diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index ed746657459..badcc4ed876 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -633,7 +633,9 @@ impl Token { (&Shebang(a), &Shebang(b)) => a == b, (&Lifetime(a), &Lifetime(b)) => a.name == b.name, - (&Ident(a, b), &Ident(c, d)) => a.name == c.name && b == d, + (&Ident(a, b), &Ident(c, d)) => b == d && (a.name == c.name || + a.name == keywords::DollarCrate.name() || + c.name == keywords::DollarCrate.name()), (&Literal(ref a, b), &Literal(ref c, d)) => { b == d && a.probably_equal_for_proc_macro(c) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index c11ef33f931..013ecd3d343 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -348,7 +348,9 @@ impl TokenStream { | TokenTree::Token(_, Token::Semi) // The pretty printer collapses whitespace arbitrarily and can // introduce whitespace from `NoDelim`. - | TokenTree::Token(_, Token::Whitespace) => false, + | TokenTree::Token(_, Token::Whitespace) + // The pretty printer can turn `$crate` into `::crate_name` + | TokenTree::Token(_, Token::ModSep) => false, _ => true } } diff --git a/src/test/ui/proc-macro/dollar-crate.stderr b/src/test/ui/proc-macro/dollar-crate.stderr index 171562a5aff..75d3e17802e 100644 --- a/src/test/ui/proc-macro/dollar-crate.stderr +++ b/src/test/ui/proc-macro/dollar-crate.stderr @@ -2,7 +2,10 @@ error[E0428]: the name `D` is defined multiple times --> $DIR/dollar-crate.rs:23:13 | LL | struct D($crate::S); //~ ERROR the name `D` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^ `D` redefined here + | ^^^^^^^^^^^^^^^^^^^^ + | | + | `D` redefined here + | previous definition of the type `D` here ... LL | local!(); | --------- in this macro invocation @@ -13,7 +16,10 @@ error[E0428]: the name `D` is defined multiple times --> $DIR/dollar-crate.rs:31:5 | LL | dollar_crate_external::external!(); //~ ERROR the name `D` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `D` redefined here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `D` redefined here + | previous definition of the type `D` here | = note: `D` must be defined only once in the type namespace of this module = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 8e254854e32..c47b3603f41 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -42,80 +42,80 @@ ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(crate::S); ATTRIBUTE INPUT: TokenStream [ Ident { ident: "struct", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Ident { ident: "A", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "crate", - span: #0 bytes(0..0) + ident: "$crate", + span: #2 bytes(LO..HI) }, Punct { ch: ':', spacing: Joint, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Punct { ch: ':', spacing: Alone, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Ident { ident: "S", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) } ], - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Punct { ch: ';', spacing: Alone, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) } ] DERIVE INPUT (PRETTY-PRINTED): struct D(crate::S); DERIVE INPUT: TokenStream [ Ident { ident: "struct", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Ident { ident: "D", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "crate", - span: #0 bytes(0..0) + ident: "$crate", + span: #2 bytes(LO..HI) }, Punct { ch: ':', spacing: Joint, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Punct { ch: ':', spacing: Alone, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Ident { ident: "S", - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) } ], - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) }, Punct { ch: ';', spacing: Alone, - span: #0 bytes(0..0) + span: #2 bytes(LO..HI) } ] PROC MACRO INPUT (PRETTY-PRINTED): struct M ( $crate :: S ) ; @@ -162,99 +162,79 @@ ATTRIBUTE INPUT (PRETTY-PRINTED): struct A(::dollar_crate_external::S); ATTRIBUTE INPUT: TokenStream [ Ident { ident: "struct", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Ident { ident: "A", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Group { delimiter: Parenthesis, stream: TokenStream [ - Punct { - ch: ':', - spacing: Joint, - span: #0 bytes(0..0) - }, - Punct { - ch: ':', - spacing: Alone, - span: #0 bytes(0..0) - }, Ident { - ident: "dollar_crate_external", - span: #0 bytes(0..0) + ident: "$crate", + span: #10 bytes(LO..HI) }, Punct { ch: ':', spacing: Joint, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Punct { ch: ':', spacing: Alone, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Ident { ident: "S", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) } ], - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Punct { ch: ';', spacing: Alone, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) } ] DERIVE INPUT (PRETTY-PRINTED): struct D(::dollar_crate_external::S); DERIVE INPUT: TokenStream [ Ident { ident: "struct", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Ident { ident: "D", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Group { delimiter: Parenthesis, stream: TokenStream [ - Punct { - ch: ':', - spacing: Joint, - span: #0 bytes(0..0) - }, - Punct { - ch: ':', - spacing: Alone, - span: #0 bytes(0..0) - }, Ident { - ident: "dollar_crate_external", - span: #0 bytes(0..0) + ident: "$crate", + span: #10 bytes(LO..HI) }, Punct { ch: ':', spacing: Joint, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Punct { ch: ':', spacing: Alone, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Ident { ident: "S", - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) } ], - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) }, Punct { ch: ';', spacing: Alone, - span: #0 bytes(0..0) + span: #10 bytes(LO..HI) } ]