Skip to content

Commit 33d9f1e

Browse files
committed
Alternative approach for tracking macro fragment span
1 parent fc359aa commit 33d9f1e

File tree

20 files changed

+164
-195
lines changed

20 files changed

+164
-195
lines changed

compiler/rustc_ast/src/ast_traits.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -231,29 +231,29 @@ impl HasTokens for Attribute {
231231
impl HasTokens for Nonterminal {
232232
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
233233
match self {
234-
Nonterminal::NtItem(item, _) => item.tokens(),
235-
Nonterminal::NtStmt(stmt, _) => stmt.tokens(),
236-
Nonterminal::NtExpr(expr, _) | Nonterminal::NtLiteral(expr, _) => expr.tokens(),
237-
Nonterminal::NtPat(pat, _) => pat.tokens(),
238-
Nonterminal::NtTy(ty, _) => ty.tokens(),
239-
Nonterminal::NtMeta(attr_item, _) => attr_item.tokens(),
240-
Nonterminal::NtPath(path, _) => path.tokens(),
241-
Nonterminal::NtVis(vis, _) => vis.tokens(),
242-
Nonterminal::NtBlock(block, _) => block.tokens(),
234+
Nonterminal::NtItem(item) => item.tokens(),
235+
Nonterminal::NtStmt(stmt) => stmt.tokens(),
236+
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
237+
Nonterminal::NtPat(pat) => pat.tokens(),
238+
Nonterminal::NtTy(ty) => ty.tokens(),
239+
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
240+
Nonterminal::NtPath(path) => path.tokens(),
241+
Nonterminal::NtVis(vis) => vis.tokens(),
242+
Nonterminal::NtBlock(block) => block.tokens(),
243243
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
244244
}
245245
}
246246
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
247247
match self {
248-
Nonterminal::NtItem(item, _) => item.tokens_mut(),
249-
Nonterminal::NtStmt(stmt, _) => stmt.tokens_mut(),
250-
Nonterminal::NtExpr(expr, _) | Nonterminal::NtLiteral(expr, _) => expr.tokens_mut(),
251-
Nonterminal::NtPat(pat, _) => pat.tokens_mut(),
252-
Nonterminal::NtTy(ty, _) => ty.tokens_mut(),
253-
Nonterminal::NtMeta(attr_item, _) => attr_item.tokens_mut(),
254-
Nonterminal::NtPath(path, _) => path.tokens_mut(),
255-
Nonterminal::NtVis(vis, _) => vis.tokens_mut(),
256-
Nonterminal::NtBlock(block, _) => block.tokens_mut(),
248+
Nonterminal::NtItem(item) => item.tokens_mut(),
249+
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
250+
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
251+
Nonterminal::NtPat(pat) => pat.tokens_mut(),
252+
Nonterminal::NtTy(ty) => ty.tokens_mut(),
253+
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
254+
Nonterminal::NtPath(path) => path.tokens_mut(),
255+
Nonterminal::NtVis(vis) => vis.tokens_mut(),
256+
Nonterminal::NtBlock(block) => block.tokens_mut(),
257257
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
258258
}
259259
}

compiler/rustc_ast/src/attr/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ impl MetaItem {
342342
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
343343
Path { span, segments, tokens: None }
344344
}
345-
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
346-
token::Nonterminal::NtMeta(item, _) => return item.meta(item.path.span),
347-
token::Nonterminal::NtPath(path, _) => (**path).clone(),
345+
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &nt.0 {
346+
token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
347+
token::Nonterminal::NtPath(path) => (**path).clone(),
348348
_ => return None,
349349
},
350350
_ => return None,

compiler/rustc_ast/src/mut_visit.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,10 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
760760
return; // Avoid visiting the span for the second time.
761761
}
762762
token::Interpolated(nt) => {
763-
visit_nonterminal(Lrc::make_mut(nt), vis);
763+
let nt = Lrc::make_mut(nt);
764+
let (nt, sp) = (&mut nt.0, &mut nt.1);
765+
vis.visit_span(sp);
766+
visit_nonterminal(nt, vis);
764767
}
765768
_ => {}
766769
}
@@ -793,33 +796,33 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
793796
// multiple items there....
794797
pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
795798
match nt {
796-
token::NtItem(item, _) => visit_clobber(item, |item| {
799+
token::NtItem(item) => visit_clobber(item, |item| {
797800
// This is probably okay, because the only visitors likely to
798801
// peek inside interpolated nodes will be renamings/markings,
799802
// which map single items to single items.
800803
vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item")
801804
}),
802-
token::NtBlock(block, _) => vis.visit_block(block),
803-
token::NtStmt(stmt, _) => visit_clobber(stmt, |stmt| {
805+
token::NtBlock(block) => vis.visit_block(block),
806+
token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
804807
// See reasoning above.
805808
stmt.map(|stmt| {
806809
vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
807810
})
808811
}),
809-
token::NtPat(pat, _) => vis.visit_pat(pat),
810-
token::NtExpr(expr, _) => vis.visit_expr(expr),
811-
token::NtTy(ty, _) => vis.visit_ty(ty),
812-
token::NtIdent(ident, _is_raw, _) => vis.visit_ident(ident),
813-
token::NtLifetime(ident, _) => vis.visit_ident(ident),
814-
token::NtLiteral(expr, _) => vis.visit_expr(expr),
815-
token::NtMeta(item, _) => {
812+
token::NtPat(pat) => vis.visit_pat(pat),
813+
token::NtExpr(expr) => vis.visit_expr(expr),
814+
token::NtTy(ty) => vis.visit_ty(ty),
815+
token::NtIdent(ident, _is_raw) => vis.visit_ident(ident),
816+
token::NtLifetime(ident) => vis.visit_ident(ident),
817+
token::NtLiteral(expr) => vis.visit_expr(expr),
818+
token::NtMeta(item) => {
816819
let AttrItem { path, args, tokens } = item.deref_mut();
817820
vis.visit_path(path);
818821
visit_attr_args(args, vis);
819822
visit_lazy_tts(tokens, vis);
820823
}
821-
token::NtPath(path, _) => vis.visit_path(path),
822-
token::NtVis(visib, _) => vis.visit_vis(visib),
824+
token::NtPath(path) => vis.visit_path(path),
825+
token::NtVis(visib) => vis.visit_vis(visib),
823826
}
824827
}
825828

compiler/rustc_ast/src/token.rs

+45-62
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl Lit {
112112
}
113113
Literal(token_lit) => Some(token_lit),
114114
Interpolated(ref nt)
115-
if let NtExpr(expr, _) | NtLiteral(expr, _) = &**nt
115+
if let NtExpr(expr) | NtLiteral(expr) = &nt.0
116116
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
117117
{
118118
Some(token_lit)
@@ -289,7 +289,7 @@ pub enum TokenKind {
289289
/// - It prevents `Token` from implementing `Copy`.
290290
/// It adds complexity and likely slows things down. Please don't add new
291291
/// occurrences of this token kind!
292-
Interpolated(Lrc<Nonterminal>),
292+
Interpolated(Lrc<(Nonterminal, Span)>),
293293

294294
/// A doc comment token.
295295
/// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc)
@@ -395,7 +395,7 @@ impl Token {
395395
/// if they keep spans or perform edition checks.
396396
pub fn uninterpolated_span(&self) -> Span {
397397
match &self.kind {
398-
Interpolated(nt) => nt.use_span(),
398+
Interpolated(nt) => nt.0.use_span(),
399399
_ => self.span,
400400
}
401401
}
@@ -438,7 +438,7 @@ impl Token {
438438
ModSep | // global path
439439
Lifetime(..) | // labeled loop
440440
Pound => true, // expression attributes
441-
Interpolated(ref nt) => matches!(**nt, NtLiteral(..) |
441+
Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) |
442442
NtExpr(..) |
443443
NtBlock(..) |
444444
NtPath(..)),
@@ -462,7 +462,7 @@ impl Token {
462462
| DotDot | DotDotDot | DotDotEq // ranges
463463
| Lt | BinOp(Shl) // associated path
464464
| ModSep => true, // global path
465-
Interpolated(ref nt) => matches!(**nt, NtLiteral(..) |
465+
Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) |
466466
NtPat(..) |
467467
NtBlock(..) |
468468
NtPath(..)),
@@ -485,7 +485,7 @@ impl Token {
485485
Lifetime(..) | // lifetime bound in trait object
486486
Lt | BinOp(Shl) | // associated path
487487
ModSep => true, // global path
488-
Interpolated(ref nt) => matches!(**nt, NtTy(..) | NtPath(..)),
488+
Interpolated(ref nt) => matches!(&nt.0, NtTy(..) | NtPath(..)),
489489
// For anonymous structs or unions, which only appear in specific positions
490490
// (type of struct fields or union fields), we don't consider them as regular types
491491
_ => false,
@@ -496,7 +496,7 @@ impl Token {
496496
pub fn can_begin_const_arg(&self) -> bool {
497497
match self.kind {
498498
OpenDelim(Delimiter::Brace) => true,
499-
Interpolated(ref nt) => matches!(**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
499+
Interpolated(ref nt) => matches!(&nt.0, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
500500
_ => self.can_begin_literal_maybe_minus(),
501501
}
502502
}
@@ -550,9 +550,9 @@ impl Token {
550550
match self.uninterpolate().kind {
551551
Literal(..) | BinOp(Minus) => true,
552552
Ident(name, false) if name.is_bool_lit() => true,
553-
Interpolated(ref nt) => match &**nt {
553+
Interpolated(ref nt) => match &nt.0 {
554554
NtLiteral(..) => true,
555-
NtExpr(e, _) => match &e.kind {
555+
NtExpr(e) => match &e.kind {
556556
ast::ExprKind::Lit(_) => true,
557557
ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
558558
matches!(&e.kind, ast::ExprKind::Lit(_))
@@ -571,11 +571,11 @@ impl Token {
571571
/// otherwise returns the original token.
572572
pub fn uninterpolate(&self) -> Cow<'_, Token> {
573573
match &self.kind {
574-
Interpolated(nt) => match **nt {
575-
NtIdent(ident, is_raw, _) => {
576-
Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span))
574+
Interpolated(nt) => match &nt.0 {
575+
NtIdent(ident, is_raw) => {
576+
Cow::Owned(Token::new(Ident(ident.name, *is_raw), ident.span))
577577
}
578-
NtLifetime(ident, _) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),
578+
NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),
579579
_ => Cow::Borrowed(self),
580580
},
581581
_ => Cow::Borrowed(self),
@@ -588,8 +588,8 @@ impl Token {
588588
// We avoid using `Token::uninterpolate` here because it's slow.
589589
match &self.kind {
590590
&Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)),
591-
Interpolated(nt) => match **nt {
592-
NtIdent(ident, is_raw, _) => Some((ident, is_raw)),
591+
Interpolated(nt) => match &nt.0 {
592+
NtIdent(ident, is_raw) => Some((*ident, *is_raw)),
593593
_ => None,
594594
},
595595
_ => None,
@@ -602,8 +602,8 @@ impl Token {
602602
// We avoid using `Token::uninterpolate` here because it's slow.
603603
match &self.kind {
604604
&Lifetime(name) => Some(Ident::new(name, self.span)),
605-
Interpolated(nt) => match **nt {
606-
NtLifetime(ident, _) => Some(ident),
605+
Interpolated(nt) => match &nt.0 {
606+
NtLifetime(ident) => Some(*ident),
607607
_ => None,
608608
},
609609
_ => None,
@@ -628,7 +628,7 @@ impl Token {
628628

629629
/// Returns `true` if the token is an interpolated path.
630630
fn is_path(&self) -> bool {
631-
if let Interpolated(nt) = &self.kind && let NtPath(..) = **nt {
631+
if let Interpolated(nt) = &self.kind && let NtPath(..) = &nt.0 {
632632
return true;
633633
}
634634

@@ -640,7 +640,7 @@ impl Token {
640640
/// (which happens while parsing the result of macro expansion)?
641641
pub fn is_whole_expr(&self) -> bool {
642642
if let Interpolated(nt) = &self.kind
643-
&& let NtExpr(..) | NtLiteral(..) | NtPath(..) | NtBlock(..) = **nt
643+
&& let NtExpr(..) | NtLiteral(..) | NtPath(..) | NtBlock(..) = &nt.0
644644
{
645645
return true;
646646
}
@@ -650,7 +650,7 @@ impl Token {
650650

651651
/// Is the token an interpolated block (`$b:block`)?
652652
pub fn is_whole_block(&self) -> bool {
653-
if let Interpolated(nt) = &self.kind && let NtBlock(..) = **nt {
653+
if let Interpolated(nt) = &self.kind && let NtBlock(..) = &nt.0 {
654654
return true;
655655
}
656656

@@ -803,19 +803,19 @@ impl PartialEq<TokenKind> for Token {
803803
#[derive(Clone, Encodable, Decodable)]
804804
/// For interpolation during macro expansion.
805805
pub enum Nonterminal {
806-
NtItem(P<ast::Item>, Span),
807-
NtBlock(P<ast::Block>, Span),
808-
NtStmt(P<ast::Stmt>, Span),
809-
NtPat(P<ast::Pat>, Span),
810-
NtExpr(P<ast::Expr>, Span),
811-
NtTy(P<ast::Ty>, Span),
812-
NtIdent(Ident, /* is_raw */ bool, Span),
813-
NtLifetime(Ident, Span),
814-
NtLiteral(P<ast::Expr>, Span),
806+
NtItem(P<ast::Item>),
807+
NtBlock(P<ast::Block>),
808+
NtStmt(P<ast::Stmt>),
809+
NtPat(P<ast::Pat>),
810+
NtExpr(P<ast::Expr>),
811+
NtTy(P<ast::Ty>),
812+
NtIdent(Ident, /* is_raw */ bool),
813+
NtLifetime(Ident),
814+
NtLiteral(P<ast::Expr>),
815815
/// Stuff inside brackets for attributes
816-
NtMeta(P<ast::AttrItem>, Span),
817-
NtPath(P<ast::Path>, Span),
818-
NtVis(P<ast::Visibility>, Span),
816+
NtMeta(P<ast::AttrItem>),
817+
NtPath(P<ast::Path>),
818+
NtVis(P<ast::Visibility>),
819819
}
820820

821821
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
@@ -899,33 +899,16 @@ impl fmt::Display for NonterminalKind {
899899
impl Nonterminal {
900900
pub fn use_span(&self) -> Span {
901901
match self {
902-
NtItem(item, _) => item.span,
903-
NtBlock(block, _) => block.span,
904-
NtStmt(stmt, _) => stmt.span,
905-
NtPat(pat, _) => pat.span,
906-
NtExpr(expr, _) | NtLiteral(expr, _) => expr.span,
907-
NtTy(ty, _) => ty.span,
908-
NtIdent(ident, _, _) | NtLifetime(ident, _) => ident.span,
909-
NtMeta(attr_item, _) => attr_item.span(),
910-
NtPath(path, _) => path.span,
911-
NtVis(vis, _) => vis.span,
912-
}
913-
}
914-
915-
pub fn def_span(&self) -> Span {
916-
match self {
917-
NtItem(_, span)
918-
| NtBlock(_, span)
919-
| NtStmt(_, span)
920-
| NtPat(_, span)
921-
| NtExpr(_, span)
922-
| NtLiteral(_, span)
923-
| NtTy(_, span)
924-
| NtIdent(_, _, span)
925-
| NtLifetime(_, span)
926-
| NtMeta(_, span)
927-
| NtPath(_, span)
928-
| NtVis(_, span) => *span,
902+
NtItem(item) => item.span,
903+
NtBlock(block) => block.span,
904+
NtStmt(stmt) => stmt.span,
905+
NtPat(pat) => pat.span,
906+
NtExpr(expr) | NtLiteral(expr) => expr.span,
907+
NtTy(ty) => ty.span,
908+
NtIdent(ident, _) | NtLifetime(ident) => ident.span,
909+
NtMeta(attr_item) => attr_item.span(),
910+
NtPath(path) => path.span,
911+
NtVis(vis) => vis.span,
929912
}
930913
}
931914

@@ -950,10 +933,10 @@ impl Nonterminal {
950933
impl PartialEq for Nonterminal {
951934
fn eq(&self, rhs: &Self) -> bool {
952935
match (self, rhs) {
953-
(NtIdent(ident_lhs, is_raw_lhs, _), NtIdent(ident_rhs, is_raw_rhs, _)) => {
936+
(NtIdent(ident_lhs, is_raw_lhs), NtIdent(ident_rhs, is_raw_rhs)) => {
954937
ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs
955938
}
956-
(NtLifetime(ident_lhs, _), NtLifetime(ident_rhs, _)) => ident_lhs == ident_rhs,
939+
(NtLifetime(ident_lhs), NtLifetime(ident_rhs)) => ident_lhs == ident_rhs,
957940
// FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them
958941
// correctly based on data from AST. This will prevent them from matching each other
959942
// in macros. The comparison will become possible only when each nonterminal has an
@@ -999,7 +982,7 @@ mod size_asserts {
999982
// tidy-alphabetical-start
1000983
static_assert_size!(Lit, 12);
1001984
static_assert_size!(LitKind, 2);
1002-
static_assert_size!(Nonterminal, 24);
985+
static_assert_size!(Nonterminal, 16);
1003986
static_assert_size!(Token, 24);
1004987
static_assert_size!(TokenKind, 16);
1005988
// tidy-alphabetical-end

0 commit comments

Comments
 (0)