diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index d5b3e87adc36a..9635750fb40bc 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -810,10 +810,10 @@ impl Nonterminal { if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind { let filename = source_map.span_to_filename(orig_span); if let FileName::Real(RealFileName::Named(path)) = filename { - let matches_prefix = |prefix| { - // Check for a path that ends with 'prefix*/src/lib.rs' + let matches_prefix = |prefix, filename| { + // Check for a path that ends with 'prefix*/src/' let mut iter = path.components().rev(); - iter.next().and_then(|p| p.as_os_str().to_str()) == Some("lib.rs") + iter.next().and_then(|p| p.as_os_str().to_str()) == Some(filename) && iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src") && iter .next() @@ -821,14 +821,25 @@ impl Nonterminal { .map_or(false, |p| p.starts_with(prefix)) }; - if (macro_name == sym::impl_macros && matches_prefix("time-macros-impl")) - || (macro_name == sym::arrays && matches_prefix("js-sys")) + if (macro_name == sym::impl_macros + && matches_prefix("time-macros-impl", "lib.rs")) + || (macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs")) { let snippet = source_map.span_to_snippet(orig_span); if snippet.as_deref() == Ok("$name") { return Some((*ident, *is_raw)); } } + + if macro_name == sym::tuple_from_req + && (matches_prefix("actix-web", "extract.rs") + || matches_prefix("actori-web", "extract.rs")) + { + let snippet = source_map.span_to_snippet(orig_span); + if snippet.as_deref() == Ok("$T") { + return Some((*ident, *is_raw)); + } + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 223a0758f008b..28fef65da070a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1114,6 +1114,7 @@ symbols! { try_trait, tt, tuple, + tuple_from_req, tuple_indexing, two_phase, ty, diff --git a/src/test/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs b/src/test/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs new file mode 100644 index 0000000000000..2d4f6010012df --- /dev/null +++ b/src/test/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs @@ -0,0 +1,7 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Three($T); + } +} diff --git a/src/test/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs b/src/test/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs new file mode 100644 index 0000000000000..2d4f6010012df --- /dev/null +++ b/src/test/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs @@ -0,0 +1,7 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Three($T); + } +} diff --git a/src/test/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs b/src/test/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs new file mode 100644 index 0000000000000..9ec6aba63f35f --- /dev/null +++ b/src/test/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs @@ -0,0 +1,7 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Four($T); + } +} diff --git a/src/test/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs b/src/test/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs new file mode 100644 index 0000000000000..9ec6aba63f35f --- /dev/null +++ b/src/test/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs @@ -0,0 +1,7 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Four($T); + } +} diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs index bc82a2ff196d2..652fabf34ac3d 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs @@ -45,5 +45,33 @@ mod with_version { other!(Foo); } +mod actix_web_test { + include!("actix-web/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actix_web_version_test { + include!("actix-web-2.0.0/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actori_web_test { + include!("actori-web/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actori_web_version_test { + include!("actori-web-2.0.0/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + fn main() {} diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout index e83bc9f8fca7a..c6b18ab674baa 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout @@ -4,3 +4,7 @@ Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/gro Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#20) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#20) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:43:18: 43:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#20) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#20) }] Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#24) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#24) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:13: 44:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#24) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#24) }] Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:38:25: 38:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:38:32: 38:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:45:12: 45:15 (#0) }], span: $DIR/group-compat-hack.rs:38:38: 38:43 (#28) }], span: $DIR/group-compat-hack.rs:38:37: 38:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:38:44: 38:45 (#28) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:52:21: 52:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:59:21: 59:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:66:21: 66:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:73:21: 73:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }]