From 4a384089402cb4b90674554467b7a506a00a5d59 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 8 Dec 2018 20:30:38 +0300 Subject: Remove `eliminate_crate_var` and special pretty-printing for `$crate` --- src/libsyntax_ext/deriving/custom.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libsyntax_ext') diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 5c82d191138..cc2fa685687 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -74,7 +74,6 @@ impl MultiItemModifier for ProcMacroDerive { // Mark attributes as known, and used. MarkAttrs(&self.attrs).visit_item(&item); - let item = ecx.resolver.eliminate_crate_var(item); let token = Token::interpolated(token::NtItem(item)); let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); -- cgit 1.4.1-3-g733a5 From 8a8ef260bef994c1e9d3444356fa9f33c01943c1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 8 Dec 2018 21:00:39 +0300 Subject: proc_macro: Validate tokens coming from the compiler again --- src/libproc_macro/lib.rs | 21 ------- src/libsyntax_ext/proc_macro_server.rs | 107 +++++++++++++++++---------------- 2 files changed, 56 insertions(+), 72 deletions(-) (limited to 'src/libsyntax_ext') diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index f2b85832dac..ebba5c81fe0 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -729,11 +729,6 @@ impl Punct { /// which can be further configured with the `set_span` method below. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn new(ch: char, spacing: Spacing) -> Punct { - const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', - '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\'']; - if !LEGAL_CHARS.contains(&ch) { - panic!("unsupported character `{:?}`", ch) - } Punct(bridge::client::Punct::new(ch, spacing)) } @@ -800,16 +795,6 @@ impl fmt::Debug for Punct { pub struct Ident(bridge::client::Ident); impl Ident { - fn is_valid(string: &str) -> bool { - let mut chars = string.chars(); - if let Some(start) = chars.next() { - (start == '_' || start.is_xid_start()) - && chars.all(|cont| cont == '_' || cont.is_xid_continue()) - } else { - false - } - } - /// Creates a new `Ident` with the given `string` as well as the specified /// `span`. /// The `string` argument must be a valid identifier permitted by the @@ -831,18 +816,12 @@ impl Ident { /// tokens, requires a `Span` to be specified at construction. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn new(string: &str, span: Span) -> Ident { - if !Ident::is_valid(string) { - panic!("`{:?}` is not a valid identifier", string) - } Ident(bridge::client::Ident::new(string, span.0, false)) } /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). #[unstable(feature = "proc_macro_raw_ident", issue = "54723")] pub fn new_raw(string: &str, span: Span) -> Ident { - if !Ident::is_valid(string) { - panic!("`{:?}` is not a valid identifier", string) - } Ident(bridge::client::Ident::new(string, span.0, true)) } diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index a04d6c92b78..ea4a8afc0aa 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -81,29 +81,23 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec)> $($field $(: $value)*,)* span, }) - ) + ); + ($ty:ident::$method:ident($($value:expr),*)) => ( + TokenTree::$ty(self::$ty::$method($($value,)* span)) + ); } macro_rules! op { ($a:expr) => { - tt!(Punct { ch: $a, joint }) + tt!(Punct::new($a, joint)) }; ($a:expr, $b:expr) => {{ - stack.push(tt!(Punct { ch: $b, joint })); - tt!(Punct { - ch: $a, - joint: true - }) + stack.push(tt!(Punct::new($b, joint))); + tt!(Punct::new($a, true)) }}; ($a:expr, $b:expr, $c:expr) => {{ - stack.push(tt!(Punct { ch: $c, joint })); - stack.push(tt!(Punct { - ch: $b, - joint: true - })); - tt!(Punct { - ch: $a, - joint: true - }) + stack.push(tt!(Punct::new($c, joint))); + stack.push(tt!(Punct::new($b, true))); + tt!(Punct::new($a, true)) }}; } @@ -156,20 +150,11 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec)> Question => op!('?'), SingleQuote => op!('\''), - Ident(ident, is_raw) => tt!(Ident { - sym: ident.name, - is_raw - }), + Ident(ident, is_raw) => tt!(Ident::new(ident.name, is_raw)), Lifetime(ident) => { let ident = ident.without_first_quote(); - stack.push(tt!(Ident { - sym: ident.name, - is_raw: false - })); - tt!(Punct { - ch: '\'', - joint: true - }) + stack.push(tt!(Ident::new(ident.name, false))); + tt!(Punct::new('\'', true)) } Literal(lit, suffix) => tt!(Literal { lit, suffix }), DocComment(c) => { @@ -193,15 +178,9 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec)> span: DelimSpan::from_single(span), })); if style == ast::AttrStyle::Inner { - stack.push(tt!(Punct { - ch: '!', - joint: false - })); + stack.push(tt!(Punct::new('!', false))); } - tt!(Punct { - ch: '#', - joint: false - }) + tt!(Punct::new('#', false)) } Interpolated(_) => { @@ -237,7 +216,7 @@ impl ToInternal for TokenTree { ) .into(); } - TokenTree::Ident(self::Ident { sym, span, is_raw }) => { + TokenTree::Ident(self::Ident { sym, is_raw, span }) => { let token = Ident(ast::Ident::new(sym, span), is_raw); return tokenstream::TokenTree::Token(span, token).into(); } @@ -338,11 +317,48 @@ pub struct Punct { span: Span, } +impl Punct { + fn new(ch: char, joint: bool, span: Span) -> Punct { + const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', + '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\'']; + if !LEGAL_CHARS.contains(&ch) { + panic!("unsupported character `{:?}`", ch) + } + Punct { ch, joint, span } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Ident { sym: Symbol, - span: Span, is_raw: bool, + span: Span, +} + +impl Ident { + fn is_valid(string: &str) -> bool { + let mut chars = string.chars(); + if let Some(start) = chars.next() { + (start == '_' || start.is_xid_start()) + && chars.all(|cont| cont == '_' || cont.is_xid_continue()) + } else { + false + } + } + fn new(sym: Symbol, is_raw: bool, span: Span) -> Ident { + let string = sym.as_str().get(); + if !Self::is_valid(string) { + panic!("`{:?}` is not a valid identifier", string) + } + if is_raw { + let normalized_sym = Symbol::intern(string); + if normalized_sym == keywords::Underscore.name() || + ast::Ident::with_empty_ctxt(normalized_sym).is_path_segment_keyword() { + panic!("`{:?}` is not a valid raw identifier", string) + } + } + Ident { sym, is_raw, span } + } } // FIXME(eddyb) `Literal` should not expose internal `Debug` impls. @@ -492,11 +508,7 @@ impl server::Group for Rustc<'_> { impl server::Punct for Rustc<'_> { fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct { - Punct { - ch, - joint: spacing == Spacing::Joint, - span: server::Span::call_site(self), - } + Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self)) } fn as_char(&mut self, punct: Self::Punct) -> char { punct.ch @@ -518,14 +530,7 @@ impl server::Punct for Rustc<'_> { impl server::Ident for Rustc<'_> { fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident { - let sym = Symbol::intern(string); - if is_raw - && (sym == keywords::Underscore.name() - || ast::Ident::with_empty_ctxt(sym).is_path_segment_keyword()) - { - panic!("`{:?}` is not a valid raw identifier", string) - } - Ident { sym, span, is_raw } + Ident::new(Symbol::intern(string), is_raw, span) } fn span(&mut self, ident: Self::Ident) -> Self::Span { ident.span -- cgit 1.4.1-3-g733a5 From 2bc67da378db40b23a426ea6384b2660c29a002c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 9 Dec 2018 17:31:12 +0300 Subject: proc_macro: Accept `$crate` as an identifier if it comes from the compiler --- src/libsyntax_ext/proc_macro_server.rs | 6 ++++++ src/test/ui/proc-macro/auxiliary/dollar-crate.rs | 12 ++++++++++++ src/test/ui/proc-macro/dollar-crate.rs | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/dollar-crate.rs create mode 100644 src/test/ui/proc-macro/dollar-crate.rs (limited to 'src/libsyntax_ext') diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index ea4a8afc0aa..ca960cbe41b 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -150,6 +150,8 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec)> Question => op!('?'), SingleQuote => op!('\''), + Ident(ident, false) if ident.name == keywords::DollarCrate.name() => + tt!(Ident::dollar_crate()), Ident(ident, is_raw) => tt!(Ident::new(ident.name, is_raw)), Lifetime(ident) => { let ident = ident.without_first_quote(); @@ -359,6 +361,10 @@ impl Ident { } Ident { sym, is_raw, span } } + fn dollar_crate(span: Span) -> Ident { + // `$crate` is accepted as an ident only if it comes from the compiler. + Ident { sym: keywords::DollarCrate.name(), is_raw: false, span } + } } // FIXME(eddyb) `Literal` should not expose internal `Debug` impls. diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate.rs new file mode 100644 index 00000000000..b0727a33332 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/dollar-crate.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn normalize(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} diff --git a/src/test/ui/proc-macro/dollar-crate.rs b/src/test/ui/proc-macro/dollar-crate.rs new file mode 100644 index 00000000000..b8b1ddd5d1c --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate.rs @@ -0,0 +1,16 @@ +// compile-pass +// aux-build:dollar-crate.rs + +extern crate dollar_crate; + +type S = u8; + +macro_rules! check { () => { + dollar_crate::normalize! { + type A = $crate::S; + } +}} + +check!(); + +fn main() {} -- cgit 1.4.1-3-g733a5