Skip to content

Commit b5e01ba

Browse files
committed
API: Add HasSpan and HasNodeId traits and review changes <3
1 parent 3d05704 commit b5e01ba

File tree

18 files changed

+327
-320
lines changed

18 files changed

+327
-320
lines changed

marker_adapter/src/context.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22
#![allow(clippy::needless_lifetimes)]
33

44
use marker_api::{
5-
ast::{
6-
item::{Body, ItemKind},
7-
ty::SemTyKind,
8-
BodyId, ExpnId, ExpnInfo, ExprId, FileInfo, FilePos, ItemId, Span, SpanId, SpanPos, SpanSource, SymbolId,
9-
TyDefId,
10-
},
5+
ast::{ty::SemTyKind, ExpnId, ExpnInfo, ExprId, FileInfo, FilePos, SpanId, SpanPos, SpanSource, SymbolId},
116
context::DriverCallbacks,
12-
diagnostic::{Diagnostic, EmissionNodeId},
7+
diagnostic::Diagnostic,
138
ffi::{self, FfiOption},
149
lint::{Level, Lint},
10+
prelude::*,
1511
};
1612

1713
/// ### Safety
@@ -59,7 +55,7 @@ impl<'ast> DriverContextWrapper<'ast> {
5955

6056
// False positive because `EmissionNode` are non-exhaustive
6157
#[allow(improper_ctypes_definitions)]
62-
extern "C" fn lint_level_at<'ast>(data: &'ast (), lint: &'static Lint, node: EmissionNodeId) -> Level {
58+
extern "C" fn lint_level_at<'ast>(data: &'ast (), lint: &'static Lint, node: NodeId) -> Level {
6359
unsafe { as_driver_cx(data) }.lint_level_at(lint, node)
6460
}
6561

@@ -129,7 +125,7 @@ unsafe fn as_driver_cx<'ast>(data: &'ast ()) -> &'ast dyn DriverContext<'ast> {
129125
}
130126

131127
pub trait DriverContext<'ast> {
132-
fn lint_level_at(&'ast self, lint: &'static Lint, node: EmissionNodeId) -> Level;
128+
fn lint_level_at(&'ast self, lint: &'static Lint, node: NodeId) -> Level;
133129
fn emit_diag(&'ast self, diag: &Diagnostic<'_, 'ast>);
134130

135131
fn item(&'ast self, api_id: ItemId) -> Option<ItemKind<'ast>>;

marker_api/src/ast/common/id.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ macro_rules! new_id {
3939

4040
use new_id;
4141

42+
use crate::private::Sealed;
43+
4244
new_id!(
4345
/// This ID uniquely identifies a crate during linting.
4446
pub CrateId: u32
@@ -144,3 +146,63 @@ new_id! {
144146
/// This ID uniquely identifies a statement during linting.
145147
pub StmtId: u64
146148
}
149+
150+
#[repr(C)]
151+
#[non_exhaustive]
152+
#[derive(Debug, Clone, Copy)]
153+
pub enum NodeId {
154+
Expr(ExprId),
155+
Item(ItemId),
156+
Stmt(StmtId),
157+
Body(BodyId),
158+
Field(FieldId),
159+
Variant(VariantId),
160+
}
161+
162+
macro_rules! impl_into_node_id_for {
163+
($variant:ident, $ty:ty) => {
164+
impl From<$ty> for NodeId {
165+
fn from(value: $ty) -> Self {
166+
NodeId::$variant(value)
167+
}
168+
}
169+
170+
impl From<&$ty> for NodeId {
171+
fn from(value: &$ty) -> Self {
172+
NodeId::$variant(*value)
173+
}
174+
}
175+
};
176+
}
177+
178+
impl_into_node_id_for!(Expr, ExprId);
179+
impl_into_node_id_for!(Item, ItemId);
180+
impl_into_node_id_for!(Stmt, StmtId);
181+
impl_into_node_id_for!(Body, BodyId);
182+
impl_into_node_id_for!(Field, FieldId);
183+
impl_into_node_id_for!(Variant, VariantId);
184+
185+
pub trait HasNodeId: Sealed {
186+
/// Returns the [`NodeId`] of the identifiable node
187+
fn node_id(&self) -> NodeId;
188+
}
189+
190+
impl<N: HasNodeId> HasNodeId for &N {
191+
fn node_id(&self) -> NodeId {
192+
(*self).node_id()
193+
}
194+
}
195+
196+
macro_rules! impl_identifiable_for {
197+
($ty:ty$(, use $data_trait:path)?) => {
198+
impl<'ast> $crate::ast::HasNodeId for $ty {
199+
fn node_id(&self) -> $crate::ast::NodeId {
200+
$(
201+
use $data_trait;
202+
)*
203+
self.id().into()
204+
}
205+
}
206+
};
207+
}
208+
pub(crate) use impl_identifiable_for;

marker_api/src/ast/common/span.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::marker::PhantomData;
22

3-
use crate::{context::with_cx, diagnostic::Applicability, ffi};
3+
use crate::{context::with_cx, diagnostic::Applicability, ffi, private::Sealed};
44

55
use super::{ExpnId, MacroId, SpanId, SpanSrcId, SymbolId};
66

@@ -386,6 +386,13 @@ impl<'ast> Span<'ast> {
386386
}
387387
}
388388

389+
impl<'ast> HasSpan<'ast> for Span<'ast> {
390+
fn span(&self) -> &Span<'ast> {
391+
self
392+
}
393+
}
394+
impl Sealed for Span<'_> {}
395+
389396
#[cfg(feature = "driver-api")]
390397
impl<'ast> Span<'ast> {
391398
#[must_use]
@@ -509,11 +516,14 @@ impl<'ast> Ident<'ast> {
509516
pub fn name(&self) -> &str {
510517
with_cx(self, |cx| cx.symbol_str(self.sym))
511518
}
519+
}
512520

513-
pub fn span(&self) -> &Span<'ast> {
521+
impl<'ast> HasSpan<'ast> for Ident<'ast> {
522+
fn span(&self) -> &Span<'ast> {
514523
with_cx(self, |cx| cx.span(self.span))
515524
}
516525
}
526+
impl<'ast> crate::private::Sealed for Ident<'ast> {}
517527

518528
#[cfg(feature = "driver-api")]
519529
impl<'ast> Ident<'ast> {
@@ -570,3 +580,28 @@ impl_ident_eq_for!(
570580
std::ffi::OsString,
571581
std::borrow::Cow<'_, str>
572582
);
583+
584+
/// A trait for nodes, that provide a [`Span`].
585+
pub trait HasSpan<'ast>: Sealed {
586+
/// This returns the [`Span`] of the implementing AST node.
587+
fn span(&self) -> &Span<'ast>;
588+
}
589+
590+
/// This macro implements the [`HasSpan`] trait for data types, that provide a
591+
/// `span()` method.
592+
macro_rules! impl_spanned_for {
593+
($ty:ty) => {
594+
impl<'ast> $crate::ast::HasSpan<'ast> for $ty {
595+
fn span(&self) -> &$crate::ast::Span<'ast> {
596+
self.span()
597+
}
598+
}
599+
};
600+
}
601+
pub(crate) use impl_spanned_for;
602+
603+
impl<'ast, N: HasSpan<'ast>> HasSpan<'ast> for &N {
604+
fn span(&self) -> &Span<'ast> {
605+
(*self).span()
606+
}
607+
}

marker_api/src/ast/expr.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{prelude::EmissionNode, private::Sealed, CtorBlocker};
22

3-
use super::{ty::SemTyKind, ExprId, Span, SpanId};
3+
use super::{ty::SemTyKind, ExprId, HasNodeId, HasSpan, Span, SpanId};
44

55
use std::{fmt::Debug, marker::PhantomData};
66

@@ -27,16 +27,10 @@ pub use unstable_expr::*;
2727
///
2828
/// This trait is only meant to be implemented inside this crate. The `Sealed`
2929
/// super trait prevents external implementations.
30-
pub trait ExprData<'ast>: Debug + Sealed
31-
where
32-
for<'a> &'a Self: EmissionNode<'ast>,
33-
{
30+
pub trait ExprData<'ast>: Debug + EmissionNode<'ast> + HasSpan<'ast> + HasNodeId + Sealed {
3431
/// Returns the [`ExprId`] of this expression.
3532
fn id(&self) -> ExprId;
3633

37-
/// Returns the [`Span`] of this expression.
38-
fn span(&self) -> &Span<'ast>;
39-
4034
/// Returns the semantic type of this expression.
4135
fn ty(&self) -> SemTyKind<'ast>;
4236

@@ -96,9 +90,9 @@ impl<'ast> ExprKind<'ast> {
9690
impl_expr_kind_fn!(ExprKind: precedence() -> ExprPrecedence);
9791
}
9892

93+
crate::ast::impl_spanned_for!(ExprKind<'ast>);
94+
crate::ast::impl_identifiable_for!(ExprKind<'ast>);
9995
impl Sealed for ExprKind<'_> {}
100-
crate::diagnostic::impl_emission_node_for_node!(ExprKind<'ast>);
101-
crate::diagnostic::impl_emission_node_for_node!(&ExprKind<'ast>);
10296

10397
#[repr(C)]
10498
#[non_exhaustive]
@@ -122,9 +116,9 @@ impl<'ast> LitExprKind<'ast> {
122116
impl_expr_kind_fn!(LitExprKind: precedence() -> ExprPrecedence);
123117
}
124118

119+
crate::ast::impl_spanned_for!(LitExprKind<'ast>);
120+
crate::ast::impl_identifiable_for!(LitExprKind<'ast>);
125121
impl Sealed for LitExprKind<'_> {}
126-
crate::diagnostic::impl_emission_node_for_node!(LitExprKind<'ast>);
127-
crate::diagnostic::impl_emission_node_for_node!(&LitExprKind<'ast>);
128122

129123
impl<'ast> From<LitExprKind<'ast>> for ExprKind<'ast> {
130124
fn from(value: LitExprKind<'ast>) -> Self {
@@ -322,10 +316,6 @@ macro_rules! impl_expr_data {
322316
self.data.id
323317
}
324318

325-
fn span(&self) -> &crate::ast::Span<'ast> {
326-
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
327-
}
328-
329319
fn ty(&self) -> $crate::ast::ty::SemTyKind<'ast> {
330320
$crate::context::with_cx(self, |cx| cx.expr_ty(self.data.id))
331321
}
@@ -337,8 +327,14 @@ macro_rules! impl_expr_data {
337327
}
338328
}
339329

330+
impl<'ast> $crate::ast::HasSpan<'ast> for $self_ty {
331+
fn span(&self) -> &crate::ast::Span<'ast> {
332+
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
333+
}
334+
}
335+
$crate::ast::impl_identifiable_for!($self_ty, use $crate::ast::expr::ExprData);
336+
340337
impl<'ast> $crate::private::Sealed for $self_ty {}
341-
$crate::diagnostic::impl_emission_node_for_node!(&$self_ty, use super::ExprData);
342338

343339
impl<'ast> From<&'ast $self_ty> for $crate::ast::expr::ExprKind<'ast> {
344340
fn from(from: &'ast $self_ty) -> Self {

marker_api/src/ast/expr/lit_expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'ast> CharLitExpr<'ast> {
6262
/// can be hardware-dependent. For exact value checks, it might be better to check
6363
/// the written float literal by getting the code snipped from the expression span.
6464
/// See:
65-
/// * [`ExprData::span()`](`super::ExprData::span`)
65+
/// * [`HasSpan::span()`](`super::HasSpan::span`)
6666
/// * [`Span::snippet()`](`crate::ast::Span::snippet`)
6767
///
6868
/// All integer literals are unsigned, negative numbers have a unary negation

marker_api/src/ast/item.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::private::Sealed;
55
use crate::CtorBlocker;
66

77
use super::expr::ExprKind;
8-
use super::{Ident, ItemId, Span, SpanId};
8+
use super::{HasNodeId, HasSpan, Ident, ItemId, Span, SpanId};
99

1010
// Item implementations
1111
mod extern_crate_item;
@@ -37,18 +37,11 @@ pub use unstable_item::*;
3737
///
3838
/// This trait is only meant to be implemented inside this crate. The `Sealed`
3939
/// super trait prevents external implementations.
40-
pub trait ItemData<'ast>: Debug + Sealed
41-
where
42-
for<'a> &'a Self: EmissionNode<'ast>,
43-
{
40+
pub trait ItemData<'ast>: Debug + EmissionNode<'ast> + HasSpan<'ast> + HasNodeId + Sealed {
4441
/// Returns the [`ItemId`] of this item. This is a unique identifier used for comparison
4542
/// and to request items from the [`AstContext`](`crate::context::AstContext`).
4643
fn id(&self) -> ItemId;
4744

48-
/// The [`Span`] of the entire item. This span should be used for general item related
49-
/// diagnostics.
50-
fn span(&self) -> &Span<'ast>;
51-
5245
/// The [`Visibility`] of this item.
5346
fn visibility(&self) -> &Visibility<'ast>;
5447

@@ -97,8 +90,9 @@ impl<'ast> ItemKind<'ast> {
9790
impl_item_type_fn!(ItemKind: attrs() -> ());
9891
}
9992

100-
crate::diagnostic::impl_emission_node_for_node!(ItemKind<'ast>);
101-
crate::diagnostic::impl_emission_node_for_node!(&ItemKind<'ast>);
93+
crate::ast::impl_spanned_for!(ItemKind<'ast>);
94+
crate::ast::impl_identifiable_for!(ItemKind<'ast>);
95+
impl<'ast> crate::private::Sealed for ItemKind<'ast> {}
10296

10397
#[non_exhaustive]
10498
#[derive(Debug, Copy, Clone)]
@@ -118,8 +112,9 @@ impl<'ast> AssocItemKind<'ast> {
118112
// FIXME: Potentially add a field to the items to optionally store the owner id
119113
}
120114

121-
crate::diagnostic::impl_emission_node_for_node!(AssocItemKind<'ast>);
122-
crate::diagnostic::impl_emission_node_for_node!(&AssocItemKind<'ast>);
115+
crate::ast::impl_spanned_for!(AssocItemKind<'ast>);
116+
crate::ast::impl_identifiable_for!(AssocItemKind<'ast>);
117+
impl<'ast> crate::private::Sealed for AssocItemKind<'ast> {}
123118

124119
impl<'ast> From<AssocItemKind<'ast>> for ItemKind<'ast> {
125120
fn from(value: AssocItemKind<'ast>) -> Self {
@@ -147,8 +142,9 @@ impl<'ast> ExternItemKind<'ast> {
147142
impl_item_type_fn!(ExternItemKind: as_item() -> ItemKind<'ast>);
148143
}
149144

150-
crate::diagnostic::impl_emission_node_for_node!(ExternItemKind<'ast>);
151-
crate::diagnostic::impl_emission_node_for_node!(&ExternItemKind<'ast>);
145+
crate::ast::impl_spanned_for!(ExternItemKind<'ast>);
146+
crate::ast::impl_identifiable_for!(ExternItemKind<'ast>);
147+
impl<'ast> crate::private::Sealed for ExternItemKind<'ast> {}
152148

153149
impl<'ast> From<ExternItemKind<'ast>> for ItemKind<'ast> {
154150
fn from(value: ExternItemKind<'ast>) -> Self {
@@ -206,10 +202,6 @@ macro_rules! impl_item_data {
206202
self.data.id
207203
}
208204

209-
fn span(&self) -> &crate::ast::Span<'ast> {
210-
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
211-
}
212-
213205
fn visibility(&self) -> &crate::ast::item::Visibility<'ast> {
214206
&self.data.vis
215207
}
@@ -225,8 +217,14 @@ macro_rules! impl_item_data {
225217
fn attrs(&self) {}
226218
}
227219

220+
impl<'ast> $crate::ast::HasSpan<'ast> for $self_name<'ast> {
221+
fn span(&self) -> &crate::ast::Span<'ast> {
222+
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
223+
}
224+
}
225+
226+
$crate::ast::impl_identifiable_for!($self_name<'ast>, use $crate::ast::item::ItemData);
228227
impl $crate::private::Sealed for $self_name<'_> {}
229-
$crate::diagnostic::impl_emission_node_for_node!(&$self_name<'ast>, use super::ItemData);
230228

231229
impl<'ast> From<&'ast $self_name<'ast>> for crate::ast::item::ItemKind<'ast> {
232230
fn from(value: &'ast $self_name<'ast>) -> Self {

0 commit comments

Comments
 (0)