Skip to content

Commit 1e15606

Browse files
committed
rustc_ast: Visit tokens stored in AST nodes in mutable visitor
1 parent 9d78d1d commit 1e15606

File tree

2 files changed

+61
-15
lines changed

2 files changed

+61
-15
lines changed

compiler/rustc_ast/src/mut_visit.rs

+34-15
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ pub fn noop_visit_ty_constraint<T: MutVisitor>(
461461
}
462462

463463
pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
464-
let Ty { id, kind, span, tokens: _ } = ty.deref_mut();
464+
let Ty { id, kind, span, tokens } = ty.deref_mut();
465465
vis.visit_id(id);
466466
match kind {
467467
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {}
@@ -497,6 +497,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
497497
TyKind::MacCall(mac) => vis.visit_mac(mac),
498498
}
499499
vis.visit_span(span);
500+
visit_lazy_tts(tokens, vis);
500501
}
501502

502503
pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) {
@@ -523,13 +524,14 @@ pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis:
523524
vis.visit_span(span);
524525
}
525526

526-
pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens: _ }: &mut Path, vis: &mut T) {
527+
pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) {
527528
vis.visit_span(span);
528529
for PathSegment { ident, id, args } in segments {
529530
vis.visit_ident(ident);
530531
vis.visit_id(id);
531532
visit_opt(args, |args| vis.visit_generic_args(args));
532533
}
534+
visit_lazy_tts(tokens, vis);
533535
}
534536

535537
pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
@@ -587,15 +589,17 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
587589
}
588590

589591
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
590-
let Attribute { kind, id: _, style: _, span, tokens: _ } = attr;
592+
let Attribute { kind, id: _, style: _, span, tokens } = attr;
591593
match kind {
592-
AttrKind::Normal(AttrItem { path, args, tokens: _ }) => {
594+
AttrKind::Normal(AttrItem { path, args, tokens }) => {
593595
vis.visit_path(path);
594596
visit_mac_args(args, vis);
597+
visit_lazy_tts(tokens, vis);
595598
}
596599
AttrKind::DocComment(..) => {}
597600
}
598601
vis.visit_span(span);
602+
visit_lazy_tts(tokens, vis);
599603
}
600604

601605
pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) {
@@ -658,6 +662,16 @@ pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T)
658662
}
659663
}
660664

665+
pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) {
666+
if vis.token_visiting_enabled() {
667+
visit_opt(lazy_tts, |lazy_tts| {
668+
let mut tts = lazy_tts.create_token_stream();
669+
visit_tts(&mut tts, vis);
670+
*lazy_tts = LazyTokenStream::new(tts);
671+
})
672+
}
673+
}
674+
661675
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
662676
// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
663677
// In practice the ident part is not actually used by specific visitors right now,
@@ -725,9 +739,10 @@ pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut
725739
token::NtLifetime(ident) => vis.visit_ident(ident),
726740
token::NtLiteral(expr) => vis.visit_expr(expr),
727741
token::NtMeta(item) => {
728-
let AttrItem { path, args, tokens: _ } = item.deref_mut();
742+
let AttrItem { path, args, tokens } = item.deref_mut();
729743
vis.visit_path(path);
730744
visit_mac_args(args, vis);
745+
visit_lazy_tts(tokens, vis);
731746
}
732747
token::NtPath(path) => vis.visit_path(path),
733748
token::NtTT(tt) => visit_tt(tt, vis),
@@ -887,10 +902,11 @@ pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mu
887902
}
888903

889904
pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
890-
let Block { id, stmts, rules: _, span, tokens: _ } = block.deref_mut();
905+
let Block { id, stmts, rules: _, span, tokens } = block.deref_mut();
891906
vis.visit_id(id);
892907
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
893908
vis.visit_span(span);
909+
visit_lazy_tts(tokens, vis);
894910
}
895911

896912
pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
@@ -955,7 +971,7 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
955971
mut item: P<AssocItem>,
956972
visitor: &mut T,
957973
) -> SmallVec<[P<AssocItem>; 1]> {
958-
let Item { id, ident, vis, attrs, kind, span, tokens: _ } = item.deref_mut();
974+
let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut();
959975
visitor.visit_id(id);
960976
visitor.visit_ident(ident);
961977
visitor.visit_vis(vis);
@@ -978,6 +994,7 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
978994
AssocItemKind::MacCall(mac) => visitor.visit_mac(mac),
979995
}
980996
visitor.visit_span(span);
997+
visit_lazy_tts(tokens, visitor);
981998
smallvec![item]
982999
}
9831000

@@ -1028,16 +1045,14 @@ pub fn noop_flat_map_item<T: MutVisitor>(
10281045
mut item: P<Item>,
10291046
visitor: &mut T,
10301047
) -> SmallVec<[P<Item>; 1]> {
1031-
let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut();
1048+
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
10321049
visitor.visit_ident(ident);
10331050
visit_attrs(attrs, visitor);
10341051
visitor.visit_id(id);
10351052
visitor.visit_item_kind(kind);
10361053
visitor.visit_vis(vis);
10371054
visitor.visit_span(span);
1038-
1039-
// FIXME: if `tokens` is modified with a call to `vis.visit_tts` it causes
1040-
// an ICE during resolve... odd!
1055+
visit_lazy_tts(tokens, visitor);
10411056

10421057
smallvec![item]
10431058
}
@@ -1046,7 +1061,7 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
10461061
mut item: P<ForeignItem>,
10471062
visitor: &mut T,
10481063
) -> SmallVec<[P<ForeignItem>; 1]> {
1049-
let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut();
1064+
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
10501065
visitor.visit_id(id);
10511066
visitor.visit_ident(ident);
10521067
visitor.visit_vis(vis);
@@ -1069,11 +1084,12 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
10691084
ForeignItemKind::MacCall(mac) => visitor.visit_mac(mac),
10701085
}
10711086
visitor.visit_span(span);
1087+
visit_lazy_tts(tokens, visitor);
10721088
smallvec![item]
10731089
}
10741090

10751091
pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
1076-
let Pat { id, kind, span, tokens: _ } = pat.deref_mut();
1092+
let Pat { id, kind, span, tokens } = pat.deref_mut();
10771093
vis.visit_id(id);
10781094
match kind {
10791095
PatKind::Wild | PatKind::Rest => {}
@@ -1108,6 +1124,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
11081124
PatKind::MacCall(mac) => vis.visit_mac(mac),
11091125
}
11101126
vis.visit_span(span);
1127+
visit_lazy_tts(tokens, vis);
11111128
}
11121129

11131130
pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) {
@@ -1116,7 +1133,7 @@ pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonCo
11161133
}
11171134

11181135
pub fn noop_visit_expr<T: MutVisitor>(
1119-
Expr { kind, id, span, attrs, tokens: _ }: &mut Expr,
1136+
Expr { kind, id, span, attrs, tokens }: &mut Expr,
11201137
vis: &mut T,
11211138
) {
11221139
match kind {
@@ -1295,6 +1312,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
12951312
vis.visit_id(id);
12961313
vis.visit_span(span);
12971314
visit_thin_attrs(attrs, vis);
1315+
visit_lazy_tts(tokens, vis);
12981316
}
12991317

13001318
pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> {
@@ -1305,11 +1323,12 @@ pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Optio
13051323
}
13061324

13071325
pub fn noop_flat_map_stmt<T: MutVisitor>(
1308-
Stmt { kind, mut span, mut id, tokens }: Stmt,
1326+
Stmt { kind, mut span, mut id, mut tokens }: Stmt,
13091327
vis: &mut T,
13101328
) -> SmallVec<[Stmt; 1]> {
13111329
vis.visit_id(&mut id);
13121330
vis.visit_span(&mut span);
1331+
visit_lazy_tts(&mut tokens, vis);
13131332
noop_flat_map_stmt_kind(kind, vis)
13141333
.into_iter()
13151334
.map(|kind| Stmt { id, kind, span, tokens: tokens.clone() })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Make sure that marks from declarative macros are applied to tokens in nonterminal.
2+
3+
// check-pass
4+
// aux-build:test-macros.rs
5+
6+
#![feature(decl_macro)]
7+
8+
#[macro_use]
9+
extern crate test_macros;
10+
11+
macro_rules! outer {
12+
($item:item) => {
13+
macro inner() {
14+
recollect! { $item }
15+
}
16+
17+
inner!();
18+
};
19+
}
20+
21+
struct S;
22+
23+
outer! {
24+
struct S; // OK, not a duplicate definition of `S`
25+
}
26+
27+
fn main() {}

0 commit comments

Comments
 (0)