Skip to content

Commit ff5e0f1

Browse files
committed
Auto merge of #74846 - Aaron1011:fix/pat-token-capture, r=petrochenkov
Capture tokens for Pat used in macro_rules! argument This extends PR #73293 to handle patterns (Pat). Unlike expressions, patterns do not support custom attributes, so we only need to capture tokens during macro_rules! argument parsing.
2 parents d9d4d39 + 607a190 commit ff5e0f1

File tree

13 files changed

+85
-10
lines changed

13 files changed

+85
-10
lines changed

src/librustc_ast/ast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ pub struct Pat {
550550
pub id: NodeId,
551551
pub kind: PatKind,
552552
pub span: Span,
553+
pub tokens: Option<TokenStream>,
553554
}
554555

555556
impl Pat {
@@ -2138,6 +2139,7 @@ impl Param {
21382139
id: DUMMY_NODE_ID,
21392140
kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
21402141
span,
2142+
tokens: None,
21412143
}),
21422144
span,
21432145
ty,

src/librustc_ast/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
10531053
}
10541054

10551055
pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
1056-
let Pat { id, kind, span } = pat.deref_mut();
1056+
let Pat { id, kind, span, tokens: _ } = pat.deref_mut();
10571057
vis.visit_id(id);
10581058
match kind {
10591059
PatKind::Wild | PatKind::Rest => {}

src/librustc_expand/base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ impl MacResult for MacEager {
551551
id: ast::DUMMY_NODE_ID,
552552
span: e.span,
553553
kind: PatKind::Lit(e),
554+
tokens: None,
554555
}));
555556
}
556557
}
@@ -597,7 +598,7 @@ impl DummyResult {
597598

598599
/// A plain dummy pattern.
599600
pub fn raw_pat(sp: Span) -> ast::Pat {
600-
ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp }
601+
ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp, tokens: None }
601602
}
602603

603604
/// A plain dummy type.

src/librustc_expand/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ impl<'a> ExtCtxt<'a> {
392392
}
393393

394394
pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
395-
P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span })
395+
P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None })
396396
}
397397
pub fn pat_wild(&self, span: Span) -> P<ast::Pat> {
398398
self.pat(span, PatKind::Wild)

src/librustc_expand/placeholders.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ pub fn placeholder(
3838
})
3939
};
4040
let ty = || P(ast::Ty { id, kind: ast::TyKind::MacCall(mac_placeholder()), span });
41-
let pat = || P(ast::Pat { id, kind: ast::PatKind::MacCall(mac_placeholder()), span });
41+
let pat =
42+
|| P(ast::Pat { id, kind: ast::PatKind::MacCall(mac_placeholder()), span, tokens: None });
4243

4344
match kind {
4445
AstFragmentKind::Expr => AstFragment::Expr(expr_placeholder()),
@@ -85,6 +86,7 @@ pub fn placeholder(
8586
id,
8687
span,
8788
kind: ast::PatKind::MacCall(mac_placeholder()),
89+
tokens: None,
8890
})),
8991
AstFragmentKind::Ty => {
9092
AstFragment::Ty(P(ast::Ty { id, span, kind: ast::TyKind::MacCall(mac_placeholder()) }))

src/librustc_parse/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
263263
Nonterminal::NtItem(ref item) => {
264264
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
265265
}
266+
Nonterminal::NtPat(ref pat) => pat.tokens.clone(),
266267
Nonterminal::NtIdent(ident, is_raw) => {
267268
Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into())
268269
}

src/librustc_parse/parser/diagnostics.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
2626
id: ast::DUMMY_NODE_ID,
2727
kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None),
2828
span: ident.span,
29+
tokens: None,
2930
});
3031
let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID };
3132
Param {
@@ -83,7 +84,12 @@ impl RecoverQPath for Pat {
8384
self.to_ty()
8485
}
8586
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
86-
Self { span: path.span, kind: PatKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
87+
Self {
88+
span: path.span,
89+
kind: PatKind::Path(qself, path),
90+
id: ast::DUMMY_NODE_ID,
91+
tokens: None,
92+
}
8793
}
8894
}
8995

@@ -1526,7 +1532,8 @@ impl<'a> Parser<'a> {
15261532
.emit();
15271533

15281534
// Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
1529-
let pat = P(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID });
1535+
let pat =
1536+
P(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID, tokens: None });
15301537
Ok((pat, ty))
15311538
}
15321539

src/librustc_parse/parser/nonterminal.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,14 @@ impl<'a> Parser<'a> {
116116
Some(s) => token::NtStmt(s),
117117
None => return Err(self.struct_span_err(self.token.span, "expected a statement")),
118118
},
119-
NonterminalKind::Pat => token::NtPat(self.parse_pat(None)?),
119+
NonterminalKind::Pat => {
120+
let (mut pat, tokens) = self.collect_tokens(|this| this.parse_pat(None))?;
121+
// We have have eaten an NtPat, which could already have tokens
122+
if pat.tokens.is_none() {
123+
pat.tokens = Some(tokens);
124+
}
125+
token::NtPat(pat)
126+
}
120127
NonterminalKind::Expr => {
121128
let (mut expr, tokens) = self.collect_tokens(|this| this.parse_expr())?;
122129
// If we captured tokens during parsing (due to outer attributes),

src/librustc_parse/parser/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,6 @@ impl<'a> Parser<'a> {
10071007
}
10081008

10091009
fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
1010-
P(Pat { kind, span, id: ast::DUMMY_NODE_ID })
1010+
P(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
10111011
}
10121012
}

src/test/ui-fulldeps/pprust-expr-roundtrip.rs

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
164164
id: DUMMY_NODE_ID,
165165
kind: PatKind::Wild,
166166
span: DUMMY_SP,
167+
tokens: None,
167168
});
168169
iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e)))
169170
},

src/test/ui/proc-macro/capture-macro-rules-invoke.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
// aux-build:test-macros.rs
22
// check-pass
3+
// compile-flags: -Z span-debug
4+
// normalize-stdout-test "#\d+" -> "#CTXT"
35

46
extern crate test_macros;
5-
use test_macros::recollect;
7+
use test_macros::print_bang;
68

79
macro_rules! use_expr {
810
($expr:expr) => {
9-
recollect!($expr)
11+
print_bang!($expr)
12+
}
13+
}
14+
15+
macro_rules! use_pat {
16+
($pat:pat) => {
17+
print_bang!($pat)
1018
}
1119
}
1220

@@ -17,6 +25,10 @@ impl Foo {
1725
fn use_self(self) {
1826
drop(use_expr!(self));
1927
}
28+
29+
fn with_pat(use_pat!((a, b)): (u32, u32)) {
30+
println!("Args: {} {}", a, b);
31+
}
2032
}
2133

2234
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
PRINT-BANG INPUT (DISPLAY): self
2+
PRINT-BANG INPUT (DEBUG): TokenStream [
3+
Group {
4+
delimiter: None,
5+
stream: TokenStream [
6+
Ident {
7+
ident: "self",
8+
span: $DIR/capture-macro-rules-invoke.rs:26:24: 26:28 (#CTXT),
9+
},
10+
],
11+
span: $DIR/capture-macro-rules-invoke.rs:11:21: 11:26 (#CTXT),
12+
},
13+
]
14+
PRINT-BANG INPUT (DISPLAY): (a, b)
15+
PRINT-BANG INPUT (DEBUG): TokenStream [
16+
Group {
17+
delimiter: None,
18+
stream: TokenStream [
19+
Group {
20+
delimiter: Parenthesis,
21+
stream: TokenStream [
22+
Ident {
23+
ident: "a",
24+
span: $DIR/capture-macro-rules-invoke.rs:29:27: 29:28 (#CTXT),
25+
},
26+
Punct {
27+
ch: ',',
28+
spacing: Alone,
29+
span: $DIR/capture-macro-rules-invoke.rs:29:28: 29:29 (#CTXT),
30+
},
31+
Ident {
32+
ident: "b",
33+
span: $DIR/capture-macro-rules-invoke.rs:29:30: 29:31 (#CTXT),
34+
},
35+
],
36+
span: $DIR/capture-macro-rules-invoke.rs:29:26: 29:32 (#CTXT),
37+
},
38+
],
39+
span: $DIR/capture-macro-rules-invoke.rs:17:21: 17:25 (#CTXT),
40+
},
41+
]

src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs

+1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ fn take_pat(from: &mut Pat) -> Pat {
340340
id: DUMMY_NODE_ID,
341341
kind: Wild,
342342
span: DUMMY_SP,
343+
tokens: None
343344
};
344345
mem::replace(from, dummy)
345346
}

0 commit comments

Comments
 (0)