Skip to content

Capture tokens for Pat used in macro_rules! argument #74846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ pub struct Pat {
pub id: NodeId,
pub kind: PatKind,
pub span: Span,
pub tokens: Option<TokenStream>,
}

impl Pat {
Expand Down Expand Up @@ -2138,6 +2139,7 @@ impl Param {
id: DUMMY_NODE_ID,
kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
span,
tokens: None,
}),
span,
ty,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
}

pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
let Pat { id, kind, span } = pat.deref_mut();
let Pat { id, kind, span, tokens: _ } = pat.deref_mut();
vis.visit_id(id);
match kind {
PatKind::Wild | PatKind::Rest => {}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_expand/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ impl MacResult for MacEager {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: PatKind::Lit(e),
tokens: None,
}));
}
}
Expand Down Expand Up @@ -597,7 +598,7 @@ impl DummyResult {

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

/// A plain dummy type.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_expand/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ impl<'a> ExtCtxt<'a> {
}

pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span })
P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None })
}
pub fn pat_wild(&self, span: Span) -> P<ast::Pat> {
self.pat(span, PatKind::Wild)
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_expand/placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ pub fn placeholder(
})
};
let ty = || P(ast::Ty { id, kind: ast::TyKind::MacCall(mac_placeholder()), span });
let pat = || P(ast::Pat { id, kind: ast::PatKind::MacCall(mac_placeholder()), span });
let pat =
|| P(ast::Pat { id, kind: ast::PatKind::MacCall(mac_placeholder()), span, tokens: None });

match kind {
AstFragmentKind::Expr => AstFragment::Expr(expr_placeholder()),
Expand Down Expand Up @@ -85,6 +86,7 @@ pub fn placeholder(
id,
span,
kind: ast::PatKind::MacCall(mac_placeholder()),
tokens: None,
})),
AstFragmentKind::Ty => {
AstFragment::Ty(P(ast::Ty { id, span, kind: ast::TyKind::MacCall(mac_placeholder()) }))
Expand Down
1 change: 1 addition & 0 deletions src/librustc_parse/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
Nonterminal::NtItem(ref item) => {
prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
}
Nonterminal::NtPat(ref pat) => pat.tokens.clone(),
Nonterminal::NtIdent(ident, is_raw) => {
Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into())
}
Expand Down
11 changes: 9 additions & 2 deletions src/librustc_parse/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
id: ast::DUMMY_NODE_ID,
kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None),
span: ident.span,
tokens: None,
});
let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID };
Param {
Expand Down Expand Up @@ -83,7 +84,12 @@ impl RecoverQPath for Pat {
self.to_ty()
}
fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
Self { span: path.span, kind: PatKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
Self {
span: path.span,
kind: PatKind::Path(qself, path),
id: ast::DUMMY_NODE_ID,
tokens: None,
}
}
}

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

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

Expand Down
9 changes: 8 additions & 1 deletion src/librustc_parse/parser/nonterminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,14 @@ impl<'a> Parser<'a> {
Some(s) => token::NtStmt(s),
None => return Err(self.struct_span_err(self.token.span, "expected a statement")),
},
NonterminalKind::Pat => token::NtPat(self.parse_pat(None)?),
NonterminalKind::Pat => {
let (mut pat, tokens) = self.collect_tokens(|this| this.parse_pat(None))?;
// We have have eaten an NtPat, which could already have tokens
if pat.tokens.is_none() {
pat.tokens = Some(tokens);
}
token::NtPat(pat)
}
NonterminalKind::Expr => {
let (mut expr, tokens) = self.collect_tokens(|this| this.parse_expr())?;
// If we captured tokens during parsing (due to outer attributes),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_parse/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,6 @@ impl<'a> Parser<'a> {
}

fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
P(Pat { kind, span, id: ast::DUMMY_NODE_ID })
P(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
}
}
1 change: 1 addition & 0 deletions src/test/ui-fulldeps/pprust-expr-roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
id: DUMMY_NODE_ID,
kind: PatKind::Wild,
span: DUMMY_SP,
tokens: None,
});
iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e)))
},
Expand Down
16 changes: 14 additions & 2 deletions src/test/ui/proc-macro/capture-macro-rules-invoke.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
// aux-build:test-macros.rs
// check-pass
// compile-flags: -Z span-debug
// normalize-stdout-test "#\d+" -> "#CTXT"

extern crate test_macros;
use test_macros::recollect;
use test_macros::print_bang;

macro_rules! use_expr {
($expr:expr) => {
recollect!($expr)
print_bang!($expr)
}
}

macro_rules! use_pat {
($pat:pat) => {
print_bang!($pat)
}
}

Expand All @@ -17,6 +25,10 @@ impl Foo {
fn use_self(self) {
drop(use_expr!(self));
}

fn with_pat(use_pat!((a, b)): (u32, u32)) {
println!("Args: {} {}", a, b);
}
}

fn main() {}
41 changes: 41 additions & 0 deletions src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
PRINT-BANG INPUT (DISPLAY): self
PRINT-BANG INPUT (DEBUG): TokenStream [
Group {
delimiter: None,
stream: TokenStream [
Ident {
ident: "self",
span: $DIR/capture-macro-rules-invoke.rs:26:24: 26:28 (#CTXT),
},
],
span: $DIR/capture-macro-rules-invoke.rs:11:21: 11:26 (#CTXT),
},
]
PRINT-BANG INPUT (DISPLAY): (a, b)
PRINT-BANG INPUT (DEBUG): TokenStream [
Group {
delimiter: None,
stream: TokenStream [
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "a",
span: $DIR/capture-macro-rules-invoke.rs:29:27: 29:28 (#CTXT),
},
Punct {
ch: ',',
spacing: Alone,
span: $DIR/capture-macro-rules-invoke.rs:29:28: 29:29 (#CTXT),
},
Ident {
ident: "b",
span: $DIR/capture-macro-rules-invoke.rs:29:30: 29:31 (#CTXT),
},
],
span: $DIR/capture-macro-rules-invoke.rs:29:26: 29:32 (#CTXT),
},
],
span: $DIR/capture-macro-rules-invoke.rs:17:21: 17:25 (#CTXT),
},
]
1 change: 1 addition & 0 deletions src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ fn take_pat(from: &mut Pat) -> Pat {
id: DUMMY_NODE_ID,
kind: Wild,
span: DUMMY_SP,
tokens: None
};
mem::replace(from, dummy)
}
Expand Down