From d708d026ef59ab4abd52d204fbc5c01e26d98a0a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Mar 2018 01:09:22 +0200 Subject: [PATCH 01/14] proc_macro: introduce frontend bridge and use it for TokenStream and its builders & cursors. --- src/libproc_macro/bridge.rs | 547 ++++++++++++++++++ src/libproc_macro/lib.rs | 319 ++-------- src/libproc_macro/quote.rs | 16 - src/libproc_macro/rustc.rs | 282 +++++++++ src/librustc_metadata/creader.rs | 9 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/libsyntax_ext/deriving/custom.rs | 51 +- src/libsyntax_ext/proc_macro_impl.rs | 32 +- src/libsyntax_ext/proc_macro_registrar.rs | 41 +- src/test/ui-fulldeps/proc-macro/signature.rs | 2 +- .../ui-fulldeps/proc-macro/signature.stderr | 11 +- 11 files changed, 973 insertions(+), 339 deletions(-) create mode 100644 src/libproc_macro/bridge.rs create mode 100644 src/libproc_macro/rustc.rs diff --git a/src/libproc_macro/bridge.rs b/src/libproc_macro/bridge.rs new file mode 100644 index 0000000000000..697a9d79c94e3 --- /dev/null +++ b/src/libproc_macro/bridge.rs @@ -0,0 +1,547 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Internal interface for communicating with the front-end of a compiler. +//! +//! C ABI and "generation tagging" are employed to allow safely interfacing +//! between two copies of `proc_macro` built (from the same source by different +//! compilers with potentially mismatching Rust ABIs (e.g. during bootstrap). +//! +//! FIXME(eddyb) fully implement the ABI compatibility described above. +//! So far it wouldn't be needed unless beta and nightly differ in +//! type layout or function call ABI, and it's only relevant to +//! `stage1/bin/rustc` loading and invoking proc macros it built. + +use std::cell::Cell; +use std::fmt; +use std::ptr::NonNull; + +use self::storage::{FromConcrete, ToConcrete}; + +mod generation { + use std::cell::Cell; + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub(super) struct Generation(usize); + + impl !Send for Generation {} + impl !Sync for Generation {} + + impl Generation { + pub(super) extern "C" fn next() -> Self { + thread_local!(static NEXT: Cell = Cell::new(0)); + NEXT.with(|next| { + let gen = next.get(); + next.set(gen.checked_add(1).expect("Generation::next overflowed counter")); + Generation(gen) + }) + } + } +} + +#[macro_use] +mod storage { + use std::marker::PhantomData; + use std::mem; + use std::ptr::NonNull; + + use super::generation::Generation; + + #[repr(C)] + pub(super) struct Storage { + gen: Generation, + _marker: PhantomData, + } + + impl Storage { + pub(super) fn new(next_generation: extern "C" fn() -> Generation) -> Self { + Storage { + gen: next_generation(), + _marker: PhantomData, + } + } + } + + pub(super) trait Concrete { + type Concrete: 'static; + } + + pub(super) trait FromConcrete { + fn from_concrete(&self, x: T) -> U; + } + + pub(super) trait ToConcrete { + fn to_concrete(&self, x: T) -> U; + } + + // FIXME(eddyb) achieve ABI compatibility for these types. + impl FromConcrete<(T1, T2), (U1, U2)> for S + where S: FromConcrete + FromConcrete + { + fn from_concrete(&self, (a, b): (T1, T2)) -> (U1, U2) { + (self.from_concrete(a), self.from_concrete(b)) + } + } + + // FIXME(eddyb) achieve ABI compatibility for these types. + impl, T, U> FromConcrete, Option> for S { + fn from_concrete(&self, x: Option) -> Option { + x.map(|x| self.from_concrete(x)) + } + } + + // FIXME(eddyb) achieve ABI compatibility for these types. + impl FromConcrete, Result> for S + where S: FromConcrete + FromConcrete + { + fn from_concrete(&self, r: Result) -> Result { + r.map(|x| self.from_concrete(x)).map_err(|e| self.from_concrete(e)) + } + } + + macro_rules! storage_concrete_passthrough { + ($([$($generics:tt),*] $ty:ty),*) => { + $( + impl<$($generics,)* S> FromConcrete<$ty, $ty> for S { + fn from_concrete(&self, x: $ty) -> $ty { x } + } + impl<$($generics,)* S> ToConcrete<$ty, $ty> for S { + fn to_concrete(&self, x: $ty) -> $ty { x } + } + )* + } + } + + pub(super) trait Cleanup: Sized { + fn cleanup_boxed(boxed: Boxed); + } + + #[repr(C)] + pub(super) struct Boxed { + ptr: NonNull<*mut ()>, + gen: Generation, + _marker: PhantomData, + } + + impl !Send for Boxed {} + impl !Sync for Boxed {} + + impl Drop for Boxed { + fn drop(&mut self) { + T::cleanup_boxed(Boxed { + ptr: self.ptr, + gen: self.gen, + _marker: PhantomData, + }); + } + } + + impl> FromConcrete, Boxed> for Storage { + fn from_concrete(&self, x: Box) -> Boxed { + Boxed { + ptr: Box::into_raw_non_null(x).cast(), + gen: self.gen, + _marker: PhantomData, + } + } + } + + impl> ToConcrete, Box> for Storage { + fn to_concrete(&self, x: Boxed) -> Box { + assert_eq!(x.gen, self.gen); + let ptr = x.ptr.cast::(); + mem::forget(x); + unsafe { + Box::from_raw(ptr.as_ptr()) + } + } + } + + impl<'a, S, T: Cleanup + Concrete> ToConcrete<&'a Boxed, &'a T::Concrete> for Storage { + fn to_concrete(&self, x: &'a Boxed) -> &'a T::Concrete { + assert_eq!(x.gen, self.gen); + unsafe { + &*x.ptr.cast::().as_ptr() + } + } + } + + impl<'a, S, T: Cleanup + Concrete> ToConcrete<&'a mut Boxed, &'a mut T::Concrete> + for Storage { + fn to_concrete(&self, x: &'a mut Boxed) -> &'a mut T::Concrete { + assert_eq!(x.gen, self.gen); + unsafe { + &mut *x.ptr.cast::().as_ptr() + } + } + } +} + +storage_concrete_passthrough! { + [] (), + [] bool, + ['a] &'a str, + + // FIXME(eddyb) achieve ABI compatibility for these types. + [] ::TokenTree, + [] ::Span, + [] ::Delimiter, + [] ::LexError, + // NOTE(eddyb) this will need some `extern "C" fn write`. + ['a, 'b] &'a mut fmt::Formatter<'b>, + [] fmt::Error +} + +macro_rules! each_frontend_method { + ($meth:ident) => { + $meth!(fn token_stream_cleanup(&self, _stream: Self::TokenStream) -> () {}); + $meth!(fn token_stream_clone(&self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + }); + $meth!(fn token_stream_debug(&self, stream: &Self::TokenStream, + f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(stream, f) + }); + $meth!(fn token_stream_display(&self, stream: &Self::TokenStream, + f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(stream, f) + }); + $meth!(fn token_stream_empty(&self) -> Self::TokenStream;); + $meth!(fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool;); + $meth!(fn token_stream_from_str(&self, src: &str) + -> Result;); + $meth!(fn token_stream_delimited(&self, span: ::Span, + delimiter: ::Delimiter, + delimed: Self::TokenStream) + -> Self::TokenStream;); + $meth!(fn token_stream_from_token_tree(&self, tree: ::TokenTree) + -> Self::TokenStream;); + $meth!(fn token_stream_to_token_tree(&self, stream: Self::TokenStream) + -> Result<(::TokenTree, Option), + (::Span, (::Delimiter, + Self::TokenStream))>;); + $meth!(fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor;); + + $meth!(fn token_stream_builder_cleanup(&self, _builder: Self::TokenStreamBuilder) -> () {}); + $meth!(fn token_stream_builder_new(&self) -> Self::TokenStreamBuilder;); + $meth!(fn token_stream_builder_push(&self, builder: &mut Self::TokenStreamBuilder, + stream: Self::TokenStream) -> ();); + $meth!(fn token_stream_builder_build(&self, builder: Self::TokenStreamBuilder) + -> Self::TokenStream;); + + $meth!(fn token_cursor_cleanup(&self, _cursor: Self::TokenCursor) -> () {}); + $meth!(fn token_cursor_clone(&self, cursor: &Self::TokenCursor) -> Self::TokenCursor { + cursor.clone() + }); + $meth!(fn token_cursor_next(&self, cursor: &mut Self::TokenCursor) + -> Option;); + } +} + +macro_rules! define_frontend_trait_method { + ($($m:tt)*) => ($($m)*) +} +pub trait FrontendInterface { + type TokenStream: 'static + Clone + fmt::Debug + fmt::Display; + type TokenStreamBuilder: 'static; + type TokenCursor: 'static + Clone; + each_frontend_method!(define_frontend_trait_method); +} + +macro_rules! define_boxed { + ($($name:ident { cleanup: $cleanup:ident }),*) => { + $( + #[repr(C)] + pub(crate) struct $name(storage::Boxed<$name>); + impl storage::Concrete for $name { + type Concrete = F::$name; + } + impl storage::Cleanup for $name { + fn cleanup_boxed(boxed: storage::Boxed) { + Frontend.$cleanup($name(boxed)) + } + } + impl FromConcrete for storage::Storage + where $name: storage::Concrete + { + fn from_concrete(&self, x: T) -> $name { + $name(self.from_concrete(Box::new(x))) + } + } + impl ToConcrete<$name, T> for storage::Storage + where $name: storage::Concrete + { + fn to_concrete(&self, x: $name) -> T { + *self.to_concrete(x.0) + } + } + impl<'a, S, T: 'static> ToConcrete<&'a $name, &'a T> for storage::Storage + where $name: storage::Concrete + { + fn to_concrete(&self, x: &'a $name) -> &'a T { + self.to_concrete(&x.0) + } + } + impl<'a, S, T: 'static> ToConcrete<&'a mut $name, &'a mut T> for storage::Storage + where $name: storage::Concrete + { + fn to_concrete(&self, x: &'a mut $name) -> &'a mut T { + self.to_concrete(&mut x.0) + } + } + )* + } +} + +define_boxed! { + TokenStream { + cleanup: token_stream_cleanup + }, + TokenStreamBuilder { + cleanup: token_stream_builder_cleanup + }, + TokenCursor { + cleanup: token_cursor_cleanup + } +} + +impl Clone for TokenStream { + fn clone(&self) -> Self { + Frontend.token_stream_clone(self) + } +} + +impl fmt::Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Frontend.token_stream_debug(self, f) + } +} + +impl fmt::Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Frontend.token_stream_display(self, f) + } +} + +impl Clone for TokenCursor { + fn clone(&self) -> Self { + Frontend.token_cursor_clone(self) + } +} + +pub(crate) struct Frontend; + +macro_rules! define_frontend_current_method { + (fn $name:ident(&$self:ident $(, $arg:ident: $arg_ty:ty)*) -> $ret_ty:ty + $($body:block)* $(;)*) => { + fn $name(&$self $(, $arg: $arg_ty)*) -> $ret_ty { + with_current_frontend(|current| current.$name($($arg),*)) + } + } +} +impl FrontendInterface for Frontend { + type TokenStream = TokenStream; + type TokenStreamBuilder = TokenStreamBuilder; + type TokenCursor = TokenCursor; + each_frontend_method!(define_frontend_current_method); +} + +// FIXME(eddyb) generate a manual C ABI vtable instead. +type CurrentFrontend<'a> = FrontendInterface< + TokenStream = TokenStream, + TokenStreamBuilder = TokenStreamBuilder, + TokenCursor = TokenCursor, +> + 'a; + +// Emulate scoped_thread_local!() here essentially +thread_local! { + static CURRENT_FRONTEND: Cell>>> = Cell::new(None); +} + +pub fn has_current_frontend() -> bool { + CURRENT_FRONTEND.with(|p| p.get().is_some()) +} + +fn with_current_frontend(f: F) -> R + where F: FnOnce(&CurrentFrontend) -> R +{ + let p = CURRENT_FRONTEND.with(|p| p.get()); + assert!(!p.is_none(), "proc_macro::bridge::with_current_frontend() called \ + before set_current_frontend()!"); + f(unsafe { p.unwrap().as_ref() }) +} + +fn set_current_frontend(frontend: &CurrentFrontend, f: F) -> R + where F: FnOnce() -> R +{ + struct Reset { prev: Option>> } + + impl Drop for Reset { + fn drop(&mut self) { + CURRENT_FRONTEND.with(|p| p.set(self.prev)); + } + } + + CURRENT_FRONTEND.with(|p| { + let _reset = Reset { prev: p.get() }; + p.set(NonNull::new(frontend as *const _ as *mut _)); + f() + }) +} + +fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generation, + frontend: F, + f: G) -> R + where F: FrontendInterface, + G: FnOnce(&CurrentFrontend, &storage::Storage) -> R +{ + struct EraseConcrete { + storage: storage::Storage, + concrete: F + } + + macro_rules! define_frontend_erase_concrete_method { + (fn $name:ident(&$self:ident $(, $arg:ident: $arg_ty:ty)*) -> $ret_ty:ty + $($body:block)* $(;)*) => { + fn $name(&$self $(, $arg: $arg_ty)*) -> $ret_ty { + let r = $self.concrete.$name($($self.storage.to_concrete($arg)),*); + $self.storage.from_concrete(r) + } + } + } + impl FrontendInterface for EraseConcrete { + type TokenStream = TokenStream; + type TokenStreamBuilder = TokenStreamBuilder; + type TokenCursor = TokenCursor; + each_frontend_method!(define_frontend_erase_concrete_method); + } + + let frontend = EraseConcrete { + storage: storage::Storage::new(ng), + concrete: frontend + }; + f(&frontend, &frontend.storage) +} + +/// A function taking one `TokenStream` and returning another, +/// which may be using a different `proc_macro` from the one +/// used by the frontend, but can be interacted with compatibly. +#[repr(C)] +pub struct Expand1 { + next_generation: extern "C" fn() -> generation::Generation, + data: *const (), + run: unsafe extern "C" fn(*const (), &&CurrentFrontend, TokenStream) + -> TokenStream, +} + +impl !Send for Expand1 {} +impl !Sync for Expand1 {} + +impl Expand1 { + pub fn new(f: &'static F) -> Self + where F: Fn(::TokenStream) -> ::TokenStream + { + unsafe extern "C" fn run(f: *const (), + frontend: &&CurrentFrontend, + input: TokenStream) -> TokenStream + where F: Fn(::TokenStream) -> ::TokenStream + { + let f = &*(f as *const F); + set_current_frontend(*frontend, || { + f(::TokenStream(input)).0 + }) + } + Expand1 { + next_generation: generation::Generation::next, + data: f as *const _ as *const (), + run: run:: + } + } + + pub fn run(&self, frontend: F, input: F::TokenStream) -> F::TokenStream + where F: FrontendInterface + { + erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { + let input = storage.from_concrete(input); + let output = unsafe { + (self.run)(self.data, &frontend, input) + }; + storage.to_concrete(output) + }) + } +} + +/// A function taking two `TokenStream`s and returning another, +/// which may be using a different `proc_macro` from the one +/// used by the frontend, but can be interacted with compatibly. +#[repr(C)] +pub struct Expand2 { + next_generation: extern "C" fn() -> generation::Generation, + data: *const (), + run: unsafe extern "C" fn(*const (), &&CurrentFrontend, TokenStream, TokenStream) + -> TokenStream, +} + +impl !Send for Expand2 {} +impl !Sync for Expand2 {} + +impl Expand2 { + pub fn new(f: &'static F) -> Self + where F: Fn(::TokenStream, ::TokenStream) -> ::TokenStream + { + unsafe extern "C" fn run(f: *const (), + frontend: &&CurrentFrontend, + input: TokenStream, + input2: TokenStream) -> TokenStream + where F: Fn(::TokenStream, ::TokenStream) -> ::TokenStream + { + let f = &*(f as *const F); + set_current_frontend(*frontend, || { + f(::TokenStream(input), ::TokenStream(input2)).0 + }) + } + Expand2 { + next_generation: generation::Generation::next, + data: f as *const _ as *const (), + run: run:: + } + } + + pub fn run(&self, frontend: F, input: F::TokenStream, input2: F::TokenStream) + -> F::TokenStream + where F: FrontendInterface + { + erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { + let input = storage.from_concrete(input); + let input2 = storage.from_concrete(input2); + let output = unsafe { + (self.run)(self.data, &frontend, input, input2) + }; + storage.to_concrete(output) + }) + } +} + +// FIXME(eddyb) use a C ABI wrapper instead of `&mut Registry` in the registrar. +pub trait Registry { + fn register_custom_derive(&mut self, + trait_name: &str, + expand: Expand1, + attributes: &[&'static str]); + + fn register_attr_proc_macro(&mut self, + name: &str, + expand: Expand2); + + fn register_bang_proc_macro(&mut self, + name: &str, + expand: Expand1); +} diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index b239f8018bebb..ace095a15bb57 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -39,6 +39,8 @@ #![feature(staged_api)] #![feature(lang_items)] #![feature(optin_builtin_traits)] +#![feature(box_into_raw_non_null)] +#![feature(nonnull_cast)] #[macro_use] extern crate syntax; @@ -46,6 +48,16 @@ extern crate syntax_pos; extern crate rustc_errors; extern crate rustc_data_structures; +#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[doc(hidden)] +pub mod bridge; + +use bridge::{Frontend, FrontendInterface}; + +#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[doc(hidden)] +pub mod rustc; + mod diagnostic; #[unstable(feature = "proc_macro", issue = "38356")] @@ -55,14 +67,10 @@ use std::{ascii, fmt, iter}; use rustc_data_structures::sync::Lrc; use std::str::FromStr; -use syntax::ast; -use syntax::errors::DiagnosticBuilder; -use syntax::parse::{self, token}; +use syntax::parse::token; use syntax::symbol::Symbol; -use syntax::tokenstream; use syntax_pos::DUMMY_SP; use syntax_pos::{FileMap, Pos, SyntaxContext, FileName}; -use syntax_pos::hygiene::Mark; /// The main type provided by this crate, representing an abstract stream of /// tokens. @@ -75,7 +83,7 @@ use syntax_pos::hygiene::Mark; /// time! #[stable(feature = "proc_macro_lib", since = "1.15.0")] #[derive(Clone, Debug)] -pub struct TokenStream(tokenstream::TokenStream); +pub struct TokenStream(bridge::TokenStream); /// Error returned from `TokenStream::from_str`. #[stable(feature = "proc_macro_lib", since = "1.15.0")] @@ -89,18 +97,7 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - __internal::with_sess(|(sess, mark)| { - let src = src.to_string(); - let name = FileName::ProcMacroSourceCode; - let expn_info = mark.expn_info().unwrap(); - let call_site = expn_info.call_site; - // notify the expansion info that it is unhygienic - let mark = Mark::fresh(mark); - mark.set_expn_info(expn_info); - let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span)); - Ok(__internal::token_stream_wrap(stream)) - }) + Frontend.token_stream_from_str(src).map(TokenStream) } } @@ -128,7 +125,12 @@ mod quote; #[unstable(feature = "proc_macro", issue = "38356")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream(tree.to_internal()) + TokenStream(match tree.kind { + TokenNode::Group(delimiter, tokens) => { + Frontend.token_stream_delimited(tree.span, delimiter, tokens.0) + } + _ => Frontend.token_stream_from_token_tree(tree) + }) } } @@ -142,11 +144,11 @@ impl From for TokenStream { #[unstable(feature = "proc_macro", issue = "38356")] impl> iter::FromIterator for TokenStream { fn from_iter>(streams: I) -> Self { - let mut builder = tokenstream::TokenStreamBuilder::new(); + let mut builder = Frontend.token_stream_builder_new(); for stream in streams { - builder.push(stream.into().0); + Frontend.token_stream_builder_push(&mut builder, stream.into().0); } - TokenStream(builder.build()) + TokenStream(Frontend.token_stream_builder_build(builder)) } } @@ -156,7 +158,10 @@ impl IntoIterator for TokenStream { type IntoIter = TokenTreeIter; fn into_iter(self) -> TokenTreeIter { - TokenTreeIter { cursor: self.0.trees(), next: None } + TokenTreeIter { + cursor: Frontend.token_stream_trees(self.0), + next: None, + } } } @@ -164,13 +169,13 @@ impl TokenStream { /// Returns an empty `TokenStream`. #[unstable(feature = "proc_macro", issue = "38356")] pub fn empty() -> TokenStream { - TokenStream(tokenstream::TokenStream::empty()) + TokenStream(Frontend.token_stream_empty()) } /// Checks if this `TokenStream` is empty. #[unstable(feature = "proc_macro", issue = "38356")] pub fn is_empty(&self) -> bool { - self.0.is_empty() + Frontend.token_stream_is_empty(&self.0) } } @@ -553,8 +558,8 @@ impl Literal { #[derive(Clone)] #[unstable(feature = "proc_macro", issue = "38356")] pub struct TokenTreeIter { - cursor: tokenstream::Cursor, - next: Option, + cursor: bridge::TokenCursor, + next: Option, } #[unstable(feature = "proc_macro", issue = "38356")] @@ -562,194 +567,20 @@ impl Iterator for TokenTreeIter { type Item = TokenTree; fn next(&mut self) -> Option { - loop { - let next = - unwrap_or!(self.next.take().or_else(|| self.cursor.next_as_stream()), return None); - let tree = TokenTree::from_internal(next, &mut self.next); - if tree.span.0 == DUMMY_SP { - if let TokenNode::Group(Delimiter::None, stream) = tree.kind { - self.cursor.insert(stream.0); - continue - } - } - return Some(tree); - } - } -} - -impl Delimiter { - fn from_internal(delim: token::DelimToken) -> Delimiter { - match delim { - token::Paren => Delimiter::Parenthesis, - token::Brace => Delimiter::Brace, - token::Bracket => Delimiter::Bracket, - token::NoDelim => Delimiter::None, - } - } - - fn to_internal(self) -> token::DelimToken { - match self { - Delimiter::Parenthesis => token::Paren, - Delimiter::Brace => token::Brace, - Delimiter::Bracket => token::Bracket, - Delimiter::None => token::NoDelim, - } - } -} - -impl TokenTree { - fn from_internal(stream: tokenstream::TokenStream, next: &mut Option) - -> TokenTree { - use syntax::parse::token::*; - - let (tree, is_joint) = stream.as_tree(); - let (mut span, token) = match tree { - tokenstream::TokenTree::Token(span, token) => (span, token), - tokenstream::TokenTree::Delimited(span, delimed) => { - let delimiter = Delimiter::from_internal(delimed.delim); - return TokenTree { - span: Span(span), - kind: TokenNode::Group(delimiter, TokenStream(delimed.tts.into())), - }; + let next = unwrap_or!(self.next.take().or_else(|| { + Frontend.token_cursor_next(&mut self.cursor) + }), return None); + let (tree, next) = match Frontend.token_stream_to_token_tree(next) { + Ok((tree, next)) => (tree, next), + Err((span, (delimiter, delimed))) => { + (TokenTree { + span, + kind: TokenNode::Group(delimiter, TokenStream(delimed)), + }, None) } }; - - let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone }; - macro_rules! op { - ($op:expr) => { TokenNode::Op($op, op_kind) } - } - - macro_rules! joint { - ($first:expr, $rest:expr) => { joint($first, $rest, is_joint, &mut span, next) } - } - - fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span, - next: &mut Option) - -> TokenNode { - let (first_span, rest_span) = (*span, *span); - *span = first_span; - let tree = tokenstream::TokenTree::Token(rest_span, rest); - *next = Some(if is_joint { tree.joint() } else { tree.into() }); - TokenNode::Op(first, Spacing::Joint) - } - - let kind = match token { - Eq => op!('='), - Lt => op!('<'), - Le => joint!('<', Eq), - EqEq => joint!('=', Eq), - Ne => joint!('!', Eq), - Ge => joint!('>', Eq), - Gt => op!('>'), - AndAnd => joint!('&', BinOp(And)), - OrOr => joint!('|', BinOp(Or)), - Not => op!('!'), - Tilde => op!('~'), - BinOp(Plus) => op!('+'), - BinOp(Minus) => op!('-'), - BinOp(Star) => op!('*'), - BinOp(Slash) => op!('/'), - BinOp(Percent) => op!('%'), - BinOp(Caret) => op!('^'), - BinOp(And) => op!('&'), - BinOp(Or) => op!('|'), - BinOp(Shl) => joint!('<', Lt), - BinOp(Shr) => joint!('>', Gt), - BinOpEq(Plus) => joint!('+', Eq), - BinOpEq(Minus) => joint!('-', Eq), - BinOpEq(Star) => joint!('*', Eq), - BinOpEq(Slash) => joint!('/', Eq), - BinOpEq(Percent) => joint!('%', Eq), - BinOpEq(Caret) => joint!('^', Eq), - BinOpEq(And) => joint!('&', Eq), - BinOpEq(Or) => joint!('|', Eq), - BinOpEq(Shl) => joint!('<', Le), - BinOpEq(Shr) => joint!('>', Ge), - At => op!('@'), - Dot => op!('.'), - DotDot => joint!('.', Dot), - DotDotDot => joint!('.', DotDot), - DotDotEq => joint!('.', DotEq), - Comma => op!(','), - Semi => op!(';'), - Colon => op!(':'), - ModSep => joint!(':', Colon), - RArrow => joint!('-', Gt), - LArrow => joint!('<', BinOp(Minus)), - FatArrow => joint!('=', Gt), - Pound => op!('#'), - Dollar => op!('$'), - Question => op!('?'), - - Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), - Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)), - - Interpolated(_) => { - __internal::with_sess(|(sess, _)| { - let tts = token.interpolated_to_tokenstream(sess, span); - TokenNode::Group(Delimiter::None, TokenStream(tts)) - }) - } - - DotEq => joint!('.', Eq), - OpenDelim(..) | CloseDelim(..) => unreachable!(), - Whitespace | Comment | Shebang(..) | Eof => unreachable!(), - }; - - TokenTree { span: Span(span), kind: kind } - } - - fn to_internal(self) -> tokenstream::TokenStream { - use syntax::parse::token::*; - use syntax::tokenstream::{TokenTree, Delimited}; - - let (op, kind) = match self.kind { - TokenNode::Op(op, kind) => (op, kind), - TokenNode::Group(delimiter, tokens) => { - return TokenTree::Delimited(self.span.0, Delimited { - delim: delimiter.to_internal(), - tts: tokens.0.into(), - }).into(); - }, - TokenNode::Term(symbol) => { - let ident = ast::Ident { name: symbol.0, ctxt: self.span.0.ctxt() }; - let token = - if symbol.0.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) }; - return TokenTree::Token(self.span.0, token).into(); - } - TokenNode::Literal(token) => return TokenTree::Token(self.span.0, token.0).into(), - }; - - let token = match op { - '=' => Eq, - '<' => Lt, - '>' => Gt, - '!' => Not, - '~' => Tilde, - '+' => BinOp(Plus), - '-' => BinOp(Minus), - '*' => BinOp(Star), - '/' => BinOp(Slash), - '%' => BinOp(Percent), - '^' => BinOp(Caret), - '&' => BinOp(And), - '|' => BinOp(Or), - '@' => At, - '.' => Dot, - ',' => Comma, - ';' => Semi, - ':' => Colon, - '#' => Pound, - '$' => Dollar, - '?' => Question, - _ => panic!("unsupported character {}", op), - }; - - let tree = TokenTree::Token(self.span.0, token); - match kind { - Spacing::Alone => tree.into(), - Spacing::Joint => tree.joint(), - } + self.next = next; + Some(tree) } } @@ -765,64 +596,26 @@ impl TokenTree { #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] pub mod __internal { - pub use quote::{LiteralKind, Quoter, unquote}; + pub use bridge::{Expand1, Expand2, Registry}; + pub use quote::{LiteralKind, unquote}; use std::cell::Cell; - use syntax::ast; + use syntax::errors::DiagnosticBuilder; use syntax::ext::base::ExtCtxt; use syntax::ext::hygiene::Mark; - use syntax::ptr::P; - use syntax::parse::{self, ParseSess}; - use syntax::parse::token::{self, Token}; - use syntax::tokenstream; - use syntax_pos::{BytePos, Loc, DUMMY_SP}; + use syntax::parse::ParseSess; + use syntax_pos::{BytePos, Loc}; - use super::{TokenStream, LexError}; + use super::LexError; pub fn lookup_char_pos(pos: BytePos) -> Loc { with_sess(|(sess, _)| sess.codemap().lookup_char_pos(pos)) } - pub fn new_token_stream(item: P) -> TokenStream { - let token = Token::interpolated(token::NtItem(item)); - TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into()) - } - - pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream { - TokenStream(inner) - } - - pub fn token_stream_parse_items(stream: TokenStream) -> Result>, LexError> { - with_sess(move |(sess, _)| { - let mut parser = parse::stream_to_parser(sess, stream.0); - let mut items = Vec::new(); - - while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) { - items.push(item) - } - - Ok(items) - }) - } - - pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream { - stream.0 - } - - pub trait Registry { - fn register_custom_derive(&mut self, - trait_name: &str, - expand: fn(TokenStream) -> TokenStream, - attributes: &[&'static str]); - - fn register_attr_proc_macro(&mut self, - name: &str, - expand: fn(TokenStream, TokenStream) -> TokenStream); - - fn register_bang_proc_macro(&mut self, - name: &str, - expand: fn(TokenStream) -> TokenStream); + pub fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError { + err.cancel(); + LexError { _inner: () } } // Emulate scoped_thread_local!() here essentially @@ -845,6 +638,7 @@ pub mod __internal { CURRENT_SESS.with(|p| { let _reset = Reset { prev: p.get() }; p.set((cx.parse_sess, cx.current_expansion.mark)); + f() }) } @@ -864,8 +658,3 @@ pub mod __internal { f(unsafe { (&*p.0, p.1) }) } } - -fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError { - err.cancel(); - LexError { _inner: () } -} diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index 8b5add1a0f0d7..2608fe9d3f068 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -16,11 +16,7 @@ use {Delimiter, Literal, Spacing, Span, Term, TokenNode, TokenStream, TokenTree}; -use syntax::ext::base::{ExtCtxt, ProcMacro}; use syntax::parse::token; -use syntax::tokenstream; - -pub struct Quoter; pub fn unquote + Clone>(tokens: &T) -> TokenStream { T::into(tokens.clone()) @@ -67,18 +63,6 @@ macro_rules! quote { }; } -impl ProcMacro for Quoter { - fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, - _: ::syntax_pos::Span, - stream: tokenstream::TokenStream) - -> tokenstream::TokenStream { - let mut info = cx.current_expansion.mark.expn_info().unwrap(); - info.callee.allow_internal_unstable = true; - cx.current_expansion.mark.set_expn_info(info); - ::__internal::set_sess(cx, || TokenStream(stream).quote().0) - } -} - impl Quote for Option { fn quote(self) -> TokenStream { match self { diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs new file mode 100644 index 0000000000000..234b1ab14c185 --- /dev/null +++ b/src/libproc_macro/rustc.rs @@ -0,0 +1,282 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use {__internal, Delimiter, Spacing, Span, Term, TokenNode, TokenTree}; + +use syntax_pos::{self, SyntaxContext, FileName}; +use syntax_pos::hygiene::Mark; +use syntax::ast; +use syntax::ext::base::{ExtCtxt, ProcMacro}; +use syntax::parse::{self, token}; +use syntax::tokenstream; + +pub struct Quoter; + +impl ProcMacro for Quoter { + fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, + _: syntax_pos::Span, + stream: tokenstream::TokenStream) + -> tokenstream::TokenStream { + let expand_quoter = ::bridge::Expand1::new(&::quote::Quote::quote); + + let mut info = cx.current_expansion.mark.expn_info().unwrap(); + info.callee.allow_internal_unstable = true; + cx.current_expansion.mark.set_expn_info(info); + __internal::set_sess(cx, || expand_quoter.run(Rustc, stream)) + } +} + +impl Delimiter { + fn from_internal(delim: token::DelimToken) -> Delimiter { + match delim { + token::Paren => Delimiter::Parenthesis, + token::Brace => Delimiter::Brace, + token::Bracket => Delimiter::Bracket, + token::NoDelim => Delimiter::None, + } + } + + fn to_internal(self) -> token::DelimToken { + match self { + Delimiter::Parenthesis => token::Paren, + Delimiter::Brace => token::Brace, + Delimiter::Bracket => token::Bracket, + Delimiter::None => token::NoDelim, + } + } +} + +pub struct Rustc; +impl ::bridge::FrontendInterface for Rustc { + type TokenStream = tokenstream::TokenStream; + type TokenStreamBuilder = tokenstream::TokenStreamBuilder; + type TokenCursor = tokenstream::Cursor; + + + fn token_stream_empty(&self) -> Self::TokenStream { + tokenstream::TokenStream::empty() + } + fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool { + stream.is_empty() + } + fn token_stream_from_str(&self, src: &str) -> Result { + ::__internal::with_sess(|(sess, mark)| { + let src = src.to_string(); + let name = FileName::ProcMacroSourceCode; + let expn_info = mark.expn_info().unwrap(); + let call_site = expn_info.call_site; + // notify the expansion info that it is unhygienic + let mark = Mark::fresh(mark); + mark.set_expn_info(expn_info); + let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); + Ok(parse::parse_stream_from_source_str(name, src, sess, Some(span))) + }) + } + fn token_stream_delimited(&self, span: ::Span, + delimiter: ::Delimiter, + delimed: Self::TokenStream) + -> Self::TokenStream { + tokenstream::TokenTree::Delimited(span.0, tokenstream::Delimited { + delim: delimiter.to_internal(), + tts: delimed.into(), + }).into() + } + fn token_stream_from_token_tree(&self, tree: TokenTree) -> Self::TokenStream { + use syntax::parse::token::*; + use syntax::tokenstream::TokenTree; + + let (op, kind) = match tree.kind { + TokenNode::Op(op, kind) => (op, kind), + TokenNode::Group(..) => unreachable!(), + TokenNode::Term(symbol) => { + let ident = ast::Ident { name: symbol.0, ctxt: tree.span.0.ctxt() }; + let token = if symbol.0.as_str().starts_with("'") { + Lifetime(ident) + } else { + Ident(ident) + }; + return TokenTree::Token(tree.span.0, token).into(); + } + TokenNode::Literal(token) => return TokenTree::Token(tree.span.0, token.0).into(), + }; + + let token = match op { + '=' => Eq, + '<' => Lt, + '>' => Gt, + '!' => Not, + '~' => Tilde, + '+' => BinOp(Plus), + '-' => BinOp(Minus), + '*' => BinOp(Star), + '/' => BinOp(Slash), + '%' => BinOp(Percent), + '^' => BinOp(Caret), + '&' => BinOp(And), + '|' => BinOp(Or), + '@' => At, + '.' => Dot, + ',' => Comma, + ';' => Semi, + ':' => Colon, + '#' => Pound, + '$' => Dollar, + '?' => Question, + _ => panic!("unsupported character {}", op), + }; + + let tree = TokenTree::Token(tree.span.0, token); + match kind { + Spacing::Alone => tree.into(), + Spacing::Joint => tree.joint(), + } + } + fn token_stream_to_token_tree(&self, stream: Self::TokenStream) + -> Result<(::TokenTree, Option), + (::Span, (::Delimiter, Self::TokenStream))> { + use syntax::parse::token::*; + + let mut next = None; + + let (tree, is_joint) = stream.as_tree(); + let (mut span, token) = match tree { + tokenstream::TokenTree::Delimited(span, delimed) => { + let delimiter = Delimiter::from_internal(delimed.delim); + return Err((Span(span), (delimiter, delimed.tts.into()))); + } + tokenstream::TokenTree::Token(span, token) => (span, token), + }; + + let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone }; + macro_rules! op { + ($op:expr) => { TokenNode::Op($op, op_kind) } + } + + macro_rules! joint { + ($first:expr, $rest:expr) => { + joint($first, $rest, is_joint, &mut span, &mut next) + } + } + + fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span, + next: &mut Option) + -> TokenNode { + let (first_span, rest_span) = (*span, *span); + *span = first_span; + let tree = tokenstream::TokenTree::Token(rest_span, rest); + *next = Some(if is_joint { tree.joint() } else { tree.into() }); + TokenNode::Op(first, Spacing::Joint) + } + + let kind = match token { + Eq => op!('='), + Lt => op!('<'), + Le => joint!('<', Eq), + EqEq => joint!('=', Eq), + Ne => joint!('!', Eq), + Ge => joint!('>', Eq), + Gt => op!('>'), + AndAnd => joint!('&', BinOp(And)), + OrOr => joint!('|', BinOp(Or)), + Not => op!('!'), + Tilde => op!('~'), + BinOp(Plus) => op!('+'), + BinOp(Minus) => op!('-'), + BinOp(Star) => op!('*'), + BinOp(Slash) => op!('/'), + BinOp(Percent) => op!('%'), + BinOp(Caret) => op!('^'), + BinOp(And) => op!('&'), + BinOp(Or) => op!('|'), + BinOp(Shl) => joint!('<', Lt), + BinOp(Shr) => joint!('>', Gt), + BinOpEq(Plus) => joint!('+', Eq), + BinOpEq(Minus) => joint!('-', Eq), + BinOpEq(Star) => joint!('*', Eq), + BinOpEq(Slash) => joint!('/', Eq), + BinOpEq(Percent) => joint!('%', Eq), + BinOpEq(Caret) => joint!('^', Eq), + BinOpEq(And) => joint!('&', Eq), + BinOpEq(Or) => joint!('|', Eq), + BinOpEq(Shl) => joint!('<', Le), + BinOpEq(Shr) => joint!('>', Ge), + At => op!('@'), + Dot => op!('.'), + DotDot => joint!('.', Dot), + DotDotDot => joint!('.', DotDot), + DotDotEq => joint!('.', DotEq), + Comma => op!(','), + Semi => op!(';'), + Colon => op!(':'), + ModSep => joint!(':', Colon), + RArrow => joint!('-', Gt), + LArrow => joint!('<', BinOp(Minus)), + FatArrow => joint!('=', Gt), + Pound => op!('#'), + Dollar => op!('$'), + Question => op!('?'), + + Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Literal(..) | DocComment(..) => TokenNode::Literal(::Literal(token)), + + Interpolated(_) => { + return Err((Span(span), __internal::with_sess(|(sess, _)| { + let tts = token.interpolated_to_tokenstream(sess, span); + (Delimiter::None, tts) + }))); + } + + DotEq => joint!('.', Eq), + OpenDelim(..) | CloseDelim(..) => unreachable!(), + Whitespace | Comment | Shebang(..) | Eof => unreachable!(), + }; + + Ok((TokenTree { span: Span(span), kind: kind }, next)) + } + fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor { + stream.trees() + } + + fn token_stream_builder_new(&self) -> Self::TokenStreamBuilder { + tokenstream::TokenStreamBuilder::new() + } + fn token_stream_builder_push(&self, builder: &mut Self::TokenStreamBuilder, + stream: Self::TokenStream) { + builder.push(stream); + } + fn token_stream_builder_build(&self, builder: Self::TokenStreamBuilder) + -> Self::TokenStream { + builder.build() + } + + fn token_cursor_next(&self, cursor: &mut Self::TokenCursor) -> Option { + while let Some(stream) = cursor.next_as_stream() { + let (tree, _) = stream.clone().as_tree(); + let span = tree.span(); + if span != DUMMY_SP { + return Some(stream); + } + let nested_stream = match tree { + tokenstream::TokenTree::Delimited(_, tokenstream::Delimited { + delim: token::NoDelim, + tts + }) => tts.into(), + tokenstream::TokenTree::Token(_, token @ token::Interpolated(_)) => { + __internal::with_sess(|(sess, _)| { + token.interpolated_to_tokenstream(sess, span) + }) + } + _ => return Some(stream) + }; + cursor.insert(nested_stream); + } + None + } +} diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a0546b369a8eb..333d9bef87bd2 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -514,8 +514,7 @@ impl<'a> CrateLoader<'a> { fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option, span: Span) -> Vec<(ast::Name, Lrc)> { use std::{env, mem}; - use proc_macro::TokenStream; - use proc_macro::__internal::Registry; + use proc_macro::bridge::{Registry, Expand1, Expand2}; use dynamic_lib::DynamicLibrary; use syntax_ext::deriving::custom::ProcMacroDerive; use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro}; @@ -545,7 +544,7 @@ impl<'a> CrateLoader<'a> { impl Registry for MyRegistrar { fn register_custom_derive(&mut self, trait_name: &str, - expand: fn(TokenStream) -> TokenStream, + expand: Expand1, attributes: &[&'static str]) { let attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); let derive = ProcMacroDerive::new(expand, attrs.clone()); @@ -555,7 +554,7 @@ impl<'a> CrateLoader<'a> { fn register_attr_proc_macro(&mut self, name: &str, - expand: fn(TokenStream, TokenStream) -> TokenStream) { + expand: Expand2) { let expand = SyntaxExtension::AttrProcMacro( Box::new(AttrProcMacro { inner: expand }) ); @@ -564,7 +563,7 @@ impl<'a> CrateLoader<'a> { fn register_bang_proc_macro(&mut self, name: &str, - expand: fn(TokenStream) -> TokenStream) { + expand: Expand1) { let expand = SyntaxExtension::ProcMacro( Box::new(BangProcMacro { inner: expand }) ); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 2de27f3a1c3ea..a8ada587add7c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -502,7 +502,7 @@ impl CrateStore for cstore::CStore { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); } else if data.name == "proc_macro" && self.get_crate_data(id.krate).item_name(id.index) == "quote" { - let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter)); + let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::rustc::Quoter)); return LoadedMacro::ProcMacro(Lrc::new(ext)); } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 22e78e9b426b2..c34029e7bb90a 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -11,12 +11,15 @@ use std::panic; use errors::FatalError; -use proc_macro::{TokenStream, __internal}; use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; use syntax::codemap::Span; use syntax::ext::base::*; +use syntax::parse; +use syntax::parse::token::{self, Token}; +use syntax::tokenstream; use syntax::visit::Visitor; +use syntax_pos::DUMMY_SP; struct MarkAttrs<'a>(&'a [ast::Name]); @@ -34,12 +37,12 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> { } pub struct ProcMacroDerive { - inner: fn(TokenStream) -> TokenStream, + inner: ::proc_macro::bridge::Expand1, attrs: Vec, } impl ProcMacroDerive { - pub fn new(inner: fn(TokenStream) -> TokenStream, attrs: Vec) -> ProcMacroDerive { + pub fn new(inner: ::proc_macro::bridge::Expand1, attrs: Vec) -> ProcMacroDerive { ProcMacroDerive { inner: inner, attrs: attrs } } } @@ -73,11 +76,14 @@ impl MultiItemModifier for ProcMacroDerive { // Mark attributes as known, and used. MarkAttrs(&self.attrs).visit_item(&item); - let input = __internal::new_token_stream(ecx.resolver.eliminate_crate_var(item.clone())); - let res = __internal::set_sess(ecx, || { - let inner = self.inner; - panic::catch_unwind(panic::AssertUnwindSafe(|| inner(input))) - }); + let item = ecx.resolver.eliminate_crate_var(item.clone()); + let token = Token::interpolated(token::NtItem(item)); + let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + ::proc_macro::__internal::set_sess(ecx, || { + self.inner.run(::proc_macro::rustc::Rustc, input) + }) + })); let stream = match res { Ok(stream) => stream, @@ -97,21 +103,32 @@ impl MultiItemModifier for ProcMacroDerive { }; let error_count_before = ecx.parse_sess.span_diagnostic.err_count(); - __internal::set_sess(ecx, || { - let msg = "proc-macro derive produced unparseable tokens"; - match __internal::token_stream_parse_items(stream) { - // fail if there have been errors emitted - Ok(_) if ecx.parse_sess.span_diagnostic.err_count() > error_count_before => { - ecx.struct_span_fatal(span, msg).emit(); - FatalError.raise(); + let msg = "proc-macro derive produced unparseable tokens"; + + let mut parser = parse::stream_to_parser(ecx.parse_sess, stream); + let mut items = vec![]; + + loop { + match parser.parse_item().map_err(::proc_macro::__internal::parse_to_lex_err) { + Ok(None) => break, + Ok(Some(item)) => { + items.push(Annotatable::Item(item)) } - Ok(new_items) => new_items.into_iter().map(Annotatable::Item).collect(), Err(_) => { // FIXME: handle this better ecx.struct_span_fatal(span, msg).emit(); FatalError.raise(); } } - }) + } + + + // fail if there have been errors emitted + if ecx.parse_sess.span_diagnostic.err_count() > error_count_before { + ecx.struct_span_fatal(span, msg).emit(); + FatalError.raise(); + } + + items } } diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 12400e363f4b0..26357d390e1f5 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -17,11 +17,8 @@ use syntax::ext::base::*; use syntax::tokenstream::TokenStream; use syntax::ext::base; -use proc_macro::TokenStream as TsShim; -use proc_macro::__internal; - pub struct AttrProcMacro { - pub inner: fn(TsShim, TsShim) -> TsShim, + pub inner: ::proc_macro::bridge::Expand2, } impl base::AttrProcMacro for AttrProcMacro { @@ -31,15 +28,14 @@ impl base::AttrProcMacro for AttrProcMacro { annotation: TokenStream, annotated: TokenStream) -> TokenStream { - let annotation = __internal::token_stream_wrap(annotation); - let annotated = __internal::token_stream_wrap(annotated); - - let res = __internal::set_sess(ecx, || { - panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(annotation, annotated))) - }); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + ::proc_macro::__internal::set_sess(ecx, || { + self.inner.run(::proc_macro::rustc::Rustc, annotation, annotated) + }) + })); match res { - Ok(stream) => __internal::token_stream_inner(stream), + Ok(stream) => stream, Err(e) => { let msg = "custom attribute panicked"; let mut err = ecx.struct_span_fatal(span, msg); @@ -58,7 +54,7 @@ impl base::AttrProcMacro for AttrProcMacro { } pub struct BangProcMacro { - pub inner: fn(TsShim) -> TsShim, + pub inner: ::proc_macro::bridge::Expand1, } impl base::ProcMacro for BangProcMacro { @@ -67,14 +63,14 @@ impl base::ProcMacro for BangProcMacro { span: Span, input: TokenStream) -> TokenStream { - let input = __internal::token_stream_wrap(input); - - let res = __internal::set_sess(ecx, || { - panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input))) - }); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + ::proc_macro::__internal::set_sess(ecx, || { + self.inner.run(::proc_macro::rustc::Rustc, input) + }) + })); match res { - Ok(stream) => __internal::token_stream_inner(stream), + Ok(stream) => stream, Err(e) => { let msg = "proc macro panicked"; let mut err = ecx.struct_span_fatal(span, msg); diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index e623779ce63ba..802fcffc07cfb 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -348,12 +348,14 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // mod $gensym { // extern crate proc_macro; // -// use proc_macro::__internal::Registry; +// use proc_macro::__internal::{Expand1, Expand2, Registry}; // // #[plugin_registrar] // fn registrar(registrar: &mut Registry) { -// registrar.register_custom_derive($name_trait1, ::$name1, &[]); -// registrar.register_custom_derive($name_trait2, ::$name2, &["attribute_name"]); +// registrar.register_custom_derive($name_trait1, +// Expand1::new(&::$name1), &[]); +// registrar.register_custom_derive($name_trait2, +// Expand1::new(&::$name2), &["attribute_name"]); // // ... // } // } @@ -371,7 +373,8 @@ fn mk_registrar(cx: &mut ExtCtxt, allow_internal_unsafe: false, } }); - let span = DUMMY_SP.with_ctxt(SyntaxContext::empty().apply_mark(mark)); + let ctxt = SyntaxContext::empty().apply_mark(mark); + let span = DUMMY_SP.with_ctxt(ctxt); let proc_macro = Ident::from_str("proc_macro"); let krate = cx.item(span, @@ -380,6 +383,9 @@ fn mk_registrar(cx: &mut ExtCtxt, ast::ItemKind::ExternCrate(None)); let __internal = Ident::from_str("__internal"); + let expand1 = Ident::from_str("Expand1"); + let expand2 = Ident::from_str("Expand2"); + let new = Ident::from_str("new"); let registry = Ident::from_str("Registry"); let registrar = Ident::from_str("_registrar"); let register_custom_derive = Ident::from_str("register_custom_derive"); @@ -387,7 +393,12 @@ fn mk_registrar(cx: &mut ExtCtxt, let register_bang_proc_macro = Ident::from_str("register_bang_proc_macro"); let mut stmts = custom_derives.iter().map(|cd| { - let path = cx.path_global(cd.span, vec![cd.function_name]); + let expand = cx.expr_path(cx.path_global(cd.span, vec![cd.function_name])); + let expand = cx.expr_addr_of(span, expand); + let expand_span = cd.span.with_ctxt(ctxt); + let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ + proc_macro, __internal, expand1, new + ])), vec![expand]); let trait_name = cx.expr_str(cd.span, cd.trait_name); let attrs = cx.expr_vec_slice( span, @@ -398,32 +409,42 @@ fn mk_registrar(cx: &mut ExtCtxt, register_custom_derive]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, trait_name, cx.expr_path(path), attrs])) + vec![registrar, trait_name, expand, attrs])) }).collect::>(); stmts.extend(custom_attrs.iter().map(|ca| { let name = cx.expr_str(ca.span, ca.function_name.name); - let path = cx.path_global(ca.span, vec![ca.function_name]); + let expand = cx.expr_path(cx.path_global(ca.span, vec![ca.function_name])); + let expand = cx.expr_addr_of(span, expand); + let expand_span = ca.span.with_ctxt(ctxt); + let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ + proc_macro, __internal, expand2, new + ])), vec![expand]); let registrar = cx.expr_ident(ca.span, registrar); let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, register_attr_proc_macro]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, name, cx.expr_path(path)])) + vec![registrar, name, expand])) })); stmts.extend(custom_macros.iter().map(|cm| { let name = cx.expr_str(cm.span, cm.function_name.name); - let path = cx.path_global(cm.span, vec![cm.function_name]); + let expand = cx.expr_path(cx.path_global(cm.span, vec![cm.function_name])); + let expand = cx.expr_addr_of(span, expand); + let expand_span = cm.span.with_ctxt(ctxt); + let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ + proc_macro, __internal, expand1, new + ])), vec![expand]); let registrar = cx.expr_ident(cm.span, registrar); let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, register_bang_proc_macro]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), - vec![registrar, name, cx.expr_path(path)])) + vec![registrar, name, expand])) })); let path = cx.path(span, vec![proc_macro, __internal, registry]); diff --git a/src/test/ui-fulldeps/proc-macro/signature.rs b/src/test/ui-fulldeps/proc-macro/signature.rs index f2ea6f778cd26..5d9fca46bd203 100644 --- a/src/test/ui-fulldeps/proc-macro/signature.rs +++ b/src/test/ui-fulldeps/proc-macro/signature.rs @@ -15,6 +15,6 @@ extern crate proc_macro; #[proc_macro_derive(A)] pub unsafe extern fn foo(a: i32, b: u32) -> u32 { - //~^ ERROR: mismatched types + //~^ ERROR: trait bound loop {} } diff --git a/src/test/ui-fulldeps/proc-macro/signature.stderr b/src/test/ui-fulldeps/proc-macro/signature.stderr index fdd10c3c5b903..e9218e5c91fc7 100644 --- a/src/test/ui-fulldeps/proc-macro/signature.stderr +++ b/src/test/ui-fulldeps/proc-macro/signature.stderr @@ -1,15 +1,14 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `unsafe extern "C" fn(i32, u32) -> u32 {foo}: std::ops::Fn<(proc_macro::TokenStream,)>` is not satisfied --> $DIR/signature.rs:17:1 | LL | / pub unsafe extern fn foo(a: i32, b: u32) -> u32 { -LL | | //~^ ERROR: mismatched types +LL | | //~^ ERROR: trait bound LL | | loop {} LL | | } - | |_^ expected normal fn, found unsafe fn + | |_^ the trait `std::ops::Fn<(proc_macro::TokenStream,)>` is not implemented for `unsafe extern "C" fn(i32, u32) -> u32 {foo}` | - = note: expected type `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found type `unsafe extern "C" fn(i32, u32) -> u32 {foo}` + = note: required by `proc_macro::bridge::Expand1::new` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. From 56668e6a01b152ac9090323a14018077b7765f22 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Mar 2018 17:04:14 +0200 Subject: [PATCH 02/14] proc_macro: don't expose compiler-internal FileName in public API. --- src/libproc_macro/lib.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index ace095a15bb57..57584167bbc72 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -64,6 +64,7 @@ mod diagnostic; pub use diagnostic::{Diagnostic, Level}; use std::{ascii, fmt, iter}; +use std::path::PathBuf; use rustc_data_structures::sync::Lrc; use std::str::FromStr; @@ -332,14 +333,17 @@ impl SourceFile { /// the command line, the path as given may not actually be valid. /// /// [`is_real`]: #method.is_real - # [unstable(feature = "proc_macro", issue = "38356")] - pub fn path(&self) -> &FileName { - &self.filemap.name + #[unstable(feature = "proc_macro", issue = "38356")] + pub fn path(&self) -> PathBuf { + match self.filemap.name { + FileName::Real(ref path) => path.clone(), + _ => PathBuf::from(self.filemap.name.to_string()) + } } /// Returns `true` if this source file is a real source file, and not generated by an external /// macro's expansion. - # [unstable(feature = "proc_macro", issue = "38356")] + #[unstable(feature = "proc_macro", issue = "38356")] pub fn is_real(&self) -> bool { // This is a hack until intercrate spans are implemented and we can have real source files // for spans generated in external macros. @@ -348,18 +352,12 @@ impl SourceFile { } } -#[unstable(feature = "proc_macro", issue = "38356")] -impl AsRef for SourceFile { - fn as_ref(&self) -> &FileName { - self.path() - } -} #[unstable(feature = "proc_macro", issue = "38356")] impl fmt::Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("SourceFile") - .field("path", self.path()) + .field("path", &self.path()) .field("is_real", &self.is_real()) .finish() } @@ -375,13 +373,6 @@ impl PartialEq for SourceFile { #[unstable(feature = "proc_macro", issue = "38356")] impl Eq for SourceFile {} -#[unstable(feature = "proc_macro", issue = "38356")] -impl PartialEq for SourceFile { - fn eq(&self, other: &FileName) -> bool { - self.as_ref() == other - } -} - /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). #[unstable(feature = "proc_macro", issue = "38356")] #[derive(Clone, Debug)] From c05a2b28b24eca22920c276ff1effde9940fd16d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Mar 2018 19:25:03 +0200 Subject: [PATCH 03/14] proc_macro: move SourceFile to the bridge. --- src/libproc_macro/bridge.rs | 27 +++++++++++++++++++++++++++ src/libproc_macro/lib.rs | 25 ++++++------------------- src/libproc_macro/rustc.rs | 23 +++++++++++++++++++++-- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/libproc_macro/bridge.rs b/src/libproc_macro/bridge.rs index 697a9d79c94e3..8e33f10dae0ca 100644 --- a/src/libproc_macro/bridge.rs +++ b/src/libproc_macro/bridge.rs @@ -21,6 +21,7 @@ use std::cell::Cell; use std::fmt; +use std::path::PathBuf; use std::ptr::NonNull; use self::storage::{FromConcrete, ToConcrete}; @@ -195,6 +196,8 @@ storage_concrete_passthrough! { [] ::Span, [] ::Delimiter, [] ::LexError, + + [] PathBuf, // NOTE(eddyb) this will need some `extern "C" fn write`. ['a, 'b] &'a mut fmt::Formatter<'b>, [] fmt::Error @@ -243,6 +246,17 @@ macro_rules! each_frontend_method { }); $meth!(fn token_cursor_next(&self, cursor: &mut Self::TokenCursor) -> Option;); + + $meth!(fn source_file_cleanup(&self, _file: Self::SourceFile) -> () {}); + $meth!(fn source_file_clone(&self, file: &Self::SourceFile) -> Self::SourceFile { + file.clone() + }); + $meth!(fn source_file_eq(&self, file1: &Self::SourceFile, + file2: &Self::SourceFile) -> bool;); + $meth!(fn source_file_path(&self, file: &Self::SourceFile) -> PathBuf;); + $meth!(fn source_file_is_real(&self, file: &Self::SourceFile) -> bool;); + + $meth!(fn span_source_file(&self, span: ::Span) -> Self::SourceFile;); } } @@ -253,6 +267,7 @@ pub trait FrontendInterface { type TokenStream: 'static + Clone + fmt::Debug + fmt::Display; type TokenStreamBuilder: 'static; type TokenCursor: 'static + Clone; + type SourceFile: 'static + Clone; each_frontend_method!(define_frontend_trait_method); } @@ -310,6 +325,9 @@ define_boxed! { }, TokenCursor { cleanup: token_cursor_cleanup + }, + SourceFile { + cleanup: source_file_cleanup } } @@ -337,6 +355,12 @@ impl Clone for TokenCursor { } } +impl Clone for SourceFile { + fn clone(&self) -> Self { + Frontend.source_file_clone(self) + } +} + pub(crate) struct Frontend; macro_rules! define_frontend_current_method { @@ -351,6 +375,7 @@ impl FrontendInterface for Frontend { type TokenStream = TokenStream; type TokenStreamBuilder = TokenStreamBuilder; type TokenCursor = TokenCursor; + type SourceFile = SourceFile; each_frontend_method!(define_frontend_current_method); } @@ -359,6 +384,7 @@ type CurrentFrontend<'a> = FrontendInterface< TokenStream = TokenStream, TokenStreamBuilder = TokenStreamBuilder, TokenCursor = TokenCursor, + SourceFile = SourceFile, > + 'a; // Emulate scoped_thread_local!() here essentially @@ -421,6 +447,7 @@ fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generatio type TokenStream = TokenStream; type TokenStreamBuilder = TokenStreamBuilder; type TokenCursor = TokenCursor; + type SourceFile = SourceFile; each_frontend_method!(define_frontend_erase_concrete_method); } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 57584167bbc72..71e23a917414f 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -65,13 +65,12 @@ pub use diagnostic::{Diagnostic, Level}; use std::{ascii, fmt, iter}; use std::path::PathBuf; -use rustc_data_structures::sync::Lrc; use std::str::FromStr; use syntax::parse::token; use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; -use syntax_pos::{FileMap, Pos, SyntaxContext, FileName}; +use syntax_pos::{Pos, SyntaxContext}; /// The main type provided by this crate, representing an abstract stream of /// tokens. @@ -224,9 +223,7 @@ impl Span { /// The original source file into which this span points. #[unstable(feature = "proc_macro", issue = "38356")] pub fn source_file(&self) -> SourceFile { - SourceFile { - filemap: __internal::lookup_char_pos(self.0.lo()).file, - } + SourceFile(Frontend.span_source_file(*self)) } /// The `Span` for the tokens in the previous macro expansion from which @@ -313,14 +310,7 @@ pub struct LineColumn { /// The source file of a given `Span`. #[unstable(feature = "proc_macro", issue = "38356")] #[derive(Clone)] -pub struct SourceFile { - filemap: Lrc, -} - -#[unstable(feature = "proc_macro", issue = "38356")] -impl !Send for SourceFile {} -#[unstable(feature = "proc_macro", issue = "38356")] -impl !Sync for SourceFile {} +pub struct SourceFile(bridge::SourceFile); impl SourceFile { /// Get the path to this source file. @@ -335,10 +325,7 @@ impl SourceFile { /// [`is_real`]: #method.is_real #[unstable(feature = "proc_macro", issue = "38356")] pub fn path(&self) -> PathBuf { - match self.filemap.name { - FileName::Real(ref path) => path.clone(), - _ => PathBuf::from(self.filemap.name.to_string()) - } + Frontend.source_file_path(&self.0) } /// Returns `true` if this source file is a real source file, and not generated by an external @@ -348,7 +335,7 @@ impl SourceFile { // This is a hack until intercrate spans are implemented and we can have real source files // for spans generated in external macros. // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368 - self.filemap.is_real_file() + Frontend.source_file_is_real(&self.0) } } @@ -366,7 +353,7 @@ impl fmt::Debug for SourceFile { #[unstable(feature = "proc_macro", issue = "38356")] impl PartialEq for SourceFile { fn eq(&self, other: &Self) -> bool { - Lrc::ptr_eq(&self.filemap, &other.filemap) + Frontend.source_file_eq(&self.0, &other.0) } } diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index 234b1ab14c185..8978f4013d247 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -10,7 +10,9 @@ use {__internal, Delimiter, Spacing, Span, Term, TokenNode, TokenTree}; -use syntax_pos::{self, SyntaxContext, FileName}; +use rustc_data_structures::sync::Lrc; +use std::path::PathBuf; +use syntax_pos::{self, SyntaxContext, FileMap, FileName}; use syntax_pos::hygiene::Mark; use syntax::ast; use syntax::ext::base::{ExtCtxt, ProcMacro}; @@ -58,7 +60,7 @@ impl ::bridge::FrontendInterface for Rustc { type TokenStream = tokenstream::TokenStream; type TokenStreamBuilder = tokenstream::TokenStreamBuilder; type TokenCursor = tokenstream::Cursor; - + type SourceFile = Lrc; fn token_stream_empty(&self) -> Self::TokenStream { tokenstream::TokenStream::empty() @@ -279,4 +281,21 @@ impl ::bridge::FrontendInterface for Rustc { } None } + + fn source_file_eq(&self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool { + Lrc::ptr_eq(file1, file2) + } + fn source_file_path(&self, file: &Self::SourceFile) -> PathBuf { + match file.name { + FileName::Real(ref path) => path.clone(), + _ => PathBuf::from(file.name.to_string()) + } + } + fn source_file_is_real(&self, file: &Self::SourceFile) -> bool { + file.is_real_file() + } + + fn span_source_file(&self, span: ::Span) -> Self::SourceFile { + ::__internal::lookup_char_pos(span.0.lo()).file + } } From 3939760dfb0873a28fd69b420305dd64ed2da60d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 19 Mar 2018 21:15:49 +0200 Subject: [PATCH 04/14] proc_macro: move Span and Diagnostic to the bridge. --- src/libproc_macro/bridge.rs | 133 +++++++++++++++++++++++++++--- src/libproc_macro/diagnostic.rs | 42 ++-------- src/libproc_macro/lib.rs | 76 +++++++---------- src/libproc_macro/rustc.rs | 113 +++++++++++++++++++++---- src/librustc_errors/diagnostic.rs | 2 +- 5 files changed, 256 insertions(+), 110 deletions(-) diff --git a/src/libproc_macro/bridge.rs b/src/libproc_macro/bridge.rs index 8e33f10dae0ca..b1154f0f947e7 100644 --- a/src/libproc_macro/bridge.rs +++ b/src/libproc_macro/bridge.rs @@ -31,14 +31,14 @@ mod generation { #[repr(C)] #[derive(Copy, Clone, PartialEq, Eq, Debug)] - pub(super) struct Generation(usize); + pub(super) struct Generation(u32); impl !Send for Generation {} impl !Sync for Generation {} impl Generation { pub(super) extern "C" fn next() -> Self { - thread_local!(static NEXT: Cell = Cell::new(0)); + thread_local!(static NEXT: Cell = Cell::new(0)); NEXT.with(|next| { let gen = next.get(); next.set(gen.checked_add(1).expect("Generation::next overflowed counter")); @@ -99,6 +99,12 @@ mod storage { } } + impl, T, U> ToConcrete, Option> for S { + fn to_concrete(&self, x: Option) -> Option { + x.map(|x| self.to_concrete(x)) + } + } + // FIXME(eddyb) achieve ABI compatibility for these types. impl FromConcrete, Result> for S where S: FromConcrete + FromConcrete @@ -184,6 +190,47 @@ mod storage { } } } + + pub(super) trait Pod: Copy {} + impl Pod for u32 {} + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Eq)] + pub(super) struct Inline { + repr: R, + gen: Generation, + _marker: PhantomData, + } + + impl !Send for Inline {} + impl !Sync for Inline {} + + impl, R: Pod> FromConcrete> for Storage + where T::Concrete: Copy + { + fn from_concrete(&self, x: T::Concrete) -> Inline { + assert_eq!(mem::size_of::(), mem::size_of::()); + Inline { + repr: unsafe { + mem::transmute_copy(&x) + }, + gen: self.gen, + _marker: PhantomData, + } + } + } + + impl, R: Pod> ToConcrete, T::Concrete> for Storage + where T::Concrete: Copy + { + fn to_concrete(&self, x: Inline) -> T::Concrete { + assert_eq!(mem::size_of::(), mem::size_of::()); + assert_eq!(x.gen, self.gen); + unsafe { + mem::transmute_copy(&x.repr) + } + } + } } storage_concrete_passthrough! { @@ -192,10 +239,11 @@ storage_concrete_passthrough! { ['a] &'a str, // FIXME(eddyb) achieve ABI compatibility for these types. - [] ::TokenTree, - [] ::Span, + [] ::TokenNode, [] ::Delimiter, [] ::LexError, + [] ::LineColumn, + [] ::Level, [] PathBuf, // NOTE(eddyb) this will need some `extern "C" fn write`. @@ -221,16 +269,16 @@ macro_rules! each_frontend_method { $meth!(fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool;); $meth!(fn token_stream_from_str(&self, src: &str) -> Result;); - $meth!(fn token_stream_delimited(&self, span: ::Span, + $meth!(fn token_stream_delimited(&self, span: Self::Span, delimiter: ::Delimiter, delimed: Self::TokenStream) -> Self::TokenStream;); - $meth!(fn token_stream_from_token_tree(&self, tree: ::TokenTree) + $meth!(fn token_stream_from_token_tree(&self, node: ::TokenNode, span: Self::Span) -> Self::TokenStream;); $meth!(fn token_stream_to_token_tree(&self, stream: Self::TokenStream) - -> Result<(::TokenTree, Option), - (::Span, (::Delimiter, - Self::TokenStream))>;); + -> (Self::Span, + Result<(::TokenNode, Option), + (::Delimiter, Self::TokenStream)>);); $meth!(fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor;); $meth!(fn token_stream_builder_cleanup(&self, _builder: Self::TokenStreamBuilder) -> () {}); @@ -256,7 +304,25 @@ macro_rules! each_frontend_method { $meth!(fn source_file_path(&self, file: &Self::SourceFile) -> PathBuf;); $meth!(fn source_file_is_real(&self, file: &Self::SourceFile) -> bool;); - $meth!(fn span_source_file(&self, span: ::Span) -> Self::SourceFile;); + $meth!(fn diagnostic_cleanup(&self, _diagnostic: Self::Diagnostic) -> () {}); + $meth!(fn diagnostic_new(&self, level: ::Level, msg: &str, span: Option) + -> Self::Diagnostic;); + $meth!(fn diagnostic_sub(&self, diagnostic: &mut Self::Diagnostic, + level: ::Level, msg: &str, span: Option) -> ();); + $meth!(fn diagnostic_emit(&self, diagnostic: Self::Diagnostic) -> ();); + + $meth!(fn span_debug(&self, span: Self::Span, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&span, f) + }); + $meth!(fn span_def_site(&self) -> Self::Span;); + $meth!(fn span_call_site(&self) -> Self::Span;); + $meth!(fn span_source_file(&self, span: Self::Span) -> Self::SourceFile;); + $meth!(fn span_parent(&self, span: Self::Span) -> Option;); + $meth!(fn span_source(&self, span: Self::Span) -> Self::Span;); + $meth!(fn span_start(&self, span: Self::Span) -> ::LineColumn;); + $meth!(fn span_end(&self, span: Self::Span) -> ::LineColumn;); + $meth!(fn span_join(&self, first: Self::Span, second: Self::Span) -> Option;); + $meth!(fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span;); } } @@ -268,6 +334,9 @@ pub trait FrontendInterface { type TokenStreamBuilder: 'static; type TokenCursor: 'static + Clone; type SourceFile: 'static + Clone; + type Diagnostic: 'static; + /// NB. has to be the same size as u32. + type Span: 'static + Copy + Eq + fmt::Debug; each_frontend_method!(define_frontend_trait_method); } @@ -328,6 +397,9 @@ define_boxed! { }, SourceFile { cleanup: source_file_cleanup + }, + Diagnostic { + cleanup: diagnostic_cleanup } } @@ -361,6 +433,41 @@ impl Clone for SourceFile { } } +macro_rules! define_inline { + ($($name:ident),*) => { + $( + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Eq)] + pub(crate) struct $name(storage::Inline<$name>); + impl storage::Concrete for $name { + type Concrete = F::$name; + } + impl FromConcrete for storage::Storage + where $name: storage::Concrete + { + fn from_concrete(&self, x: T) -> $name { + $name(self.from_concrete(x)) + } + } + impl ToConcrete<$name, T> for storage::Storage + where $name: storage::Concrete + { + fn to_concrete(&self, x: $name) -> T { + self.to_concrete(x.0) + } + } + )* + } +} + +define_inline!(Span); + +impl fmt::Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Frontend.span_debug(*self, f) + } +} + pub(crate) struct Frontend; macro_rules! define_frontend_current_method { @@ -376,6 +483,8 @@ impl FrontendInterface for Frontend { type TokenStreamBuilder = TokenStreamBuilder; type TokenCursor = TokenCursor; type SourceFile = SourceFile; + type Diagnostic = Diagnostic; + type Span = Span; each_frontend_method!(define_frontend_current_method); } @@ -385,6 +494,8 @@ type CurrentFrontend<'a> = FrontendInterface< TokenStreamBuilder = TokenStreamBuilder, TokenCursor = TokenCursor, SourceFile = SourceFile, + Diagnostic = Diagnostic, + Span = Span, > + 'a; // Emulate scoped_thread_local!() here essentially @@ -448,6 +559,8 @@ fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generatio type TokenStreamBuilder = TokenStreamBuilder; type TokenCursor = TokenCursor; type SourceFile = SourceFile; + type Diagnostic = Diagnostic; + type Span = Span; each_frontend_method!(define_frontend_erase_concrete_method); } diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs index c39aec896e6b4..07628c951d74d 100644 --- a/src/libproc_macro/diagnostic.rs +++ b/src/libproc_macro/diagnostic.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use Span; - -use rustc_errors as rustc; +use {Frontend, FrontendInterface, Span}; /// An enum representing a diagnostic level. #[unstable(feature = "proc_macro", issue = "38356")] @@ -97,38 +95,12 @@ impl Diagnostic { /// Emit the diagnostic. #[unstable(feature = "proc_macro", issue = "38356")] pub fn emit(self) { - ::__internal::with_sess(move |(sess, _)| { - let handler = &sess.span_diagnostic; - let level = __internal::level_to_internal_level(self.level); - let mut diag = rustc::DiagnosticBuilder::new(handler, level, &*self.message); - - if let Some(span) = self.span { - diag.set_span(span.0); - } - - for child in self.children { - let span = child.span.map(|s| s.0); - let level = __internal::level_to_internal_level(child.level); - diag.sub(level, &*child.message, span); - } - - diag.emit(); - }); - } -} - -#[unstable(feature = "proc_macro_internals", issue = "27812")] -#[doc(hidden)] -pub mod __internal { - use super::{Level, rustc}; - - pub fn level_to_internal_level(level: Level) -> rustc::Level { - match level { - Level::Error => rustc::Level::Error, - Level::Warning => rustc::Level::Warning, - Level::Note => rustc::Level::Note, - Level::Help => rustc::Level::Help, - Level::__Nonexhaustive => unreachable!("Level::__Nonexhaustive") + let span = self.span.map(|s| s.0); + let mut diag = Frontend.diagnostic_new(self.level, &self.message[..], span); + for child in self.children { + let span = child.span.map(|s| s.0); + Frontend.diagnostic_sub(&mut diag, child.level, &child.message[..], span); } + Frontend.diagnostic_emit(diag); } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 71e23a917414f..4e0fb6d98f85a 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -69,8 +69,6 @@ use std::str::FromStr; use syntax::parse::token; use syntax::symbol::Symbol; -use syntax_pos::DUMMY_SP; -use syntax_pos::{Pos, SyntaxContext}; /// The main type provided by this crate, representing an abstract stream of /// tokens. @@ -127,9 +125,9 @@ impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { TokenStream(match tree.kind { TokenNode::Group(delimiter, tokens) => { - Frontend.token_stream_delimited(tree.span, delimiter, tokens.0) + Frontend.token_stream_delimited(tree.span.0, delimiter, tokens.0) } - _ => Frontend.token_stream_from_token_tree(tree) + _ => Frontend.token_stream_from_token_tree(tree.kind, tree.span.0) }) } } @@ -182,18 +180,7 @@ impl TokenStream { /// A region of source code, along with macro expansion information. #[unstable(feature = "proc_macro", issue = "38356")] #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub struct Span(syntax_pos::Span); - -impl Span { - /// A span that resolves at the macro definition site. - #[unstable(feature = "proc_macro", issue = "38356")] - pub fn def_site() -> Span { - ::__internal::with_sess(|(_, mark)| { - let call_site = mark.expn_info().unwrap().call_site; - Span(call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark))) - }) - } -} +pub struct Span(bridge::Span); /// Quote a `Span` into a `TokenStream`. /// This is needed to implement a custom quoter. @@ -214,23 +201,29 @@ macro_rules! diagnostic_method { } impl Span { + /// A span that resolves at the macro definition site. + #[unstable(feature = "proc_macro", issue = "38356")] + pub fn def_site() -> Span { + Span(Frontend.span_def_site()) + } + /// The span of the invocation of the current procedural macro. #[unstable(feature = "proc_macro", issue = "38356")] pub fn call_site() -> Span { - ::__internal::with_sess(|(_, mark)| Span(mark.expn_info().unwrap().call_site)) + Span(Frontend.span_call_site()) } /// The original source file into which this span points. #[unstable(feature = "proc_macro", issue = "38356")] pub fn source_file(&self) -> SourceFile { - SourceFile(Frontend.span_source_file(*self)) + SourceFile(Frontend.span_source_file(self.0)) } /// The `Span` for the tokens in the previous macro expansion from which /// `self` was generated from, if any. #[unstable(feature = "proc_macro", issue = "38356")] pub fn parent(&self) -> Option { - self.0.ctxt().outer().expn_info().map(|i| Span(i.call_site)) + Frontend.span_parent(self.0).map(Span) } /// The span for the origin source code that `self` was generated from. If @@ -238,27 +231,19 @@ impl Span { /// value is the same as `*self`. #[unstable(feature = "proc_macro", issue = "38356")] pub fn source(&self) -> Span { - Span(self.0.source_callsite()) + Span(Frontend.span_source(self.0)) } /// Get the starting line/column in the source file for this span. #[unstable(feature = "proc_macro", issue = "38356")] pub fn start(&self) -> LineColumn { - let loc = __internal::lookup_char_pos(self.0.lo()); - LineColumn { - line: loc.line, - column: loc.col.to_usize() - } + Frontend.span_start(self.0) } /// Get the ending line/column in the source file for this span. #[unstable(feature = "proc_macro", issue = "38356")] pub fn end(&self) -> LineColumn { - let loc = __internal::lookup_char_pos(self.0.hi()); - LineColumn { - line: loc.line, - column: loc.col.to_usize() - } + Frontend.span_end(self.0) } /// Create a new span encompassing `self` and `other`. @@ -266,19 +251,14 @@ impl Span { /// Returns `None` if `self` and `other` are from different files. #[unstable(feature = "proc_macro", issue = "38356")] pub fn join(&self, other: Span) -> Option { - let self_loc = __internal::lookup_char_pos(self.0.lo()); - let other_loc = __internal::lookup_char_pos(other.0.lo()); - - if self_loc.file.name != other_loc.file.name { return None } - - Some(Span(self.0.to(other.0))) + Frontend.span_join(self.0, other.0).map(Span) } /// Creates a new span with the same line/column information as `self` but /// that resolves symbols as though it were at `other`. #[unstable(feature = "proc_macro", issue = "38356")] pub fn resolved_at(&self, other: Span) -> Span { - Span(self.0.with_ctxt(other.0.ctxt())) + Span(Frontend.span_resolved_at(self.0, other.0)) } /// Creates a new span with the same name resolution behavior as `self` but @@ -449,7 +429,7 @@ pub struct Literal(token::Token); #[unstable(feature = "proc_macro", issue = "38356")] impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - TokenTree { kind: TokenNode::Literal(self.clone()), span: Span(DUMMY_SP) }.fmt(f) + TokenTree { kind: TokenNode::Literal(self.clone()), span: Span::def_site() }.fmt(f) } } @@ -548,17 +528,19 @@ impl Iterator for TokenTreeIter { let next = unwrap_or!(self.next.take().or_else(|| { Frontend.token_cursor_next(&mut self.cursor) }), return None); - let (tree, next) = match Frontend.token_stream_to_token_tree(next) { - Ok((tree, next)) => (tree, next), - Err((span, (delimiter, delimed))) => { - (TokenTree { - span, - kind: TokenNode::Group(delimiter, TokenStream(delimed)), - }, None) + let (span, kind) = match Frontend.token_stream_to_token_tree(next) { + (span, Ok((kind, next))) => { + self.next = next; + (span, kind) + } + (span, Err((delimiter, delimed))) => { + (span, TokenNode::Group(delimiter, TokenStream(delimed))) } }; - self.next = next; - Some(tree) + Some(TokenTree { + span: Span(span), + kind + }) } } diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index 8978f4013d247..10e2011ef32eb 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {__internal, Delimiter, Spacing, Span, Term, TokenNode, TokenTree}; +use {__internal, Delimiter, Spacing, Term, TokenNode}; use rustc_data_structures::sync::Lrc; +use rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; use std::path::PathBuf; -use syntax_pos::{self, SyntaxContext, FileMap, FileName}; +use syntax_pos::{self, SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP}; use syntax_pos::hygiene::Mark; use syntax::ast; use syntax::ext::base::{ExtCtxt, ProcMacro}; @@ -35,6 +36,18 @@ impl ProcMacro for Quoter { } } +impl ::Level { + fn to_internal(self) -> Level { + match self { + ::Level::Error => Level::Error, + ::Level::Warning => Level::Warning, + ::Level::Note => Level::Note, + ::Level::Help => Level::Help, + ::Level::__Nonexhaustive => unreachable!("Level::__Nonexhaustive") + } + } +} + impl Delimiter { fn from_internal(delim: token::DelimToken) -> Delimiter { match delim { @@ -61,6 +74,8 @@ impl ::bridge::FrontendInterface for Rustc { type TokenStreamBuilder = tokenstream::TokenStreamBuilder; type TokenCursor = tokenstream::Cursor; type SourceFile = Lrc; + type Diagnostic = Diagnostic; + type Span = syntax_pos::Span; fn token_stream_empty(&self) -> Self::TokenStream { tokenstream::TokenStream::empty() @@ -81,32 +96,33 @@ impl ::bridge::FrontendInterface for Rustc { Ok(parse::parse_stream_from_source_str(name, src, sess, Some(span))) }) } - fn token_stream_delimited(&self, span: ::Span, + fn token_stream_delimited(&self, span: Self::Span, delimiter: ::Delimiter, delimed: Self::TokenStream) -> Self::TokenStream { - tokenstream::TokenTree::Delimited(span.0, tokenstream::Delimited { + tokenstream::TokenTree::Delimited(span, tokenstream::Delimited { delim: delimiter.to_internal(), tts: delimed.into(), }).into() } - fn token_stream_from_token_tree(&self, tree: TokenTree) -> Self::TokenStream { + fn token_stream_from_token_tree(&self, node: ::TokenNode, span: Self::Span) + -> Self::TokenStream { use syntax::parse::token::*; use syntax::tokenstream::TokenTree; - let (op, kind) = match tree.kind { + let (op, kind) = match node { TokenNode::Op(op, kind) => (op, kind), TokenNode::Group(..) => unreachable!(), TokenNode::Term(symbol) => { - let ident = ast::Ident { name: symbol.0, ctxt: tree.span.0.ctxt() }; + let ident = ast::Ident { name: symbol.0, ctxt: span.ctxt() }; let token = if symbol.0.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) }; - return TokenTree::Token(tree.span.0, token).into(); + return TokenTree::Token(span, token).into(); } - TokenNode::Literal(token) => return TokenTree::Token(tree.span.0, token.0).into(), + TokenNode::Literal(token) => return TokenTree::Token(span, token.0).into(), }; let token = match op { @@ -134,15 +150,16 @@ impl ::bridge::FrontendInterface for Rustc { _ => panic!("unsupported character {}", op), }; - let tree = TokenTree::Token(tree.span.0, token); + let tree = TokenTree::Token(span, token); match kind { Spacing::Alone => tree.into(), Spacing::Joint => tree.joint(), } } fn token_stream_to_token_tree(&self, stream: Self::TokenStream) - -> Result<(::TokenTree, Option), - (::Span, (::Delimiter, Self::TokenStream))> { + -> (Self::Span, + Result<(::TokenNode, Option), + (::Delimiter, Self::TokenStream)>) { use syntax::parse::token::*; let mut next = None; @@ -151,7 +168,7 @@ impl ::bridge::FrontendInterface for Rustc { let (mut span, token) = match tree { tokenstream::TokenTree::Delimited(span, delimed) => { let delimiter = Delimiter::from_internal(delimed.delim); - return Err((Span(span), (delimiter, delimed.tts.into()))); + return (span, Err((delimiter, delimed.tts.into()))); } tokenstream::TokenTree::Token(span, token) => (span, token), }; @@ -229,7 +246,7 @@ impl ::bridge::FrontendInterface for Rustc { Literal(..) | DocComment(..) => TokenNode::Literal(::Literal(token)), Interpolated(_) => { - return Err((Span(span), __internal::with_sess(|(sess, _)| { + return (span, Err(__internal::with_sess(|(sess, _)| { let tts = token.interpolated_to_tokenstream(sess, span); (Delimiter::None, tts) }))); @@ -240,7 +257,7 @@ impl ::bridge::FrontendInterface for Rustc { Whitespace | Comment | Shebang(..) | Eof => unreachable!(), }; - Ok((TokenTree { span: Span(span), kind: kind }, next)) + (span, Ok((kind, next))) } fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor { stream.trees() @@ -295,7 +312,69 @@ impl ::bridge::FrontendInterface for Rustc { file.is_real_file() } - fn span_source_file(&self, span: ::Span) -> Self::SourceFile { - ::__internal::lookup_char_pos(span.0.lo()).file + fn diagnostic_new(&self, level: ::Level, msg: &str, span: Option) + -> Self::Diagnostic { + let mut diagnostic = Diagnostic::new(level.to_internal(), msg); + + if let Some(span) = span { + diagnostic.set_span(span); + } + + diagnostic + + } + fn diagnostic_sub(&self, diagnostic: &mut Self::Diagnostic, + level: ::Level, msg: &str, span: Option) { + let span = span.map(|s| s.into()).unwrap_or(MultiSpan::new()); + diagnostic.sub(level.to_internal(), msg, span, None); + } + fn diagnostic_emit(&self, diagnostic: Self::Diagnostic) { + ::__internal::with_sess(move |(sess, _)| { + DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, diagnostic).emit() + }); + } + + fn span_def_site(&self) -> Self::Span { + ::__internal::with_sess(|(_, mark)| { + let call_site = mark.expn_info().unwrap().call_site; + call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)) + }) + } + fn span_call_site(&self) -> Self::Span { + ::__internal::with_sess(|(_, mark)| mark.expn_info().unwrap().call_site) + } + fn span_source_file(&self, span: Self::Span) -> Self::SourceFile { + ::__internal::lookup_char_pos(span.lo()).file + } + fn span_parent(&self, span: Self::Span) -> Option { + span.ctxt().outer().expn_info().map(|i| i.call_site) + } + fn span_source(&self, span: Self::Span) -> Self::Span { + span.source_callsite() + } + fn span_start(&self, span: Self::Span) -> ::LineColumn { + let loc = ::__internal::lookup_char_pos(span.lo()); + ::LineColumn { + line: loc.line, + column: loc.col.to_usize() + } + } + fn span_end(&self, span: Self::Span) -> ::LineColumn { + let loc = ::__internal::lookup_char_pos(span.hi()); + ::LineColumn { + line: loc.line, + column: loc.col.to_usize() + } + } + fn span_join(&self, first: Self::Span, second: Self::Span) -> Option { + let self_loc = ::__internal::lookup_char_pos(first.lo()); + let other_loc = ::__internal::lookup_char_pos(second.lo()); + + if self_loc.file.name != other_loc.file.name { return None } + + Some(first.to(second)) + } + fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span { + span.with_ctxt(at.ctxt()) } } diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 40e4efb397d30..122322b54e7da 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -340,7 +340,7 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. - pub(crate) fn sub(&mut self, + pub fn sub(&mut self, level: Level, message: &str, span: MultiSpan, From 341edae786a50772fe7153512bb2ecd841b08672 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 19 Mar 2018 22:44:24 +0200 Subject: [PATCH 05/14] proc_macro: remove the __internal module. --- src/libproc_macro/lib.rs | 146 +++++++++++----------- src/libproc_macro/quote.rs | 55 ++------ src/libproc_macro/rustc.rs | 78 ++++++------ src/librustc/util/common.rs | 2 +- src/libsyntax_ext/deriving/custom.rs | 9 +- src/libsyntax_ext/proc_macro_impl.rs | 8 +- src/libsyntax_ext/proc_macro_registrar.rs | 18 +-- 7 files changed, 136 insertions(+), 180 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 4e0fb6d98f85a..66ef99e7e183a 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -120,6 +120,13 @@ macro_rules! quote { () => {} } #[doc(hidden)] mod quote; +/// Quote a `TokenStream` into a `TokenStream`. +/// This is needed to implement a custom quoter. +#[unstable(feature = "proc_macro", issue = "38356")] +pub fn quote_token_stream(stream: TokenStream) -> TokenStream { + quote::Quote::quote(stream) +} + #[unstable(feature = "proc_macro", issue = "38356")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { @@ -512,6 +519,70 @@ impl Literal { } } +macro_rules! literals { + ($($i:ident),*; $($raw:ident),*) => { + #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[doc(hidden)] + pub enum LiteralKind { + $($i,)* + $($raw(usize),)* + } + + impl LiteralKind { + #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[doc(hidden)] + pub fn with_contents_and_suffix(self, contents: Term, suffix: Option) + -> Literal { + let contents = contents.0; + let suffix = suffix.map(|t| t.0); + match self { + $(LiteralKind::$i => { + Literal(token::Literal(token::Lit::$i(contents), suffix)) + })* + $(LiteralKind::$raw(n) => { + Literal(token::Literal(token::Lit::$raw(contents, n), suffix)) + })* + } + } + } + + impl Literal { + fn kind(&self) -> LiteralKind { + let lit = match self.0 { + token::Literal(lit, _) => lit, + _ => panic!("unsupported literal {:?}", self.0), + }; + + match lit { + $(token::Lit::$i(_) => LiteralKind::$i,)* + $(token::Lit::$raw(_, n) => LiteralKind::$raw(n),)* + } + } + + fn contents(&self) -> Term { + let lit = match self.0 { + token::Literal(lit, _) => lit, + _ => panic!("unsupported literal {:?}", self.0), + }; + + match lit { + $(token::Lit::$i(contents))|* | + $(token::Lit::$raw(contents, _))|* => Term(contents) + } + } + + fn suffix(&self) -> Option { + match self.0 { + token::Literal(_, suffix) => suffix.map(Term), + _ => panic!("unsupported literal {:?}", self.0), + } + } + } + } +} + +literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); + /// An iterator over `TokenTree`s. #[derive(Clone)] #[unstable(feature = "proc_macro", issue = "38356")] @@ -543,78 +614,3 @@ impl Iterator for TokenTreeIter { }) } } - -/// Permanently unstable internal implementation details of this crate. This -/// should not be used. -/// -/// These methods are used by the rest of the compiler to generate instances of -/// `TokenStream` to hand to macro definitions, as well as consume the output. -/// -/// Note that this module is also intentionally separate from the rest of the -/// crate. This allows the `#[unstable]` directive below to naturally apply to -/// all of the contents. -#[unstable(feature = "proc_macro_internals", issue = "27812")] -#[doc(hidden)] -pub mod __internal { - pub use bridge::{Expand1, Expand2, Registry}; - pub use quote::{LiteralKind, unquote}; - - use std::cell::Cell; - - use syntax::errors::DiagnosticBuilder; - use syntax::ext::base::ExtCtxt; - use syntax::ext::hygiene::Mark; - use syntax::parse::ParseSess; - use syntax_pos::{BytePos, Loc}; - - use super::LexError; - - pub fn lookup_char_pos(pos: BytePos) -> Loc { - with_sess(|(sess, _)| sess.codemap().lookup_char_pos(pos)) - } - - pub fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError { - err.cancel(); - LexError { _inner: () } - } - - // Emulate scoped_thread_local!() here essentially - thread_local! { - static CURRENT_SESS: Cell<(*const ParseSess, Mark)> = - Cell::new((0 as *const _, Mark::root())); - } - - pub fn set_sess(cx: &ExtCtxt, f: F) -> R - where F: FnOnce() -> R - { - struct Reset { prev: (*const ParseSess, Mark) } - - impl Drop for Reset { - fn drop(&mut self) { - CURRENT_SESS.with(|p| p.set(self.prev)); - } - } - - CURRENT_SESS.with(|p| { - let _reset = Reset { prev: p.get() }; - p.set((cx.parse_sess, cx.current_expansion.mark)); - - f() - }) - } - - pub fn in_sess() -> bool - { - let p = CURRENT_SESS.with(|p| p.get()); - !p.0.is_null() - } - - pub fn with_sess(f: F) -> R - where F: FnOnce((&ParseSess, Mark)) -> R - { - let p = CURRENT_SESS.with(|p| p.get()); - assert!(!p.0.is_null(), "proc_macro::__internal::with_sess() called \ - before set_parse_sess()!"); - f(unsafe { (&*p.0, p.1) }) - } -} diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index 2608fe9d3f068..c21adc1ea90be 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -14,13 +14,7 @@ //! This quasiquoter uses macros 2.0 hygiene to reliably access //! items from `proc_macro`, to build a `proc_macro::TokenStream`. -use {Delimiter, Literal, Spacing, Span, Term, TokenNode, TokenStream, TokenTree}; - -use syntax::parse::token; - -pub fn unquote + Clone>(tokens: &T) -> TokenStream { - T::into(tokens.clone()) -} +use {Delimiter, Literal, LiteralKind, Spacing, Span, Term, TokenNode, TokenStream, TokenTree}; pub trait Quote { fn quote(self) -> TokenStream; @@ -83,7 +77,8 @@ impl Quote for TokenStream { after_dollar = false; match tree.kind { TokenNode::Term(_) => { - return Some(quote!(::__internal::unquote(&(unquote tree)),)); + return Some(quote!(Into::<::TokenStream>::into( + Clone::clone(&(unquote tree))),)); } TokenNode::Op('$', _) => {} _ => panic!("`$` must be followed by an ident or `$` in `quote!`"), @@ -158,50 +153,14 @@ impl Quote for Span { macro_rules! literals { ($($i:ident),*; $($raw:ident),*) => { - pub enum LiteralKind { - $($i,)* - $($raw(usize),)* - } - - impl LiteralKind { - pub fn with_contents_and_suffix(self, contents: Term, suffix: Option) - -> Literal { - let contents = contents.0; - let suffix = suffix.map(|t| t.0); - match self { - $(LiteralKind::$i => { - Literal(token::Literal(token::Lit::$i(contents), suffix)) - })* - $(LiteralKind::$raw(n) => { - Literal(token::Literal(token::Lit::$raw(contents, n), suffix)) - })* - } - } - } - - impl Literal { - fn kind_contents_and_suffix(self) -> (LiteralKind, Term, Option) { - let (lit, suffix) = match self.0 { - token::Literal(lit, suffix) => (lit, suffix), - _ => panic!("unsupported literal {:?}", self.0), - }; - - let (kind, contents) = match lit { - $(token::Lit::$i(contents) => (LiteralKind::$i, contents),)* - $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* - }; - (kind, Term(contents), suffix.map(Term)) - } - } - impl Quote for LiteralKind { fn quote(self) -> TokenStream { match self { $(LiteralKind::$i => quote! { - ::__internal::LiteralKind::$i + ::LiteralKind::$i },)* $(LiteralKind::$raw(n) => quote! { - ::__internal::LiteralKind::$raw((quote n)) + ::LiteralKind::$raw((quote n)) },)* } } @@ -209,7 +168,9 @@ macro_rules! literals { impl Quote for Literal { fn quote(self) -> TokenStream { - let (kind, contents, suffix) = self.kind_contents_and_suffix(); + let kind = self.kind(); + let contents = self.contents(); + let suffix = self.suffix(); quote! { (quote kind).with_contents_and_suffix((quote contents), (quote suffix)) } diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index 10e2011ef32eb..e1cee543daf18 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {__internal, Delimiter, Spacing, Term, TokenNode}; +use {Delimiter, Spacing, Term, TokenNode}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; @@ -17,7 +17,7 @@ use syntax_pos::{self, SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_S use syntax_pos::hygiene::Mark; use syntax::ast; use syntax::ext::base::{ExtCtxt, ProcMacro}; -use syntax::parse::{self, token}; +use syntax::parse::{self, token, ParseSess}; use syntax::tokenstream; pub struct Quoter; @@ -27,12 +27,13 @@ impl ProcMacro for Quoter { _: syntax_pos::Span, stream: tokenstream::TokenStream) -> tokenstream::TokenStream { - let expand_quoter = ::bridge::Expand1::new(&::quote::Quote::quote); + let expand_quoter = ::bridge::Expand1::new(&::quote_token_stream); let mut info = cx.current_expansion.mark.expn_info().unwrap(); info.callee.allow_internal_unstable = true; cx.current_expansion.mark.set_expn_info(info); - __internal::set_sess(cx, || expand_quoter.run(Rustc, stream)) + + expand_quoter.run(Rustc::new(cx), stream) } } @@ -68,8 +69,21 @@ impl Delimiter { } } -pub struct Rustc; -impl ::bridge::FrontendInterface for Rustc { +pub struct Rustc<'a> { + sess: &'a ParseSess, + mark: Mark, +} + +impl<'a> Rustc<'a> { + pub fn new(cx: &'a ExtCtxt) -> Self { + Rustc { + sess: cx.parse_sess, + mark: cx.current_expansion.mark + } + } +} + +impl<'a> ::bridge::FrontendInterface for Rustc<'a> { type TokenStream = tokenstream::TokenStream; type TokenStreamBuilder = tokenstream::TokenStreamBuilder; type TokenCursor = tokenstream::Cursor; @@ -84,17 +98,15 @@ impl ::bridge::FrontendInterface for Rustc { stream.is_empty() } fn token_stream_from_str(&self, src: &str) -> Result { - ::__internal::with_sess(|(sess, mark)| { - let src = src.to_string(); - let name = FileName::ProcMacroSourceCode; - let expn_info = mark.expn_info().unwrap(); - let call_site = expn_info.call_site; - // notify the expansion info that it is unhygienic - let mark = Mark::fresh(mark); - mark.set_expn_info(expn_info); - let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - Ok(parse::parse_stream_from_source_str(name, src, sess, Some(span))) - }) + let src = src.to_string(); + let name = FileName::ProcMacroSourceCode; + let expn_info = self.mark.expn_info().unwrap(); + let call_site = expn_info.call_site; + // notify the expansion info that it is unhygienic + let mark = Mark::fresh(self.mark); + mark.set_expn_info(expn_info); + let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); + Ok(parse::parse_stream_from_source_str(name, src, self.sess, Some(span))) } fn token_stream_delimited(&self, span: Self::Span, delimiter: ::Delimiter, @@ -246,10 +258,8 @@ impl ::bridge::FrontendInterface for Rustc { Literal(..) | DocComment(..) => TokenNode::Literal(::Literal(token)), Interpolated(_) => { - return (span, Err(__internal::with_sess(|(sess, _)| { - let tts = token.interpolated_to_tokenstream(sess, span); - (Delimiter::None, tts) - }))); + let tts = token.interpolated_to_tokenstream(self.sess, span); + return (span, Err((Delimiter::None, tts))); } DotEq => joint!('.', Eq), @@ -288,9 +298,7 @@ impl ::bridge::FrontendInterface for Rustc { tts }) => tts.into(), tokenstream::TokenTree::Token(_, token @ token::Interpolated(_)) => { - __internal::with_sess(|(sess, _)| { - token.interpolated_to_tokenstream(sess, span) - }) + token.interpolated_to_tokenstream(self.sess, span) } _ => return Some(stream) }; @@ -329,22 +337,18 @@ impl ::bridge::FrontendInterface for Rustc { diagnostic.sub(level.to_internal(), msg, span, None); } fn diagnostic_emit(&self, diagnostic: Self::Diagnostic) { - ::__internal::with_sess(move |(sess, _)| { - DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, diagnostic).emit() - }); + DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diagnostic).emit() } fn span_def_site(&self) -> Self::Span { - ::__internal::with_sess(|(_, mark)| { - let call_site = mark.expn_info().unwrap().call_site; - call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)) - }) + self.span_call_site() + .with_ctxt(SyntaxContext::empty().apply_mark(self.mark)) } fn span_call_site(&self) -> Self::Span { - ::__internal::with_sess(|(_, mark)| mark.expn_info().unwrap().call_site) + self.mark.expn_info().unwrap().call_site } fn span_source_file(&self, span: Self::Span) -> Self::SourceFile { - ::__internal::lookup_char_pos(span.lo()).file + self.sess.codemap().lookup_char_pos(span.lo()).file } fn span_parent(&self, span: Self::Span) -> Option { span.ctxt().outer().expn_info().map(|i| i.call_site) @@ -353,22 +357,22 @@ impl ::bridge::FrontendInterface for Rustc { span.source_callsite() } fn span_start(&self, span: Self::Span) -> ::LineColumn { - let loc = ::__internal::lookup_char_pos(span.lo()); + let loc = self.sess.codemap().lookup_char_pos(span.lo()); ::LineColumn { line: loc.line, column: loc.col.to_usize() } } fn span_end(&self, span: Self::Span) -> ::LineColumn { - let loc = ::__internal::lookup_char_pos(span.hi()); + let loc = self.sess.codemap().lookup_char_pos(span.hi()); ::LineColumn { line: loc.line, column: loc.col.to_usize() } } fn span_join(&self, first: Self::Span, second: Self::Span) -> Option { - let self_loc = ::__internal::lookup_char_pos(first.lo()); - let other_loc = ::__internal::lookup_char_pos(second.lo()); + let self_loc = self.sess.codemap().lookup_char_pos(first.lo()); + let other_loc = self.sess.codemap().lookup_char_pos(second.lo()); if self_loc.file.name != other_loc.file.name { return None } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 96b77d351e24c..f8aeaebe6c92a 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -47,7 +47,7 @@ lazy_static! { } fn panic_hook(info: &panic::PanicInfo) { - if !proc_macro::__internal::in_sess() { + if !proc_macro::bridge::has_current_frontend() { (*DEFAULT_HOOK)(info) } } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index c34029e7bb90a..9cc589c54cd09 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -80,9 +80,7 @@ impl MultiItemModifier for ProcMacroDerive { let token = Token::interpolated(token::NtItem(item)); let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - ::proc_macro::__internal::set_sess(ecx, || { - self.inner.run(::proc_macro::rustc::Rustc, input) - }) + self.inner.run(::proc_macro::rustc::Rustc::new(ecx), input) })); let stream = match res { @@ -109,13 +107,14 @@ impl MultiItemModifier for ProcMacroDerive { let mut items = vec![]; loop { - match parser.parse_item().map_err(::proc_macro::__internal::parse_to_lex_err) { + match parser.parse_item() { Ok(None) => break, Ok(Some(item)) => { items.push(Annotatable::Item(item)) } - Err(_) => { + Err(mut err) => { // FIXME: handle this better + err.cancel(); ecx.struct_span_fatal(span, msg).emit(); FatalError.raise(); } diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 26357d390e1f5..9e38d7ffaea57 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -29,9 +29,7 @@ impl base::AttrProcMacro for AttrProcMacro { annotated: TokenStream) -> TokenStream { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - ::proc_macro::__internal::set_sess(ecx, || { - self.inner.run(::proc_macro::rustc::Rustc, annotation, annotated) - }) + self.inner.run(::proc_macro::rustc::Rustc::new(ecx), annotation, annotated) })); match res { @@ -64,9 +62,7 @@ impl base::ProcMacro for BangProcMacro { input: TokenStream) -> TokenStream { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - ::proc_macro::__internal::set_sess(ecx, || { - self.inner.run(::proc_macro::rustc::Rustc, input) - }) + self.inner.run(::proc_macro::rustc::Rustc::new(ecx), input) })); match res { diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index 802fcffc07cfb..2a625479df493 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -348,7 +348,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // mod $gensym { // extern crate proc_macro; // -// use proc_macro::__internal::{Expand1, Expand2, Registry}; +// use proc_macro::bridge::{Expand1, Expand2, Registry}; // // #[plugin_registrar] // fn registrar(registrar: &mut Registry) { @@ -382,7 +382,7 @@ fn mk_registrar(cx: &mut ExtCtxt, Vec::new(), ast::ItemKind::ExternCrate(None)); - let __internal = Ident::from_str("__internal"); + let bridge = Ident::from_str("bridge"); let expand1 = Ident::from_str("Expand1"); let expand2 = Ident::from_str("Expand2"); let new = Ident::from_str("new"); @@ -397,7 +397,7 @@ fn mk_registrar(cx: &mut ExtCtxt, let expand = cx.expr_addr_of(span, expand); let expand_span = cd.span.with_ctxt(ctxt); let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ - proc_macro, __internal, expand1, new + proc_macro, bridge, expand1, new ])), vec![expand]); let trait_name = cx.expr_str(cd.span, cd.trait_name); let attrs = cx.expr_vec_slice( @@ -405,7 +405,7 @@ fn mk_registrar(cx: &mut ExtCtxt, cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::>() ); let registrar = cx.expr_ident(span, registrar); - let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, + let ufcs_path = cx.path(span, vec![proc_macro, bridge, registry, register_custom_derive]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), @@ -419,12 +419,12 @@ fn mk_registrar(cx: &mut ExtCtxt, let expand = cx.expr_addr_of(span, expand); let expand_span = ca.span.with_ctxt(ctxt); let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ - proc_macro, __internal, expand2, new + proc_macro, bridge, expand2, new ])), vec![expand]); let registrar = cx.expr_ident(ca.span, registrar); let ufcs_path = cx.path(span, - vec![proc_macro, __internal, registry, register_attr_proc_macro]); + vec![proc_macro, bridge, registry, register_attr_proc_macro]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), vec![registrar, name, expand])) @@ -436,18 +436,18 @@ fn mk_registrar(cx: &mut ExtCtxt, let expand = cx.expr_addr_of(span, expand); let expand_span = cm.span.with_ctxt(ctxt); let expand = cx.expr_call(expand_span, cx.expr_path(cx.path(expand_span, vec![ - proc_macro, __internal, expand1, new + proc_macro, bridge, expand1, new ])), vec![expand]); let registrar = cx.expr_ident(cm.span, registrar); let ufcs_path = cx.path(span, - vec![proc_macro, __internal, registry, register_bang_proc_macro]); + vec![proc_macro, bridge, registry, register_bang_proc_macro]); cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), vec![registrar, name, expand])) })); - let path = cx.path(span, vec![proc_macro, __internal, registry]); + let path = cx.path(span, vec![proc_macro, bridge, registry]); let registrar_path = cx.ty_path(path); let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable); let func = cx.item_fn(span, From 37a6f41d619434eae51459884c3f2e92da52534a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 01:12:48 +0200 Subject: [PATCH 06/14] proc_macro: don't use an opaque libsyntax Token in Literal. --- src/libproc_macro/lib.rs | 160 +++++++++++++++++++------------------ src/libproc_macro/quote.rs | 38 ++++----- src/libproc_macro/rustc.rs | 60 +++++++++++++- 3 files changed, 157 insertions(+), 101 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 66ef99e7e183a..970bbc98f3115 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -67,7 +67,6 @@ use std::{ascii, fmt, iter}; use std::path::PathBuf; use std::str::FromStr; -use syntax::parse::token; use syntax::symbol::Symbol; /// The main type provided by this crate, representing an abstract stream of @@ -429,14 +428,39 @@ pub enum Spacing { } /// A literal character (`'a'`), string (`"hello"`), or number (`2.3`). -#[derive(Clone, Debug)] +#[derive(Clone)] +#[unstable(feature = "proc_macro", issue = "38356")] +pub struct Literal { + #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[doc(hidden)] + pub kind: LiteralKind, + + #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[doc(hidden)] + pub contents: Term, + + #[unstable(feature = "proc_macro_internals", issue = "27812")] + #[doc(hidden)] + pub suffix: Option, +} + #[unstable(feature = "proc_macro", issue = "38356")] -pub struct Literal(token::Token); +impl fmt::Debug for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&TokenTree { + kind: TokenNode::Literal(self.clone()), + span: Span::def_site() + }, f) + } +} #[unstable(feature = "proc_macro", issue = "38356")] impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - TokenTree { kind: TokenNode::Literal(self.clone()), span: Span::def_site() }.fmt(f) + fmt::Display::fmt(&TokenTree { + kind: TokenNode::Literal(self.clone()), + span: Span::def_site() + }, f) } } @@ -454,13 +478,20 @@ impl Literal { /// Integer literal #[unstable(feature = "proc_macro", issue = "38356")] pub fn integer(n: i128) -> Literal { - Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None)) + Literal { + kind: LiteralKind::Integer, + contents: Term::intern(&n.to_string()), + suffix: None, + } } int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize); fn typed_integer(n: i128, kind: &'static str) -> Literal { - Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), - Some(Symbol::intern(kind)))) + Literal { + kind: LiteralKind::Integer, + contents: Term::intern(&n.to_string()), + suffix: Some(Term::intern(kind)), + } } /// Floating point literal. @@ -469,7 +500,11 @@ impl Literal { if !n.is_finite() { panic!("Invalid float literal {}", n); } - Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())), None)) + Literal { + kind: LiteralKind::Float, + contents: Term::intern(&n.to_string()), + suffix: None, + } } /// Floating point literal. @@ -478,8 +513,11 @@ impl Literal { if !n.is_finite() { panic!("Invalid f32 literal {}", n); } - Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())), - Some(Symbol::intern("f32")))) + Literal { + kind: LiteralKind::Float, + contents: Term::intern(&n.to_string()), + suffix: Some(Term::intern("f32")), + } } /// Floating point literal. @@ -488,8 +526,11 @@ impl Literal { if !n.is_finite() { panic!("Invalid f64 literal {}", n); } - Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())), - Some(Symbol::intern("f64")))) + Literal { + kind: LiteralKind::Float, + contents: Term::intern(&n.to_string()), + suffix: Some(Term::intern("f64")), + } } /// String literal. @@ -499,7 +540,11 @@ impl Literal { for ch in string.chars() { escaped.extend(ch.escape_debug()); } - Literal(token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None)) + Literal { + kind: LiteralKind::Str_, + contents: Term::intern(&escaped), + suffix: None, + } } /// Character literal. @@ -507,7 +552,11 @@ impl Literal { pub fn character(ch: char) -> Literal { let mut escaped = String::new(); escaped.extend(ch.escape_unicode()); - Literal(token::Literal(token::Lit::Char(Symbol::intern(&escaped)), None)) + Literal { + kind: LiteralKind::Char, + contents: Term::intern(&escaped), + suffix: None, + } } /// Byte string literal. @@ -515,73 +564,30 @@ impl Literal { pub fn byte_string(bytes: &[u8]) -> Literal { let string = bytes.iter().cloned().flat_map(ascii::escape_default) .map(Into::::into).collect::(); - Literal(token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None)) - } -} - -macro_rules! literals { - ($($i:ident),*; $($raw:ident),*) => { - #[unstable(feature = "proc_macro_internals", issue = "27812")] - #[doc(hidden)] - pub enum LiteralKind { - $($i,)* - $($raw(usize),)* - } - - impl LiteralKind { - #[unstable(feature = "proc_macro_internals", issue = "27812")] - #[doc(hidden)] - pub fn with_contents_and_suffix(self, contents: Term, suffix: Option) - -> Literal { - let contents = contents.0; - let suffix = suffix.map(|t| t.0); - match self { - $(LiteralKind::$i => { - Literal(token::Literal(token::Lit::$i(contents), suffix)) - })* - $(LiteralKind::$raw(n) => { - Literal(token::Literal(token::Lit::$raw(contents, n), suffix)) - })* - } - } - } - - impl Literal { - fn kind(&self) -> LiteralKind { - let lit = match self.0 { - token::Literal(lit, _) => lit, - _ => panic!("unsupported literal {:?}", self.0), - }; - - match lit { - $(token::Lit::$i(_) => LiteralKind::$i,)* - $(token::Lit::$raw(_, n) => LiteralKind::$raw(n),)* - } - } - - fn contents(&self) -> Term { - let lit = match self.0 { - token::Literal(lit, _) => lit, - _ => panic!("unsupported literal {:?}", self.0), - }; - - match lit { - $(token::Lit::$i(contents))|* | - $(token::Lit::$raw(contents, _))|* => Term(contents) - } - } - - fn suffix(&self) -> Option { - match self.0 { - token::Literal(_, suffix) => suffix.map(Term), - _ => panic!("unsupported literal {:?}", self.0), - } - } + Literal { + kind: LiteralKind::ByteStr, + contents: Term::intern(&string), + suffix: None, } } } -literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); +#[derive(Copy, Clone)] +#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[doc(hidden)] +pub enum LiteralKind { + DocComment, + + Byte, + Char, + Float, + Str_, + Integer, + ByteStr, + + StrRaw(usize), + ByteStrRaw(usize), +} /// An iterator over `TokenTree`s. #[derive(Clone)] diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index c21adc1ea90be..0717fa20301e4 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -151,35 +151,31 @@ impl Quote for Span { } } -macro_rules! literals { - ($($i:ident),*; $($raw:ident),*) => { - impl Quote for LiteralKind { - fn quote(self) -> TokenStream { +impl Quote for LiteralKind { + fn quote(self) -> TokenStream { + macro_rules! gen_match { + ($($i:ident),*; $($raw:ident),*) => { match self { - $(LiteralKind::$i => quote! { - ::LiteralKind::$i - },)* - $(LiteralKind::$raw(n) => quote! { - ::LiteralKind::$raw((quote n)) - },)* + $(LiteralKind::$i => quote!(::LiteralKind::$i),)* + $(LiteralKind::$raw(n) => quote!(::LiteralKind::$raw((quote n))),)* } } } - impl Quote for Literal { - fn quote(self) -> TokenStream { - let kind = self.kind(); - let contents = self.contents(); - let suffix = self.suffix(); - quote! { - (quote kind).with_contents_and_suffix((quote contents), (quote suffix)) - } - } - } + gen_match!(DocComment, Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw) } } -literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); + +impl Quote for Literal { + fn quote(self) -> TokenStream { + quote!(::Literal { + kind: (quote self.kind), + contents: (quote self.contents), + suffix: (quote self.suffix), + }) + } +} impl Quote for Delimiter { fn quote(self) -> TokenStream { diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index e1cee543daf18..3f0228222e4d1 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {Delimiter, Spacing, Term, TokenNode}; +use {Delimiter, Literal, LiteralKind, Spacing, Term, TokenNode}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; @@ -69,6 +69,56 @@ impl Delimiter { } } +macro_rules! literals { + ($($i:ident),*; $($raw:ident),*) => { + impl Literal { + fn from_internal(token: token::Token) -> Self { + let (lit, suffix) = match token { + token::Literal(lit, suffix) => (lit, suffix), + token::DocComment(contents) => { + return Literal { + kind: LiteralKind::DocComment, + contents: Term(contents), + suffix: None + }; + } + _ => panic!("unsupported literal {:?}", token), + }; + + let (kind, contents) = match lit { + $(token::Lit::$i(contents) => (LiteralKind::$i, contents),)* + $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* + }; + + Literal { + kind, + contents: Term(contents), + suffix: suffix.map(Term) + } + } + + fn to_internal(self) -> token::Token { + let contents = self.contents.0; + let suffix = self.suffix.map(|t| t.0); + match self.kind { + LiteralKind::DocComment => { + assert_eq!(suffix, None); + token::DocComment(contents) + } + $(LiteralKind::$i => { + token::Literal(token::Lit::$i(contents), suffix) + })* + $(LiteralKind::$raw(n) => { + token::Literal(token::Lit::$raw(contents, n), suffix) + })* + } + } + } + } +} + +literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); + pub struct Rustc<'a> { sess: &'a ParseSess, mark: Mark, @@ -134,7 +184,9 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { }; return TokenTree::Token(span, token).into(); } - TokenNode::Literal(token) => return TokenTree::Token(span, token.0).into(), + TokenNode::Literal(literal) => { + return TokenTree::Token(span, literal.to_internal()).into() + } }; let token = match op { @@ -255,7 +307,9 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { Question => op!('?'), Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), - Literal(..) | DocComment(..) => TokenNode::Literal(::Literal(token)), + Literal(..) | DocComment(..) => { + TokenNode::Literal(::Literal::from_internal(token)) + } Interpolated(_) => { let tts = token.interpolated_to_tokenstream(self.sess, span); From dd3be6767b7f7d4b3a542d7a550dfb4ba22b71e2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Mar 2018 01:09:22 +0200 Subject: [PATCH 07/14] proc_macro: don't use the unwrap_or macro from libsyntax. --- src/libproc_macro/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 970bbc98f3115..919b29a7598e7 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -42,7 +42,6 @@ #![feature(box_into_raw_non_null)] #![feature(nonnull_cast)] -#[macro_use] extern crate syntax; extern crate syntax_pos; extern crate rustc_errors; @@ -602,9 +601,9 @@ impl Iterator for TokenTreeIter { type Item = TokenTree; fn next(&mut self) -> Option { - let next = unwrap_or!(self.next.take().or_else(|| { + let next = self.next.take().or_else(|| { Frontend.token_cursor_next(&mut self.cursor) - }), return None); + })?; let (span, kind) = match Frontend.token_stream_to_token_tree(next) { (span, Ok((kind, next))) => { self.next = next; From a252474ac409a3820b5eb3b830cb49e4b5014f09 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 13:19:15 +0200 Subject: [PATCH 08/14] proc_macro: move compiler crate imports to the rustc module. --- src/libproc_macro/lib.rs | 11 ++--------- src/libproc_macro/rustc.rs | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 919b29a7598e7..60a0138196548 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -42,11 +42,6 @@ #![feature(box_into_raw_non_null)] #![feature(nonnull_cast)] -extern crate syntax; -extern crate syntax_pos; -extern crate rustc_errors; -extern crate rustc_data_structures; - #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] pub mod bridge; @@ -66,8 +61,6 @@ use std::{ascii, fmt, iter}; use std::path::PathBuf; use std::str::FromStr; -use syntax::symbol::Symbol; - /// The main type provided by this crate, representing an abstract stream of /// tokens. /// @@ -400,13 +393,13 @@ pub enum Delimiter { /// An interned string. #[derive(Copy, Clone, Debug)] #[unstable(feature = "proc_macro", issue = "38356")] -pub struct Term(Symbol); +pub struct Term(::rustc::Symbol); impl Term { /// Intern a string into a `Term`. #[unstable(feature = "proc_macro", issue = "38356")] pub fn intern(string: &str) -> Term { - Term(Symbol::intern(string)) + Term(::rustc::Symbol::intern(string)) } /// Get a reference to the interned string. diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index 3f0228222e4d1..e040077e3b007 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -8,17 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +extern crate syntax; +extern crate syntax_pos; +extern crate rustc_errors; +extern crate rustc_data_structures; + use {Delimiter, Literal, LiteralKind, Spacing, Term, TokenNode}; -use rustc_data_structures::sync::Lrc; -use rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; use std::path::PathBuf; -use syntax_pos::{self, SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP}; -use syntax_pos::hygiene::Mark; -use syntax::ast; -use syntax::ext::base::{ExtCtxt, ProcMacro}; -use syntax::parse::{self, token, ParseSess}; -use syntax::tokenstream; +use self::rustc_data_structures::sync::Lrc; +use self::rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; +use self::syntax_pos::{SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP}; +use self::syntax_pos::hygiene::Mark; +use self::syntax::ast; +use self::syntax::ext::base::{ExtCtxt, ProcMacro}; +use self::syntax::parse::{self, token, ParseSess}; +use self::syntax::tokenstream; + +pub use self::syntax_pos::symbol::Symbol; pub struct Quoter; @@ -169,8 +176,8 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { } fn token_stream_from_token_tree(&self, node: ::TokenNode, span: Self::Span) -> Self::TokenStream { - use syntax::parse::token::*; - use syntax::tokenstream::TokenTree; + use self::syntax::parse::token::*; + use self::syntax::tokenstream::TokenTree; let (op, kind) = match node { TokenNode::Op(op, kind) => (op, kind), @@ -224,7 +231,7 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { -> (Self::Span, Result<(::TokenNode, Option), (::Delimiter, Self::TokenStream)>) { - use syntax::parse::token::*; + use self::syntax::parse::token::*; let mut next = None; From 578c40e6e2b7b4a44fcda32f8f5f674747b8e3f9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 13:45:49 +0200 Subject: [PATCH 09/14] proc_macro: move Term to the bridge. --- src/libproc_macro/bridge.rs | 129 +++++++++++++++++++++++++++++------- src/libproc_macro/lib.rs | 46 ++++++++----- src/libproc_macro/rustc.rs | 94 +++++++++++++------------- 3 files changed, 177 insertions(+), 92 deletions(-) diff --git a/src/libproc_macro/bridge.rs b/src/libproc_macro/bridge.rs index b1154f0f947e7..42bb2bc8cd56a 100644 --- a/src/libproc_macro/bridge.rs +++ b/src/libproc_macro/bridge.rs @@ -21,10 +21,11 @@ use std::cell::Cell; use std::fmt; +use std::ops::Deref; use std::path::PathBuf; use std::ptr::NonNull; -use self::storage::{FromConcrete, ToConcrete}; +use self::storage::{FromConcrete, ToConcrete, Storage}; mod generation { use std::cell::Cell; @@ -233,14 +234,39 @@ mod storage { } } +/// Thread-local reference, to be used in place of `&'static T` +/// when it shouldn't be allowed to escape the thread. +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ThreadRef(&'static T); + +impl !Send for ThreadRef {} +impl !Sync for ThreadRef {} + +impl Deref for ThreadRef { + type Target = T; + fn deref(&self) -> &T { + self.0 + } +} + +impl ThreadRef { + pub fn new(x: &'static T) -> Self { + ThreadRef(x) + } +} + storage_concrete_passthrough! { [] (), [] bool, + [] char, ['a] &'a str, + [] ThreadRef, // FIXME(eddyb) achieve ABI compatibility for these types. - [] ::TokenNode, [] ::Delimiter, + [] ::LiteralKind, + [] ::Spacing, [] ::LexError, [] ::LineColumn, [] ::Level, @@ -269,16 +295,11 @@ macro_rules! each_frontend_method { $meth!(fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool;); $meth!(fn token_stream_from_str(&self, src: &str) -> Result;); - $meth!(fn token_stream_delimited(&self, span: Self::Span, - delimiter: ::Delimiter, - delimed: Self::TokenStream) - -> Self::TokenStream;); - $meth!(fn token_stream_from_token_tree(&self, node: ::TokenNode, span: Self::Span) + $meth!(fn token_stream_from_token_tree(&self, node: Self::TokenNode, span: Self::Span) -> Self::TokenStream;); $meth!(fn token_stream_to_token_tree(&self, stream: Self::TokenStream) - -> (Self::Span, - Result<(::TokenNode, Option), - (::Delimiter, Self::TokenStream)>);); + -> ((Self::Span, Self::TokenNode), + Option);); $meth!(fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor;); $meth!(fn token_stream_builder_cleanup(&self, _builder: Self::TokenStreamBuilder) -> () {}); @@ -323,6 +344,12 @@ macro_rules! each_frontend_method { $meth!(fn span_end(&self, span: Self::Span) -> ::LineColumn;); $meth!(fn span_join(&self, first: Self::Span, second: Self::Span) -> Option;); $meth!(fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span;); + + $meth!(fn term_debug(&self, term: Self::Term, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&term, f) + }); + $meth!(fn term_intern(&self, string: &str) -> Self::Term;); + $meth!(fn term_as_str(&self, term: Self::Term) -> ThreadRef;); } } @@ -337,9 +364,49 @@ pub trait FrontendInterface { type Diagnostic: 'static; /// NB. has to be the same size as u32. type Span: 'static + Copy + Eq + fmt::Debug; + /// NB. has to be the same size as u32. + type Term: 'static + Copy + Eq + fmt::Debug; + /// Only needed for object safety, should always be `TokenNode`. + type TokenNode; each_frontend_method!(define_frontend_trait_method); } +macro_rules! frontend_wrapper { + (enum $name:ident<$F:ident> { $($variant:ident($($field:ident: $field_ty:ty),*)),* }) => { + #[repr(C)] + pub enum $name<$F: FrontendInterface> { + $($variant($($field_ty),*)),* + } + + impl FromConcrete<$name, $name> for Storage { + fn from_concrete(&self, x: $name) -> $name { + match x { + $($name::$variant($($field),*) => { + $name::$variant($(self.from_concrete($field)),*) + }),* + } + } + } + + impl ToConcrete<$name, $name> for Storage { + fn to_concrete(&self, x: $name) -> $name { + match x { + $($name::$variant($($field),*) => { + $name::$variant($(self.to_concrete($field)),*) + }),* + } + } + } + } +} + +frontend_wrapper!(enum TokenNode { + Group(delim: ::Delimiter, delimed: F::TokenStream), + Term(term: F::Term), + Op(op: char, spacing: ::Spacing), + Literal(kind: ::LiteralKind, contents: F::Term, suffix: Option) +}); + macro_rules! define_boxed { ($($name:ident { cleanup: $cleanup:ident }),*) => { $( @@ -353,28 +420,28 @@ macro_rules! define_boxed { Frontend.$cleanup($name(boxed)) } } - impl FromConcrete for storage::Storage + impl FromConcrete for Storage where $name: storage::Concrete { fn from_concrete(&self, x: T) -> $name { $name(self.from_concrete(Box::new(x))) } } - impl ToConcrete<$name, T> for storage::Storage + impl ToConcrete<$name, T> for Storage where $name: storage::Concrete { fn to_concrete(&self, x: $name) -> T { *self.to_concrete(x.0) } } - impl<'a, S, T: 'static> ToConcrete<&'a $name, &'a T> for storage::Storage + impl<'a, S, T: 'static> ToConcrete<&'a $name, &'a T> for Storage where $name: storage::Concrete { fn to_concrete(&self, x: &'a $name) -> &'a T { self.to_concrete(&x.0) } } - impl<'a, S, T: 'static> ToConcrete<&'a mut $name, &'a mut T> for storage::Storage + impl<'a, S, T: 'static> ToConcrete<&'a mut $name, &'a mut T> for Storage where $name: storage::Concrete { fn to_concrete(&self, x: &'a mut $name) -> &'a mut T { @@ -442,14 +509,14 @@ macro_rules! define_inline { impl storage::Concrete for $name { type Concrete = F::$name; } - impl FromConcrete for storage::Storage + impl FromConcrete for Storage where $name: storage::Concrete { fn from_concrete(&self, x: T) -> $name { $name(self.from_concrete(x)) } } - impl ToConcrete<$name, T> for storage::Storage + impl ToConcrete<$name, T> for Storage where $name: storage::Concrete { fn to_concrete(&self, x: $name) -> T { @@ -460,7 +527,7 @@ macro_rules! define_inline { } } -define_inline!(Span); +define_inline!(Span, Term); impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -468,6 +535,12 @@ impl fmt::Debug for Span { } } +impl fmt::Debug for Term { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Frontend.term_debug(*self, f) + } +} + pub(crate) struct Frontend; macro_rules! define_frontend_current_method { @@ -485,6 +558,8 @@ impl FrontendInterface for Frontend { type SourceFile = SourceFile; type Diagnostic = Diagnostic; type Span = Span; + type Term = Term; + type TokenNode = TokenNode; each_frontend_method!(define_frontend_current_method); } @@ -496,6 +571,8 @@ type CurrentFrontend<'a> = FrontendInterface< SourceFile = SourceFile, Diagnostic = Diagnostic, Span = Span, + Term = Term, + TokenNode = TokenNode, > + 'a; // Emulate scoped_thread_local!() here essentially @@ -537,11 +614,11 @@ fn set_current_frontend(frontend: &CurrentFrontend, f: F) -> R fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generation, frontend: F, f: G) -> R - where F: FrontendInterface, - G: FnOnce(&CurrentFrontend, &storage::Storage) -> R + where F: FrontendInterface>, + G: FnOnce(&CurrentFrontend, &Storage) -> R { - struct EraseConcrete { - storage: storage::Storage, + struct EraseConcrete>> { + storage: Storage, concrete: F } @@ -554,18 +631,20 @@ fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generatio } } } - impl FrontendInterface for EraseConcrete { + impl>> FrontendInterface for EraseConcrete { type TokenStream = TokenStream; type TokenStreamBuilder = TokenStreamBuilder; type TokenCursor = TokenCursor; type SourceFile = SourceFile; type Diagnostic = Diagnostic; type Span = Span; + type Term = Term; + type TokenNode = TokenNode; each_frontend_method!(define_frontend_erase_concrete_method); } let frontend = EraseConcrete { - storage: storage::Storage::new(ng), + storage: Storage::new(ng), concrete: frontend }; f(&frontend, &frontend.storage) @@ -607,7 +686,7 @@ impl Expand1 { } pub fn run(&self, frontend: F, input: F::TokenStream) -> F::TokenStream - where F: FrontendInterface + where F: FrontendInterface> { erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { let input = storage.from_concrete(input); @@ -657,7 +736,7 @@ impl Expand2 { pub fn run(&self, frontend: F, input: F::TokenStream, input2: F::TokenStream) -> F::TokenStream - where F: FrontendInterface + where F: FrontendInterface> { erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { let input = storage.from_concrete(input); diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 60a0138196548..40f1246e8c6e7 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -121,12 +121,16 @@ pub fn quote_token_stream(stream: TokenStream) -> TokenStream { #[unstable(feature = "proc_macro", issue = "38356")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream(match tree.kind { - TokenNode::Group(delimiter, tokens) => { - Frontend.token_stream_delimited(tree.span.0, delimiter, tokens.0) + TokenStream(Frontend.token_stream_from_token_tree(match tree.kind { + TokenNode::Group(delim, delimed) => { + bridge::TokenNode::Group(delim, delimed.0) } - _ => Frontend.token_stream_from_token_tree(tree.kind, tree.span.0) - }) + TokenNode::Term(term) => bridge::TokenNode::Term(term.0), + TokenNode::Op(c, s) => bridge::TokenNode::Op(c, s), + TokenNode::Literal(Literal { kind, contents, suffix }) => { + bridge::TokenNode::Literal(kind, contents.0, suffix.map(|s| s.0)) + } + }, tree.span.0)) } } @@ -393,19 +397,19 @@ pub enum Delimiter { /// An interned string. #[derive(Copy, Clone, Debug)] #[unstable(feature = "proc_macro", issue = "38356")] -pub struct Term(::rustc::Symbol); +pub struct Term(bridge::Term); impl Term { /// Intern a string into a `Term`. #[unstable(feature = "proc_macro", issue = "38356")] pub fn intern(string: &str) -> Term { - Term(::rustc::Symbol::intern(string)) + Term(Frontend.term_intern(string)) } /// Get a reference to the interned string. #[unstable(feature = "proc_macro", issue = "38356")] pub fn as_str(&self) -> &str { - unsafe { &*(&*self.0.as_str() as *const str) } + unsafe { &*(&*Frontend.term_as_str(self.0) as *const str) } } } @@ -597,18 +601,24 @@ impl Iterator for TokenTreeIter { let next = self.next.take().or_else(|| { Frontend.token_cursor_next(&mut self.cursor) })?; - let (span, kind) = match Frontend.token_stream_to_token_tree(next) { - (span, Ok((kind, next))) => { - self.next = next; - (span, kind) - } - (span, Err((delimiter, delimed))) => { - (span, TokenNode::Group(delimiter, TokenStream(delimed))) - } - }; + let ((span, kind), next) = Frontend.token_stream_to_token_tree(next); + self.next = next; Some(TokenTree { span: Span(span), - kind + kind: match kind { + bridge::TokenNode::Group(delim, delimed) => { + TokenNode::Group(delim, TokenStream(delimed)) + } + bridge::TokenNode::Term(term) => TokenNode::Term(Term(term)), + bridge::TokenNode::Op(c, s) => TokenNode::Op(c, s), + bridge::TokenNode::Literal(kind, contents, suffix) => { + TokenNode::Literal(Literal { + kind, + contents: Term(contents), + suffix: suffix.map(Term) + }) + } + } }) } } diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs index e040077e3b007..415b803b5d6c9 100644 --- a/src/libproc_macro/rustc.rs +++ b/src/libproc_macro/rustc.rs @@ -13,25 +13,25 @@ extern crate syntax_pos; extern crate rustc_errors; extern crate rustc_data_structures; -use {Delimiter, Literal, LiteralKind, Spacing, Term, TokenNode}; +use {Delimiter, LiteralKind, Spacing}; +use bridge::{FrontendInterface, ThreadRef, TokenNode}; use std::path::PathBuf; use self::rustc_data_structures::sync::Lrc; use self::rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; -use self::syntax_pos::{SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP}; +use self::syntax_pos::{SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP, Span}; use self::syntax_pos::hygiene::Mark; +use self::syntax_pos::symbol::Symbol; use self::syntax::ast; use self::syntax::ext::base::{ExtCtxt, ProcMacro}; use self::syntax::parse::{self, token, ParseSess}; use self::syntax::tokenstream; -pub use self::syntax_pos::symbol::Symbol; - pub struct Quoter; impl ProcMacro for Quoter { fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, - _: syntax_pos::Span, + _: Span, stream: tokenstream::TokenStream) -> tokenstream::TokenStream { let expand_quoter = ::bridge::Expand1::new(&::quote_token_stream); @@ -78,16 +78,12 @@ impl Delimiter { macro_rules! literals { ($($i:ident),*; $($raw:ident),*) => { - impl Literal { - fn from_internal(token: token::Token) -> Self { + impl LiteralKind { + fn from_internal(token: token::Token) -> (Self, Symbol, Option) { let (lit, suffix) = match token { token::Literal(lit, suffix) => (lit, suffix), token::DocComment(contents) => { - return Literal { - kind: LiteralKind::DocComment, - contents: Term(contents), - suffix: None - }; + return (LiteralKind::DocComment, contents, None); } _ => panic!("unsupported literal {:?}", token), }; @@ -97,17 +93,11 @@ macro_rules! literals { $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* }; - Literal { - kind, - contents: Term(contents), - suffix: suffix.map(Term) - } + (kind, contents, suffix) } - fn to_internal(self) -> token::Token { - let contents = self.contents.0; - let suffix = self.suffix.map(|t| t.0); - match self.kind { + fn to_internal(self, contents: Symbol, suffix: Option) -> token::Token { + match self { LiteralKind::DocComment => { assert_eq!(suffix, None); token::DocComment(contents) @@ -140,13 +130,16 @@ impl<'a> Rustc<'a> { } } -impl<'a> ::bridge::FrontendInterface for Rustc<'a> { +impl<'a> FrontendInterface for Rustc<'a> { type TokenStream = tokenstream::TokenStream; type TokenStreamBuilder = tokenstream::TokenStreamBuilder; type TokenCursor = tokenstream::Cursor; type SourceFile = Lrc; type Diagnostic = Diagnostic; - type Span = syntax_pos::Span; + type Span = Span; + type Term = Symbol; + + type TokenNode = TokenNode; fn token_stream_empty(&self) -> Self::TokenStream { tokenstream::TokenStream::empty() @@ -165,34 +158,30 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); Ok(parse::parse_stream_from_source_str(name, src, self.sess, Some(span))) } - fn token_stream_delimited(&self, span: Self::Span, - delimiter: ::Delimiter, - delimed: Self::TokenStream) - -> Self::TokenStream { - tokenstream::TokenTree::Delimited(span, tokenstream::Delimited { - delim: delimiter.to_internal(), - tts: delimed.into(), - }).into() - } - fn token_stream_from_token_tree(&self, node: ::TokenNode, span: Self::Span) + fn token_stream_from_token_tree(&self, node: Self::TokenNode, span: Self::Span) -> Self::TokenStream { use self::syntax::parse::token::*; use self::syntax::tokenstream::TokenTree; let (op, kind) = match node { TokenNode::Op(op, kind) => (op, kind), - TokenNode::Group(..) => unreachable!(), + TokenNode::Group(delimiter, delimed) => { + return tokenstream::TokenTree::Delimited(span, tokenstream::Delimited { + delim: delimiter.to_internal(), + tts: delimed.into(), + }).into(); + } TokenNode::Term(symbol) => { - let ident = ast::Ident { name: symbol.0, ctxt: span.ctxt() }; - let token = if symbol.0.as_str().starts_with("'") { + let ident = ast::Ident { name: symbol, ctxt: span.ctxt() }; + let token = if symbol.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) }; return TokenTree::Token(span, token).into(); } - TokenNode::Literal(literal) => { - return TokenTree::Token(span, literal.to_internal()).into() + TokenNode::Literal(kind, contents, suffix) => { + return TokenTree::Token(span, kind.to_internal(contents, suffix)).into() } }; @@ -228,9 +217,8 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { } } fn token_stream_to_token_tree(&self, stream: Self::TokenStream) - -> (Self::Span, - Result<(::TokenNode, Option), - (::Delimiter, Self::TokenStream)>) { + -> ((Self::Span, Self::TokenNode), + Option) { use self::syntax::parse::token::*; let mut next = None; @@ -239,7 +227,7 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { let (mut span, token) = match tree { tokenstream::TokenTree::Delimited(span, delimed) => { let delimiter = Delimiter::from_internal(delimed.delim); - return (span, Err((delimiter, delimed.tts.into()))); + return ((span, TokenNode::Group(delimiter, delimed.tts.into())), next); } tokenstream::TokenTree::Token(span, token) => (span, token), }; @@ -255,9 +243,9 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { } } - fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span, - next: &mut Option) - -> TokenNode { + fn joint<'a>(first: char, rest: Token, is_joint: bool, span: &mut Span, + next: &mut Option) + -> TokenNode> { let (first_span, rest_span) = (*span, *span); *span = first_span; let tree = tokenstream::TokenTree::Token(rest_span, rest); @@ -313,14 +301,15 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { Dollar => op!('$'), Question => op!('?'), - Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Ident(ident) | Lifetime(ident) => TokenNode::Term(ident.name), Literal(..) | DocComment(..) => { - TokenNode::Literal(::Literal::from_internal(token)) + let (kind, contents, suffix) = LiteralKind::from_internal(token); + TokenNode::Literal(kind, contents, suffix) } Interpolated(_) => { let tts = token.interpolated_to_tokenstream(self.sess, span); - return (span, Err((Delimiter::None, tts))); + TokenNode::Group(Delimiter::None, tts) } DotEq => joint!('.', Eq), @@ -328,7 +317,7 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { Whitespace | Comment | Shebang(..) | Eof => unreachable!(), }; - (span, Ok((kind, next))) + ((span, kind), next) } fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor { stream.trees() @@ -442,4 +431,11 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> { fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span { span.with_ctxt(at.ctxt()) } + + fn term_intern(&self, string: &str) -> Self::Term { + Symbol::intern(string) + } + fn term_as_str(&self, term: Self::Term) -> ThreadRef { + ThreadRef::new(unsafe { &*(&*term.as_str() as *const str) }) + } } From a3f3b123478f9cc10184d757c2d414277a725d55 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 16:41:14 +0200 Subject: [PATCH 10/14] proc_macro: move the rustc frontend to syntax_ext::proc_macro_impl. --- src/Cargo.lock | 6 - src/libproc_macro/Cargo.toml | 5 - src/libproc_macro/lib.rs | 4 - src/libproc_macro/rustc.rs | 441 -------------------------- src/librustc_metadata/cstore_impl.rs | 3 +- src/libsyntax_ext/deriving/custom.rs | 2 +- src/libsyntax_ext/lib.rs | 1 + src/libsyntax_ext/proc_macro_impl.rs | 454 ++++++++++++++++++++++++++- 8 files changed, 448 insertions(+), 468 deletions(-) delete mode 100644 src/libproc_macro/rustc.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 26508dec4bba2..3fbcd4b98a5a0 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1270,12 +1270,6 @@ dependencies = [ [[package]] name = "proc_macro" version = "0.0.0" -dependencies = [ - "rustc_data_structures 0.0.0", - "rustc_errors 0.0.0", - "syntax 0.0.0", - "syntax_pos 0.0.0", -] [[package]] name = "profiler_builtins" diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml index c1b2622520b11..29e1c03cee170 100644 --- a/src/libproc_macro/Cargo.toml +++ b/src/libproc_macro/Cargo.toml @@ -7,8 +7,3 @@ version = "0.0.0" path = "lib.rs" crate-type = ["dylib"] -[dependencies] -syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } -rustc_errors = { path = "../librustc_errors" } -rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 40f1246e8c6e7..90c487e1507f8 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -48,10 +48,6 @@ pub mod bridge; use bridge::{Frontend, FrontendInterface}; -#[unstable(feature = "proc_macro_internals", issue = "27812")] -#[doc(hidden)] -pub mod rustc; - mod diagnostic; #[unstable(feature = "proc_macro", issue = "38356")] diff --git a/src/libproc_macro/rustc.rs b/src/libproc_macro/rustc.rs deleted file mode 100644 index 415b803b5d6c9..0000000000000 --- a/src/libproc_macro/rustc.rs +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate syntax; -extern crate syntax_pos; -extern crate rustc_errors; -extern crate rustc_data_structures; - -use {Delimiter, LiteralKind, Spacing}; -use bridge::{FrontendInterface, ThreadRef, TokenNode}; - -use std::path::PathBuf; -use self::rustc_data_structures::sync::Lrc; -use self::rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; -use self::syntax_pos::{SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP, Span}; -use self::syntax_pos::hygiene::Mark; -use self::syntax_pos::symbol::Symbol; -use self::syntax::ast; -use self::syntax::ext::base::{ExtCtxt, ProcMacro}; -use self::syntax::parse::{self, token, ParseSess}; -use self::syntax::tokenstream; - -pub struct Quoter; - -impl ProcMacro for Quoter { - fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, - _: Span, - stream: tokenstream::TokenStream) - -> tokenstream::TokenStream { - let expand_quoter = ::bridge::Expand1::new(&::quote_token_stream); - - let mut info = cx.current_expansion.mark.expn_info().unwrap(); - info.callee.allow_internal_unstable = true; - cx.current_expansion.mark.set_expn_info(info); - - expand_quoter.run(Rustc::new(cx), stream) - } -} - -impl ::Level { - fn to_internal(self) -> Level { - match self { - ::Level::Error => Level::Error, - ::Level::Warning => Level::Warning, - ::Level::Note => Level::Note, - ::Level::Help => Level::Help, - ::Level::__Nonexhaustive => unreachable!("Level::__Nonexhaustive") - } - } -} - -impl Delimiter { - fn from_internal(delim: token::DelimToken) -> Delimiter { - match delim { - token::Paren => Delimiter::Parenthesis, - token::Brace => Delimiter::Brace, - token::Bracket => Delimiter::Bracket, - token::NoDelim => Delimiter::None, - } - } - - fn to_internal(self) -> token::DelimToken { - match self { - Delimiter::Parenthesis => token::Paren, - Delimiter::Brace => token::Brace, - Delimiter::Bracket => token::Bracket, - Delimiter::None => token::NoDelim, - } - } -} - -macro_rules! literals { - ($($i:ident),*; $($raw:ident),*) => { - impl LiteralKind { - fn from_internal(token: token::Token) -> (Self, Symbol, Option) { - let (lit, suffix) = match token { - token::Literal(lit, suffix) => (lit, suffix), - token::DocComment(contents) => { - return (LiteralKind::DocComment, contents, None); - } - _ => panic!("unsupported literal {:?}", token), - }; - - let (kind, contents) = match lit { - $(token::Lit::$i(contents) => (LiteralKind::$i, contents),)* - $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* - }; - - (kind, contents, suffix) - } - - fn to_internal(self, contents: Symbol, suffix: Option) -> token::Token { - match self { - LiteralKind::DocComment => { - assert_eq!(suffix, None); - token::DocComment(contents) - } - $(LiteralKind::$i => { - token::Literal(token::Lit::$i(contents), suffix) - })* - $(LiteralKind::$raw(n) => { - token::Literal(token::Lit::$raw(contents, n), suffix) - })* - } - } - } - } -} - -literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); - -pub struct Rustc<'a> { - sess: &'a ParseSess, - mark: Mark, -} - -impl<'a> Rustc<'a> { - pub fn new(cx: &'a ExtCtxt) -> Self { - Rustc { - sess: cx.parse_sess, - mark: cx.current_expansion.mark - } - } -} - -impl<'a> FrontendInterface for Rustc<'a> { - type TokenStream = tokenstream::TokenStream; - type TokenStreamBuilder = tokenstream::TokenStreamBuilder; - type TokenCursor = tokenstream::Cursor; - type SourceFile = Lrc; - type Diagnostic = Diagnostic; - type Span = Span; - type Term = Symbol; - - type TokenNode = TokenNode; - - fn token_stream_empty(&self) -> Self::TokenStream { - tokenstream::TokenStream::empty() - } - fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool { - stream.is_empty() - } - fn token_stream_from_str(&self, src: &str) -> Result { - let src = src.to_string(); - let name = FileName::ProcMacroSourceCode; - let expn_info = self.mark.expn_info().unwrap(); - let call_site = expn_info.call_site; - // notify the expansion info that it is unhygienic - let mark = Mark::fresh(self.mark); - mark.set_expn_info(expn_info); - let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - Ok(parse::parse_stream_from_source_str(name, src, self.sess, Some(span))) - } - fn token_stream_from_token_tree(&self, node: Self::TokenNode, span: Self::Span) - -> Self::TokenStream { - use self::syntax::parse::token::*; - use self::syntax::tokenstream::TokenTree; - - let (op, kind) = match node { - TokenNode::Op(op, kind) => (op, kind), - TokenNode::Group(delimiter, delimed) => { - return tokenstream::TokenTree::Delimited(span, tokenstream::Delimited { - delim: delimiter.to_internal(), - tts: delimed.into(), - }).into(); - } - TokenNode::Term(symbol) => { - let ident = ast::Ident { name: symbol, ctxt: span.ctxt() }; - let token = if symbol.as_str().starts_with("'") { - Lifetime(ident) - } else { - Ident(ident) - }; - return TokenTree::Token(span, token).into(); - } - TokenNode::Literal(kind, contents, suffix) => { - return TokenTree::Token(span, kind.to_internal(contents, suffix)).into() - } - }; - - let token = match op { - '=' => Eq, - '<' => Lt, - '>' => Gt, - '!' => Not, - '~' => Tilde, - '+' => BinOp(Plus), - '-' => BinOp(Minus), - '*' => BinOp(Star), - '/' => BinOp(Slash), - '%' => BinOp(Percent), - '^' => BinOp(Caret), - '&' => BinOp(And), - '|' => BinOp(Or), - '@' => At, - '.' => Dot, - ',' => Comma, - ';' => Semi, - ':' => Colon, - '#' => Pound, - '$' => Dollar, - '?' => Question, - _ => panic!("unsupported character {}", op), - }; - - let tree = TokenTree::Token(span, token); - match kind { - Spacing::Alone => tree.into(), - Spacing::Joint => tree.joint(), - } - } - fn token_stream_to_token_tree(&self, stream: Self::TokenStream) - -> ((Self::Span, Self::TokenNode), - Option) { - use self::syntax::parse::token::*; - - let mut next = None; - - let (tree, is_joint) = stream.as_tree(); - let (mut span, token) = match tree { - tokenstream::TokenTree::Delimited(span, delimed) => { - let delimiter = Delimiter::from_internal(delimed.delim); - return ((span, TokenNode::Group(delimiter, delimed.tts.into())), next); - } - tokenstream::TokenTree::Token(span, token) => (span, token), - }; - - let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone }; - macro_rules! op { - ($op:expr) => { TokenNode::Op($op, op_kind) } - } - - macro_rules! joint { - ($first:expr, $rest:expr) => { - joint($first, $rest, is_joint, &mut span, &mut next) - } - } - - fn joint<'a>(first: char, rest: Token, is_joint: bool, span: &mut Span, - next: &mut Option) - -> TokenNode> { - let (first_span, rest_span) = (*span, *span); - *span = first_span; - let tree = tokenstream::TokenTree::Token(rest_span, rest); - *next = Some(if is_joint { tree.joint() } else { tree.into() }); - TokenNode::Op(first, Spacing::Joint) - } - - let kind = match token { - Eq => op!('='), - Lt => op!('<'), - Le => joint!('<', Eq), - EqEq => joint!('=', Eq), - Ne => joint!('!', Eq), - Ge => joint!('>', Eq), - Gt => op!('>'), - AndAnd => joint!('&', BinOp(And)), - OrOr => joint!('|', BinOp(Or)), - Not => op!('!'), - Tilde => op!('~'), - BinOp(Plus) => op!('+'), - BinOp(Minus) => op!('-'), - BinOp(Star) => op!('*'), - BinOp(Slash) => op!('/'), - BinOp(Percent) => op!('%'), - BinOp(Caret) => op!('^'), - BinOp(And) => op!('&'), - BinOp(Or) => op!('|'), - BinOp(Shl) => joint!('<', Lt), - BinOp(Shr) => joint!('>', Gt), - BinOpEq(Plus) => joint!('+', Eq), - BinOpEq(Minus) => joint!('-', Eq), - BinOpEq(Star) => joint!('*', Eq), - BinOpEq(Slash) => joint!('/', Eq), - BinOpEq(Percent) => joint!('%', Eq), - BinOpEq(Caret) => joint!('^', Eq), - BinOpEq(And) => joint!('&', Eq), - BinOpEq(Or) => joint!('|', Eq), - BinOpEq(Shl) => joint!('<', Le), - BinOpEq(Shr) => joint!('>', Ge), - At => op!('@'), - Dot => op!('.'), - DotDot => joint!('.', Dot), - DotDotDot => joint!('.', DotDot), - DotDotEq => joint!('.', DotEq), - Comma => op!(','), - Semi => op!(';'), - Colon => op!(':'), - ModSep => joint!(':', Colon), - RArrow => joint!('-', Gt), - LArrow => joint!('<', BinOp(Minus)), - FatArrow => joint!('=', Gt), - Pound => op!('#'), - Dollar => op!('$'), - Question => op!('?'), - - Ident(ident) | Lifetime(ident) => TokenNode::Term(ident.name), - Literal(..) | DocComment(..) => { - let (kind, contents, suffix) = LiteralKind::from_internal(token); - TokenNode::Literal(kind, contents, suffix) - } - - Interpolated(_) => { - let tts = token.interpolated_to_tokenstream(self.sess, span); - TokenNode::Group(Delimiter::None, tts) - } - - DotEq => joint!('.', Eq), - OpenDelim(..) | CloseDelim(..) => unreachable!(), - Whitespace | Comment | Shebang(..) | Eof => unreachable!(), - }; - - ((span, kind), next) - } - fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor { - stream.trees() - } - - fn token_stream_builder_new(&self) -> Self::TokenStreamBuilder { - tokenstream::TokenStreamBuilder::new() - } - fn token_stream_builder_push(&self, builder: &mut Self::TokenStreamBuilder, - stream: Self::TokenStream) { - builder.push(stream); - } - fn token_stream_builder_build(&self, builder: Self::TokenStreamBuilder) - -> Self::TokenStream { - builder.build() - } - - fn token_cursor_next(&self, cursor: &mut Self::TokenCursor) -> Option { - while let Some(stream) = cursor.next_as_stream() { - let (tree, _) = stream.clone().as_tree(); - let span = tree.span(); - if span != DUMMY_SP { - return Some(stream); - } - let nested_stream = match tree { - tokenstream::TokenTree::Delimited(_, tokenstream::Delimited { - delim: token::NoDelim, - tts - }) => tts.into(), - tokenstream::TokenTree::Token(_, token @ token::Interpolated(_)) => { - token.interpolated_to_tokenstream(self.sess, span) - } - _ => return Some(stream) - }; - cursor.insert(nested_stream); - } - None - } - - fn source_file_eq(&self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool { - Lrc::ptr_eq(file1, file2) - } - fn source_file_path(&self, file: &Self::SourceFile) -> PathBuf { - match file.name { - FileName::Real(ref path) => path.clone(), - _ => PathBuf::from(file.name.to_string()) - } - } - fn source_file_is_real(&self, file: &Self::SourceFile) -> bool { - file.is_real_file() - } - - fn diagnostic_new(&self, level: ::Level, msg: &str, span: Option) - -> Self::Diagnostic { - let mut diagnostic = Diagnostic::new(level.to_internal(), msg); - - if let Some(span) = span { - diagnostic.set_span(span); - } - - diagnostic - - } - fn diagnostic_sub(&self, diagnostic: &mut Self::Diagnostic, - level: ::Level, msg: &str, span: Option) { - let span = span.map(|s| s.into()).unwrap_or(MultiSpan::new()); - diagnostic.sub(level.to_internal(), msg, span, None); - } - fn diagnostic_emit(&self, diagnostic: Self::Diagnostic) { - DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diagnostic).emit() - } - - fn span_def_site(&self) -> Self::Span { - self.span_call_site() - .with_ctxt(SyntaxContext::empty().apply_mark(self.mark)) - } - fn span_call_site(&self) -> Self::Span { - self.mark.expn_info().unwrap().call_site - } - fn span_source_file(&self, span: Self::Span) -> Self::SourceFile { - self.sess.codemap().lookup_char_pos(span.lo()).file - } - fn span_parent(&self, span: Self::Span) -> Option { - span.ctxt().outer().expn_info().map(|i| i.call_site) - } - fn span_source(&self, span: Self::Span) -> Self::Span { - span.source_callsite() - } - fn span_start(&self, span: Self::Span) -> ::LineColumn { - let loc = self.sess.codemap().lookup_char_pos(span.lo()); - ::LineColumn { - line: loc.line, - column: loc.col.to_usize() - } - } - fn span_end(&self, span: Self::Span) -> ::LineColumn { - let loc = self.sess.codemap().lookup_char_pos(span.hi()); - ::LineColumn { - line: loc.line, - column: loc.col.to_usize() - } - } - fn span_join(&self, first: Self::Span, second: Self::Span) -> Option { - let self_loc = self.sess.codemap().lookup_char_pos(first.lo()); - let other_loc = self.sess.codemap().lookup_char_pos(second.lo()); - - if self_loc.file.name != other_loc.file.name { return None } - - Some(first.to(second)) - } - fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span { - span.with_ctxt(at.ctxt()) - } - - fn term_intern(&self, string: &str) -> Self::Term { - Symbol::intern(string) - } - fn term_as_str(&self, term: Self::Term) -> ThreadRef { - ThreadRef::new(unsafe { &*(&*term.as_str() as *const str) }) - } -} diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index a8ada587add7c..dd4987df3995b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -41,6 +41,7 @@ use syntax::ext::base::SyntaxExtension; use syntax::parse::filemap_to_stream; use syntax::symbol::Symbol; use syntax_pos::{Span, NO_EXPANSION, FileName}; +use syntax_ext::proc_macro_impl; use rustc_data_structures::indexed_set::IdxSetBuf; use rustc::hir; @@ -502,7 +503,7 @@ impl CrateStore for cstore::CStore { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); } else if data.name == "proc_macro" && self.get_crate_data(id.krate).item_name(id.index) == "quote" { - let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::rustc::Quoter)); + let ext = SyntaxExtension::ProcMacro(Box::new(proc_macro_impl::Quoter)); return LoadedMacro::ProcMacro(Lrc::new(ext)); } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 9cc589c54cd09..ae1eae8ad441f 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -80,7 +80,7 @@ impl MultiItemModifier for ProcMacroDerive { let token = Token::interpolated(token::NtItem(item)); let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(::proc_macro::rustc::Rustc::new(ecx), input) + self.inner.run(::proc_macro_impl::Frontend::new(ecx), input) })); let stream = match res { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 249a64b353f59..f23a9c91f08fe 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -15,6 +15,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] +#![feature(proc_macro)] #![feature(proc_macro_internals)] #![feature(decl_macro)] #![feature(str_escape)] diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 9e38d7ffaea57..8387fb5efb468 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -9,16 +9,24 @@ // except according to those terms. use std::panic; +use std::path::PathBuf; -use errors::FatalError; +use errors::{Diagnostic, DiagnosticBuilder, FatalError, Level}; -use syntax::codemap::Span; -use syntax::ext::base::*; -use syntax::tokenstream::TokenStream; -use syntax::ext::base; +use proc_macro::{Delimiter, LexError, LineColumn, LiteralKind, Spacing}; +use proc_macro::bridge::{Expand1, Expand2, FrontendInterface, ThreadRef, TokenNode}; + +use rustc_data_structures::sync::Lrc; +use syntax_pos::{SyntaxContext, FileMap, FileName, MultiSpan, Pos, DUMMY_SP, Span}; +use syntax_pos::hygiene::Mark; +use syntax_pos::symbol::Symbol; +use syntax::ast; +use syntax::ext::base::{self, ExtCtxt, ProcMacro}; +use syntax::parse::{self, token, ParseSess}; +use syntax::tokenstream::{self, TokenStream}; pub struct AttrProcMacro { - pub inner: ::proc_macro::bridge::Expand2, + pub inner: Expand2, } impl base::AttrProcMacro for AttrProcMacro { @@ -29,7 +37,7 @@ impl base::AttrProcMacro for AttrProcMacro { annotated: TokenStream) -> TokenStream { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(::proc_macro::rustc::Rustc::new(ecx), annotation, annotated) + self.inner.run(Frontend::new(ecx), annotation, annotated) })); match res { @@ -52,17 +60,17 @@ impl base::AttrProcMacro for AttrProcMacro { } pub struct BangProcMacro { - pub inner: ::proc_macro::bridge::Expand1, + pub inner: Expand1, } -impl base::ProcMacro for BangProcMacro { +impl ProcMacro for BangProcMacro { fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream) -> TokenStream { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(::proc_macro::rustc::Rustc::new(ecx), input) + self.inner.run(Frontend::new(ecx), input) })); match res { @@ -83,3 +91,429 @@ impl base::ProcMacro for BangProcMacro { } } } + +pub struct Quoter; + +impl ProcMacro for Quoter { + fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, + _: Span, + stream: TokenStream) + -> TokenStream { + let expand_quoter = Expand1::new(&::proc_macro::quote_token_stream); + + let mut info = cx.current_expansion.mark.expn_info().unwrap(); + info.callee.allow_internal_unstable = true; + cx.current_expansion.mark.set_expn_info(info); + + expand_quoter.run(Frontend::new(cx), stream) + } +} + +trait FromInternal { + fn from_internal(x: T) -> Self; +} + +trait ToInternal { + fn to_internal(self) -> T; +} + +impl ToInternal for ::proc_macro::Level { + fn to_internal(self) -> Level { + match self { + ::proc_macro::Level::Error => Level::Error, + ::proc_macro::Level::Warning => Level::Warning, + ::proc_macro::Level::Note => Level::Note, + ::proc_macro::Level::Help => Level::Help, + ::proc_macro::Level::__Nonexhaustive => unreachable!("Level::__Nonexhaustive") + } + } +} + +impl FromInternal for Delimiter { + fn from_internal(delim: token::DelimToken) -> Delimiter { + match delim { + token::Paren => Delimiter::Parenthesis, + token::Brace => Delimiter::Brace, + token::Bracket => Delimiter::Bracket, + token::NoDelim => Delimiter::None, + } + } +} + +impl ToInternal for Delimiter { + fn to_internal(self) -> token::DelimToken { + match self { + Delimiter::Parenthesis => token::Paren, + Delimiter::Brace => token::Brace, + Delimiter::Bracket => token::Bracket, + Delimiter::None => token::NoDelim, + } + } +} + +macro_rules! literals { + ($($i:ident),*; $($raw:ident),*) => { + impl FromInternal for (LiteralKind, Symbol, Option) { + fn from_internal(token: token::Token) -> Self { + let (lit, suffix) = match token { + token::Literal(lit, suffix) => (lit, suffix), + token::DocComment(contents) => { + return (LiteralKind::DocComment, contents, None); + } + _ => panic!("unsupported literal {:?}", token), + }; + + let (kind, contents) = match lit { + $(token::Lit::$i(contents) => (LiteralKind::$i, contents),)* + $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* + }; + + (kind, contents, suffix) + } + } + + impl ToInternal for (LiteralKind, Symbol, Option) { + fn to_internal(self) -> token::Token { + let (kind, contents, suffix) = self; + match kind { + LiteralKind::DocComment => { + assert_eq!(suffix, None); + token::DocComment(contents) + } + $(LiteralKind::$i => { + token::Literal(token::Lit::$i(contents), suffix) + })* + $(LiteralKind::$raw(n) => { + token::Literal(token::Lit::$raw(contents, n), suffix) + })* + } + } + } + } +} + +literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); + +pub(crate) struct Frontend<'a> { + sess: &'a ParseSess, + mark: Mark, +} + +impl<'a> Frontend<'a> { + pub fn new(cx: &'a ExtCtxt) -> Self { + Frontend { + sess: cx.parse_sess, + mark: cx.current_expansion.mark + } + } +} + +impl<'a> FrontendInterface for Frontend<'a> { + type TokenStream = TokenStream; + type TokenStreamBuilder = tokenstream::TokenStreamBuilder; + type TokenCursor = tokenstream::Cursor; + type SourceFile = Lrc; + type Diagnostic = Diagnostic; + type Span = Span; + type Term = Symbol; + + type TokenNode = TokenNode; + + fn token_stream_empty(&self) -> Self::TokenStream { + TokenStream::empty() + } + fn token_stream_is_empty(&self, stream: &Self::TokenStream) -> bool { + stream.is_empty() + } + fn token_stream_from_str(&self, src: &str) -> Result { + let src = src.to_string(); + let name = FileName::ProcMacroSourceCode; + let expn_info = self.mark.expn_info().unwrap(); + let call_site = expn_info.call_site; + // notify the expansion info that it is unhygienic + let mark = Mark::fresh(self.mark); + mark.set_expn_info(expn_info); + let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); + Ok(parse::parse_stream_from_source_str(name, src, self.sess, Some(span))) + } + fn token_stream_from_token_tree(&self, node: Self::TokenNode, span: Self::Span) + -> Self::TokenStream { + use syntax::parse::token::*; + use syntax::tokenstream::TokenTree; + + let (op, kind) = match node { + TokenNode::Op(op, kind) => (op, kind), + TokenNode::Group(delimiter, delimed) => { + return tokenstream::TokenTree::Delimited(span, tokenstream::Delimited { + delim: delimiter.to_internal(), + tts: delimed.into(), + }).into(); + } + TokenNode::Term(symbol) => { + let ident = ast::Ident { name: symbol, ctxt: span.ctxt() }; + let token = if symbol.as_str().starts_with("'") { + Lifetime(ident) + } else { + Ident(ident) + }; + return TokenTree::Token(span, token).into(); + } + TokenNode::Literal(kind, contents, suffix) => { + return TokenTree::Token(span, (kind, contents, suffix).to_internal()).into() + } + }; + + let token = match op { + '=' => Eq, + '<' => Lt, + '>' => Gt, + '!' => Not, + '~' => Tilde, + '+' => BinOp(Plus), + '-' => BinOp(Minus), + '*' => BinOp(Star), + '/' => BinOp(Slash), + '%' => BinOp(Percent), + '^' => BinOp(Caret), + '&' => BinOp(And), + '|' => BinOp(Or), + '@' => At, + '.' => Dot, + ',' => Comma, + ';' => Semi, + ':' => Colon, + '#' => Pound, + '$' => Dollar, + '?' => Question, + _ => panic!("unsupported character {}", op), + }; + + let tree = TokenTree::Token(span, token); + match kind { + Spacing::Alone => tree.into(), + Spacing::Joint => tree.joint(), + } + } + fn token_stream_to_token_tree(&self, stream: Self::TokenStream) + -> ((Self::Span, Self::TokenNode), + Option) { + use syntax::parse::token::*; + + let mut next = None; + + let (tree, is_joint) = stream.as_tree(); + let (mut span, token) = match tree { + tokenstream::TokenTree::Delimited(span, delimed) => { + let delimiter = Delimiter::from_internal(delimed.delim); + return ((span, TokenNode::Group(delimiter, delimed.tts.into())), next); + } + tokenstream::TokenTree::Token(span, token) => (span, token), + }; + + let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone }; + macro_rules! op { + ($op:expr) => { TokenNode::Op($op, op_kind) } + } + + macro_rules! joint { + ($first:expr, $rest:expr) => { + joint($first, $rest, is_joint, &mut span, &mut next) + } + } + + fn joint<'a>(first: char, rest: Token, is_joint: bool, span: &mut Span, + next: &mut Option) + -> TokenNode> { + let (first_span, rest_span) = (*span, *span); + *span = first_span; + let tree = tokenstream::TokenTree::Token(rest_span, rest); + *next = Some(if is_joint { tree.joint() } else { tree.into() }); + TokenNode::Op(first, Spacing::Joint) + } + + let kind = match token { + Eq => op!('='), + Lt => op!('<'), + Le => joint!('<', Eq), + EqEq => joint!('=', Eq), + Ne => joint!('!', Eq), + Ge => joint!('>', Eq), + Gt => op!('>'), + AndAnd => joint!('&', BinOp(And)), + OrOr => joint!('|', BinOp(Or)), + Not => op!('!'), + Tilde => op!('~'), + BinOp(Plus) => op!('+'), + BinOp(Minus) => op!('-'), + BinOp(Star) => op!('*'), + BinOp(Slash) => op!('/'), + BinOp(Percent) => op!('%'), + BinOp(Caret) => op!('^'), + BinOp(And) => op!('&'), + BinOp(Or) => op!('|'), + BinOp(Shl) => joint!('<', Lt), + BinOp(Shr) => joint!('>', Gt), + BinOpEq(Plus) => joint!('+', Eq), + BinOpEq(Minus) => joint!('-', Eq), + BinOpEq(Star) => joint!('*', Eq), + BinOpEq(Slash) => joint!('/', Eq), + BinOpEq(Percent) => joint!('%', Eq), + BinOpEq(Caret) => joint!('^', Eq), + BinOpEq(And) => joint!('&', Eq), + BinOpEq(Or) => joint!('|', Eq), + BinOpEq(Shl) => joint!('<', Le), + BinOpEq(Shr) => joint!('>', Ge), + At => op!('@'), + Dot => op!('.'), + DotDot => joint!('.', Dot), + DotDotDot => joint!('.', DotDot), + DotDotEq => joint!('.', DotEq), + Comma => op!(','), + Semi => op!(';'), + Colon => op!(':'), + ModSep => joint!(':', Colon), + RArrow => joint!('-', Gt), + LArrow => joint!('<', BinOp(Minus)), + FatArrow => joint!('=', Gt), + Pound => op!('#'), + Dollar => op!('$'), + Question => op!('?'), + + Ident(ident) | Lifetime(ident) => TokenNode::Term(ident.name), + Literal(..) | DocComment(..) => { + let (kind, contents, suffix) = FromInternal::from_internal(token); + TokenNode::Literal(kind, contents, suffix) + } + + Interpolated(_) => { + let tts = token.interpolated_to_tokenstream(self.sess, span); + TokenNode::Group(Delimiter::None, tts) + } + + DotEq => joint!('.', Eq), + OpenDelim(..) | CloseDelim(..) => unreachable!(), + Whitespace | Comment | Shebang(..) | Eof => unreachable!(), + }; + + ((span, kind), next) + } + fn token_stream_trees(&self, stream: Self::TokenStream) -> Self::TokenCursor { + stream.trees() + } + + fn token_stream_builder_new(&self) -> Self::TokenStreamBuilder { + tokenstream::TokenStreamBuilder::new() + } + fn token_stream_builder_push(&self, builder: &mut Self::TokenStreamBuilder, + stream: Self::TokenStream) { + builder.push(stream); + } + fn token_stream_builder_build(&self, builder: Self::TokenStreamBuilder) + -> Self::TokenStream { + builder.build() + } + + fn token_cursor_next(&self, cursor: &mut Self::TokenCursor) -> Option { + while let Some(stream) = cursor.next_as_stream() { + let (tree, _) = stream.clone().as_tree(); + let span = tree.span(); + if span != DUMMY_SP { + return Some(stream); + } + let nested_stream = match tree { + tokenstream::TokenTree::Delimited(_, tokenstream::Delimited { + delim: token::NoDelim, + tts + }) => tts.into(), + tokenstream::TokenTree::Token(_, token @ token::Interpolated(_)) => { + token.interpolated_to_tokenstream(self.sess, span) + } + _ => return Some(stream) + }; + cursor.insert(nested_stream); + } + None + } + + fn source_file_eq(&self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool { + Lrc::ptr_eq(file1, file2) + } + fn source_file_path(&self, file: &Self::SourceFile) -> PathBuf { + match file.name { + FileName::Real(ref path) => path.clone(), + _ => PathBuf::from(file.name.to_string()) + } + } + fn source_file_is_real(&self, file: &Self::SourceFile) -> bool { + file.is_real_file() + } + + fn diagnostic_new(&self, level: ::proc_macro::Level, msg: &str, span: Option) + -> Self::Diagnostic { + let mut diagnostic = Diagnostic::new(level.to_internal(), msg); + + if let Some(span) = span { + diagnostic.set_span(span); + } + + diagnostic + + } + fn diagnostic_sub(&self, diagnostic: &mut Self::Diagnostic, + level: ::proc_macro::Level, msg: &str, span: Option) { + let span = span.map(|s| s.into()).unwrap_or(MultiSpan::new()); + diagnostic.sub(level.to_internal(), msg, span, None); + } + fn diagnostic_emit(&self, diagnostic: Self::Diagnostic) { + DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diagnostic).emit() + } + + fn span_def_site(&self) -> Self::Span { + self.span_call_site() + .with_ctxt(SyntaxContext::empty().apply_mark(self.mark)) + } + fn span_call_site(&self) -> Self::Span { + self.mark.expn_info().unwrap().call_site + } + fn span_source_file(&self, span: Self::Span) -> Self::SourceFile { + self.sess.codemap().lookup_char_pos(span.lo()).file + } + fn span_parent(&self, span: Self::Span) -> Option { + span.ctxt().outer().expn_info().map(|i| i.call_site) + } + fn span_source(&self, span: Self::Span) -> Self::Span { + span.source_callsite() + } + fn span_start(&self, span: Self::Span) -> LineColumn { + let loc = self.sess.codemap().lookup_char_pos(span.lo()); + LineColumn { + line: loc.line, + column: loc.col.to_usize() + } + } + fn span_end(&self, span: Self::Span) -> LineColumn { + let loc = self.sess.codemap().lookup_char_pos(span.hi()); + LineColumn { + line: loc.line, + column: loc.col.to_usize() + } + } + fn span_join(&self, first: Self::Span, second: Self::Span) -> Option { + let self_loc = self.sess.codemap().lookup_char_pos(first.lo()); + let other_loc = self.sess.codemap().lookup_char_pos(second.lo()); + + if self_loc.file.name != other_loc.file.name { return None } + + Some(first.to(second)) + } + fn span_resolved_at(&self, span: Self::Span, at: Self::Span) -> Self::Span { + span.with_ctxt(at.ctxt()) + } + + fn term_intern(&self, string: &str) -> Self::Term { + Symbol::intern(string) + } + fn term_as_str(&self, term: Self::Term) -> ThreadRef { + ThreadRef::new(unsafe { &*(&*term.as_str() as *const str) }) + } +} From 9a87b8f29a047cb24a8642c68b1e5d2f3d5daa96 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 19:46:52 +0200 Subject: [PATCH 11/14] proc_macro: handle proc macro panics in their proc_macro instance. --- src/Cargo.lock | 3 ++ src/libproc_macro/Cargo.toml | 2 ++ src/libproc_macro/bridge.rs | 50 +++++++++++++++++++++------- src/libproc_macro/lib.rs | 3 ++ src/librustc/util/common.rs | 5 +-- src/libsyntax_ext/deriving/custom.rs | 7 +--- src/libsyntax_ext/proc_macro_impl.rs | 15 ++------- 7 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 3fbcd4b98a5a0..59aba9418134f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1270,6 +1270,9 @@ dependencies = [ [[package]] name = "proc_macro" version = "0.0.0" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "profiler_builtins" diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml index 29e1c03cee170..b0a95707e682a 100644 --- a/src/libproc_macro/Cargo.toml +++ b/src/libproc_macro/Cargo.toml @@ -7,3 +7,5 @@ version = "0.0.0" path = "lib.rs" crate-type = ["dylib"] +[dependencies] +lazy_static = "1.0.0" diff --git a/src/libproc_macro/bridge.rs b/src/libproc_macro/bridge.rs index 42bb2bc8cd56a..94fb3a33b2c1b 100644 --- a/src/libproc_macro/bridge.rs +++ b/src/libproc_macro/bridge.rs @@ -22,8 +22,10 @@ use std::cell::Cell; use std::fmt; use std::ops::Deref; +use std::panic; use std::path::PathBuf; use std::ptr::NonNull; +use std::thread; use self::storage::{FromConcrete, ToConcrete, Storage}; @@ -580,8 +582,20 @@ thread_local! { static CURRENT_FRONTEND: Cell>>> = Cell::new(None); } -pub fn has_current_frontend() -> bool { - CURRENT_FRONTEND.with(|p| p.get().is_some()) +// Hide the default panic output within `proc_macro` expansions. +// NB. frontends can't do this because they may use a different libstd. +lazy_static! { + static ref DEFAULT_HOOK: Box = { + let hook = panic::take_hook(); + panic::set_hook(Box::new(panic_hook)); + hook + }; +} + +fn panic_hook(info: &panic::PanicInfo) { + if CURRENT_FRONTEND.with(|p| p.get().is_none()) { + (*DEFAULT_HOOK)(info) + } } fn with_current_frontend(f: F) -> R @@ -604,6 +618,9 @@ fn set_current_frontend(frontend: &CurrentFrontend, f: F) -> R } } + // Ensure panic output hiding is set up. + ::lazy_static::initialize(&DEFAULT_HOOK); + CURRENT_FRONTEND.with(|p| { let _reset = Reset { prev: p.get() }; p.set(NonNull::new(frontend as *const _ as *mut _)); @@ -657,8 +674,9 @@ fn erase_concrete_frontend(ng: extern "C" fn() -> generation::Generatio pub struct Expand1 { next_generation: extern "C" fn() -> generation::Generation, data: *const (), + // FIXME(eddyb) achieve ABI compatibility for the `thread::Result` type. run: unsafe extern "C" fn(*const (), &&CurrentFrontend, TokenStream) - -> TokenStream, + -> thread::Result, } impl !Send for Expand1 {} @@ -670,12 +688,15 @@ impl Expand1 { { unsafe extern "C" fn run(f: *const (), frontend: &&CurrentFrontend, - input: TokenStream) -> TokenStream + input: TokenStream) + -> thread::Result where F: Fn(::TokenStream) -> ::TokenStream { let f = &*(f as *const F); set_current_frontend(*frontend, || { - f(::TokenStream(input)).0 + panic::catch_unwind(panic::AssertUnwindSafe(|| { + f(::TokenStream(input)).0 + })) }) } Expand1 { @@ -685,7 +706,8 @@ impl Expand1 { } } - pub fn run(&self, frontend: F, input: F::TokenStream) -> F::TokenStream + pub fn run(&self, frontend: F, input: F::TokenStream) + -> thread::Result where F: FrontendInterface> { erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { @@ -693,7 +715,7 @@ impl Expand1 { let output = unsafe { (self.run)(self.data, &frontend, input) }; - storage.to_concrete(output) + output.map(|output| storage.to_concrete(output)) }) } } @@ -705,8 +727,9 @@ impl Expand1 { pub struct Expand2 { next_generation: extern "C" fn() -> generation::Generation, data: *const (), + // FIXME(eddyb) achieve ABI compatibility for the `thread::Result` type. run: unsafe extern "C" fn(*const (), &&CurrentFrontend, TokenStream, TokenStream) - -> TokenStream, + -> thread::Result, } impl !Send for Expand2 {} @@ -719,12 +742,15 @@ impl Expand2 { unsafe extern "C" fn run(f: *const (), frontend: &&CurrentFrontend, input: TokenStream, - input2: TokenStream) -> TokenStream + input2: TokenStream) + -> thread::Result where F: Fn(::TokenStream, ::TokenStream) -> ::TokenStream { let f = &*(f as *const F); set_current_frontend(*frontend, || { - f(::TokenStream(input), ::TokenStream(input2)).0 + panic::catch_unwind(panic::AssertUnwindSafe(|| { + f(::TokenStream(input), ::TokenStream(input2)).0 + })) }) } Expand2 { @@ -735,7 +761,7 @@ impl Expand2 { } pub fn run(&self, frontend: F, input: F::TokenStream, input2: F::TokenStream) - -> F::TokenStream + -> thread::Result where F: FrontendInterface> { erase_concrete_frontend(self.next_generation, frontend, |frontend, storage| { @@ -744,7 +770,7 @@ impl Expand2 { let output = unsafe { (self.run)(self.data, &frontend, input, input2) }; - storage.to_concrete(output) + output.map(|output| storage.to_concrete(output)) }) } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 90c487e1507f8..f6e39d25a31a3 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -42,6 +42,9 @@ #![feature(box_into_raw_non_null)] #![feature(nonnull_cast)] +#[macro_use] +extern crate lazy_static; + #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] pub mod bridge; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index f8aeaebe6c92a..2f782c3914fcb 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -24,7 +24,6 @@ use std::sync::mpsc::{Sender}; use syntax_pos::{SpanData}; use ty::maps::{QueryMsg}; use dep_graph::{DepNode}; -use proc_macro; use lazy_static; use session::Session; @@ -47,9 +46,7 @@ lazy_static! { } fn panic_hook(info: &panic::PanicInfo) { - if !proc_macro::bridge::has_current_frontend() { - (*DEFAULT_HOOK)(info) - } + (*DEFAULT_HOOK)(info) } pub fn install_panic_hook() { diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index ae1eae8ad441f..98959a445b0eb 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::panic; - use errors::FatalError; use syntax::ast::{self, ItemKind, Attribute, Mac}; use syntax::attr::{mark_used, mark_known}; @@ -79,11 +77,8 @@ impl MultiItemModifier for ProcMacroDerive { let item = ecx.resolver.eliminate_crate_var(item.clone()); let token = Token::interpolated(token::NtItem(item)); let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into(); - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(::proc_macro_impl::Frontend::new(ecx), input) - })); - let stream = match res { + let stream = match self.inner.run(::proc_macro_impl::Frontend::new(ecx), input) { Ok(stream) => stream, Err(e) => { let msg = "proc-macro derive panicked"; diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index 8387fb5efb468..594d238013923 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::panic; use std::path::PathBuf; use errors::{Diagnostic, DiagnosticBuilder, FatalError, Level}; @@ -36,11 +35,7 @@ impl base::AttrProcMacro for AttrProcMacro { annotation: TokenStream, annotated: TokenStream) -> TokenStream { - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(Frontend::new(ecx), annotation, annotated) - })); - - match res { + match self.inner.run(Frontend::new(ecx), annotation, annotated) { Ok(stream) => stream, Err(e) => { let msg = "custom attribute panicked"; @@ -69,11 +64,7 @@ impl ProcMacro for BangProcMacro { span: Span, input: TokenStream) -> TokenStream { - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - self.inner.run(Frontend::new(ecx), input) - })); - - match res { + match self.inner.run(Frontend::new(ecx), input) { Ok(stream) => stream, Err(e) => { let msg = "proc macro panicked"; @@ -105,7 +96,7 @@ impl ProcMacro for Quoter { info.callee.allow_internal_unstable = true; cx.current_expansion.mark.set_expn_info(info); - expand_quoter.run(Frontend::new(cx), stream) + expand_quoter.run(Frontend::new(cx), stream).unwrap() } } From 825bfebf006a043fc17e71b19758907fe90480c9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 20:20:03 +0200 Subject: [PATCH 12/14] tests: remove ignore-stage1 where possible in proc_macro tests. --- .../compile-fail-fulldeps/proc-macro/attribute-with-error.rs | 1 - .../compile-fail-fulldeps/proc-macro/attributes-included.rs | 1 - src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs | 1 - .../compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs | 1 - src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs | 1 - src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs | 1 - src/test/compile-fail-fulldeps/proc-macro/item-error.rs | 1 - .../compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs | 1 - .../compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs | 1 - src/test/incremental-fulldeps/incremental_proc_macro.rs | 1 - src/test/run-pass-fulldeps/compiler-calls.rs | 1 + src/test/run-pass-fulldeps/macro-quote-cond.rs | 1 - src/test/run-pass-fulldeps/macro-quote-test.rs | 1 - src/test/run-pass-fulldeps/proc-macro/add-impl.rs | 1 - src/test/run-pass-fulldeps/proc-macro/append-impl.rs | 1 - src/test/run-pass-fulldeps/proc-macro/attr-args.rs | 1 - src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs | 1 - src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs | 1 - src/test/run-pass-fulldeps/proc-macro/bang-macro.rs | 1 - src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs | 1 - src/test/run-pass-fulldeps/proc-macro/crate-var.rs | 1 - src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs | 1 - src/test/run-pass-fulldeps/proc-macro/derive-b.rs | 1 - src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs | 1 - src/test/run-pass-fulldeps/proc-macro/empty-crate.rs | 1 - src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs | 1 - src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs | 1 - src/test/run-pass-fulldeps/proc-macro/issue-39889.rs | 1 - src/test/run-pass-fulldeps/proc-macro/issue-42708.rs | 1 - src/test/run-pass-fulldeps/proc-macro/load-two.rs | 1 - src/test/run-pass-fulldeps/proc-macro/smoke.rs | 1 - src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs | 1 - src/test/run-pass-fulldeps/proc-macro/use-reexport.rs | 1 - src/test/run-pass-fulldeps/proc_macro.rs | 1 - src/test/ui-fulldeps/custom-derive/issue-36935.rs | 2 +- src/test/ui-fulldeps/proc-macro/parent-source-spans.rs | 2 +- src/test/ui-fulldeps/proc-macro/three-equals.rs | 2 +- 37 files changed, 4 insertions(+), 36 deletions(-) diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs index 00a27818327f6..65f4b6350c4ee 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:attribute-with-error.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs b/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs index 2adbee1d3fbd5..f42d1006bf5c1 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:attributes-included.rs -// ignore-stage1 #![feature(proc_macro, rustc_attrs)] #![warn(unused)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs index 93790f5937298..ac27e87ace105 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-bad.rs -// ignore-stage1 #[macro_use] extern crate derive_bad; diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs index 6f254dcbdb11a..e4fcbb117a505 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-unstable-2.rs -// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs index ca0f0e382ed0c..836e336fc22f0 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-unstable.rs -// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs index 1d645a7ec510f..42475e6de90c9 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:issue_38586.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs index c0d4d71a6ec8b..4133e75e3a62d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/item-error.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-b.rs -// ignore-stage1 #![allow(warnings)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs index 773b16b945f07..90e9615e62c0e 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:bang_proc_macro2.rs -// ignore-stage1 #![feature(proc_macro)] #![allow(unused_macros)] diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs index 153e4dd05717a..df881bedec1bb 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-b.rs -// ignore-stage1 #![allow(warnings)] diff --git a/src/test/incremental-fulldeps/incremental_proc_macro.rs b/src/test/incremental-fulldeps/incremental_proc_macro.rs index e434507085332..bfbbb8d6380fd 100644 --- a/src/test/incremental-fulldeps/incremental_proc_macro.rs +++ b/src/test/incremental-fulldeps/incremental_proc_macro.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:incremental_proc_macro_aux.rs -// ignore-stage1 // revisions: cfail1 cfail2 // must-compile-successfully diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index 85aa92ce26076..5b724878cfdb0 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -11,6 +11,7 @@ // Test that the CompilerCalls interface to the compiler works. // ignore-cross-compile +// ignore-stage1 #![feature(rustc_private, path)] #![feature(core)] diff --git a/src/test/run-pass-fulldeps/macro-quote-cond.rs b/src/test/run-pass-fulldeps/macro-quote-cond.rs index cff743bdae6cd..ba92225a2e8ac 100644 --- a/src/test/run-pass-fulldeps/macro-quote-cond.rs +++ b/src/test/run-pass-fulldeps/macro-quote-cond.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:cond_plugin.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/macro-quote-test.rs b/src/test/run-pass-fulldeps/macro-quote-test.rs index eb77895e2d7ad..4b4ba18b52db0 100644 --- a/src/test/run-pass-fulldeps/macro-quote-test.rs +++ b/src/test/run-pass-fulldeps/macro-quote-test.rs @@ -11,7 +11,6 @@ // Test that a macro can emit delimiters with nothing inside - `()`, `{}` // aux-build:hello_macro.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs index 5175fe174a9e7..7ea7ceafc2876 100644 --- a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:add-impl.rs -// ignore-stage1 #[macro_use] extern crate add_impl; diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs index 37aef7ef1318c..591f3331d28c0 100644 --- a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs +++ b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:append-impl.rs -// ignore-stage1 #![allow(warnings)] diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs b/src/test/run-pass-fulldeps/proc-macro/attr-args.rs index 2968cc7871d7e..8a9fdd7536770 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-args.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:attr-args.rs -// ignore-stage1 #![allow(warnings)] #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs index 5a28d756df5a5..b1791836f3809 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:attr-cfg.rs -// ignore-stage1 // revisions: foo bar #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs b/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs index 52a8652e65bcf..8ba38875eff5b 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:attr-on-trait.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs index ffa4731f1e637..531bd0dd3569d 100644 --- a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:bang-macro.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs b/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs index 00ad0e76ed014..1a2b144e4717b 100644 --- a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs +++ b/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:count_compound_ops.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs index b6acb0faab2a5..ba1417ecb56e4 100644 --- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs +++ b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:double.rs -// ignore-stage1 #![allow(unused)] diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs index b94c45248dae5..6d8bba8bffaad 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-attr-cfg.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs index 995dc65729a50..0a8a98649013c 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-b.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs index ba5a639a759cb..ce3ba60b0ecf4 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-same-struct.rs -// ignore-stage1 #[macro_use] extern crate derive_same_struct; diff --git a/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs b/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs index 38a2716aee77b..bf34037bb596d 100644 --- a/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs +++ b/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:empty-crate.rs -// ignore-stage1 #[macro_use] extern crate empty_crate; diff --git a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs index 4ccd4615fb609..6a0669c4bb2fc 100644 --- a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:expand-with-a-macro.rs -// ignore-stage1 #![deny(warnings)] diff --git a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs b/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs index 4cac7d19b4de8..51198db5aa76d 100644 --- a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs +++ b/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs @@ -10,7 +10,6 @@ // aux-build:hygiene_example_codegen.rs // aux-build:hygiene_example.rs -// ignore-stage1 #![feature(proc_macro)] diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs b/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs index 87130242c0f04..05610116ad6bf 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:issue-39889.rs -// ignore-stage1 #![feature(proc_macro)] #![allow(unused)] diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs index e53e94ae475b2..b4eb4fe65bd8a 100644 --- a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs +++ b/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:issue-42708.rs -// ignore-stage1 #![feature(decl_macro, proc_macro)] #![allow(unused)] diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass-fulldeps/proc-macro/load-two.rs index 67c1237781470..d15a83a2cbe43 100644 --- a/src/test/run-pass-fulldeps/proc-macro/load-two.rs +++ b/src/test/run-pass-fulldeps/proc-macro/load-two.rs @@ -10,7 +10,6 @@ // aux-build:derive-atob.rs // aux-build:derive-ctod.rs -// ignore-stage1 #[macro_use] extern crate derive_atob; diff --git a/src/test/run-pass-fulldeps/proc-macro/smoke.rs b/src/test/run-pass-fulldeps/proc-macro/smoke.rs index 54d651df1f9af..c267d574702ee 100644 --- a/src/test/run-pass-fulldeps/proc-macro/smoke.rs +++ b/src/test/run-pass-fulldeps/proc-macro/smoke.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-a.rs -// ignore-stage1 #[macro_use] extern crate derive_a; diff --git a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs b/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs index c9056e08d4426..df5a3bd07cc31 100644 --- a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:derive-nothing.rs -// ignore-stage1 #[macro_use] extern crate derive_nothing; diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs index 03dfeb1f5c9a5..f0a1bfe652857 100644 --- a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs +++ b/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs @@ -10,7 +10,6 @@ // aux-build:derive-a.rs // aux-build:derive-reexport.rs -// ignore-stage1 #[macro_use] extern crate derive_reexport; diff --git a/src/test/run-pass-fulldeps/proc_macro.rs b/src/test/run-pass-fulldeps/proc_macro.rs index cdda723585b7a..98bd7e96703f8 100644 --- a/src/test/run-pass-fulldeps/proc_macro.rs +++ b/src/test/run-pass-fulldeps/proc_macro.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:proc_macro_def.rs -// ignore-stage1 // ignore-cross-compile #![feature(proc_macro)] diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.rs b/src/test/ui-fulldeps/custom-derive/issue-36935.rs index 4fd8763206733..95923d0aad2da 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.rs +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:plugin.rs -// ignore-stage1 + #![feature(proc_macro)] diff --git a/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs b/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs index 4c71afbac4df1..6221319b35f99 100644 --- a/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs +++ b/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:parent-source-spans.rs -// ignore-stage1 + #![feature(proc_macro, decl_macro)] diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.rs b/src/test/ui-fulldeps/proc-macro/three-equals.rs index ef2d160529068..b567e5a590d04 100644 --- a/src/test/ui-fulldeps/proc-macro/three-equals.rs +++ b/src/test/ui-fulldeps/proc-macro/three-equals.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:three-equals.rs -// ignore-stage1 + #![feature(proc_macro)] From 705de74d07cd289276770c786666ba62ee594c7e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 20:43:33 +0200 Subject: [PATCH 13/14] proc_macro: move to a dependency of libtest. --- src/Cargo.lock | 5 +---- src/librustc/Cargo.toml | 2 -- src/librustc_metadata/Cargo.toml | 1 - src/libsyntax_ext/Cargo.toml | 3 +-- src/libtest/Cargo.toml | 3 +++ 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 59aba9418134f..0a8f54bf45bd8 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1546,9 +1546,7 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc_macro 0.0.0", "rustc_apfloat 0.0.0", "rustc_back 0.0.0", "rustc_const_math 0.0.0", @@ -1828,7 +1826,6 @@ version = "0.0.0" dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc_macro 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_data_structures 0.0.0", @@ -2284,7 +2281,6 @@ name = "syntax_ext" version = "0.0.0" dependencies = [ "fmt_macros 0.0.0", - "proc_macro 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "syntax 0.0.0", @@ -2402,6 +2398,7 @@ name = "test" version = "0.0.0" dependencies = [ "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "proc_macro 0.0.0", "term 0.0.0", ] diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 7e84a69dd7913..2c4898cb2c006 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -14,9 +14,7 @@ bitflags = "1.0" fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } jobserver = "0.1" -lazy_static = "1.0.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } -proc_macro = { path = "../libproc_macro" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index a2dcf7f3f83f2..c38b7121bbe86 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["dylib"] [dependencies] flate2 = "1.0" log = "0.4" -proc_macro = { path = "../libproc_macro" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index d8eeb5ed2554a..432e2bc1a1b97 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -10,8 +10,7 @@ crate-type = ["dylib"] [dependencies] fmt_macros = { path = "../libfmt_macros" } -proc_macro = { path = "../libproc_macro" } rustc_errors = { path = "../librustc_errors" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file +rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml index ec77f95338081..aade10ed6c324 100644 --- a/src/libtest/Cargo.toml +++ b/src/libtest/Cargo.toml @@ -11,3 +11,6 @@ crate-type = ["dylib", "rlib"] [dependencies] getopts = "0.2" term = { path = "../libterm" } + +# not actually used but needed to always have proc_macro in the sysroot +proc_macro = { path = "../libproc_macro" } From 6e63e8d04e8b03c5aac4be1c8daecd90e4172bbb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 20 Mar 2018 22:19:52 +0200 Subject: [PATCH 14/14] tests: move all proc_macro tests from -fulldeps. --- src/bootstrap/builder.rs | 2 +- src/bootstrap/test.rs | 6 ------ .../proc-macro/attribute-with-error.rs | 0 .../proc-macro/attribute.rs | 0 .../proc-macro/attributes-included.rs | 0 .../proc-macro/auxiliary/attr_proc_macro.rs | 0 .../proc-macro/auxiliary/attribute-with-error.rs | 0 .../proc-macro/auxiliary/attributes-included.rs | 0 .../proc-macro/auxiliary/bang_proc_macro.rs | 0 .../proc-macro/auxiliary/bang_proc_macro2.rs | 0 .../proc-macro/auxiliary/derive-a-b.rs | 0 .../proc-macro/auxiliary/derive-a.rs | 0 .../proc-macro/auxiliary/derive-b.rs | 0 .../proc-macro/auxiliary/derive-bad.rs | 0 .../proc-macro/auxiliary/derive-clona.rs | 0 .../proc-macro/auxiliary/derive-foo.rs | 0 .../proc-macro/auxiliary/derive-unstable-2.rs | 0 .../proc-macro/auxiliary/derive-unstable.rs | 0 .../proc-macro/auxiliary/issue-41211.rs | 0 .../proc-macro/auxiliary/issue_38586.rs | 0 .../proc-macro/define-two.rs | 0 .../proc-macro/derive-bad.rs | 0 .../proc-macro/derive-still-gated.rs | 0 .../proc-macro/expand-to-unstable-2.rs | 0 .../proc-macro/expand-to-unstable.rs | 0 .../proc-macro/export-macro.rs | 0 .../proc-macro/exports.rs | 0 .../proc-macro/feature-gate-proc_macro.rs | 0 .../proc-macro/illegal-proc-macro-derive-use.rs | 0 .../proc-macro/import.rs | 0 .../proc-macro/issue-37788.rs | 0 .../proc-macro/issue-38586.rs | 0 .../proc-macro/issue-41211.rs | 0 .../proc-macro/item-error.rs | 0 .../proc-macro/lints_in_proc_macros.rs | 0 .../proc-macro/macro-use-attr.rs | 0 .../proc-macro/macro-use-bang.rs | 0 .../proc-macro/no-macro-use-attr.rs | 0 .../proc-macro/proc-macro-attributes.rs | 0 .../proc-macro/proc-macro-custom-attr-mutex.rs | 0 .../proc-macro/pub-at-crate-root.rs | 0 .../proc-macro/shadow-builtin.rs | 0 .../proc-macro/shadow.rs | 0 .../proc-macro/two-crate-types-1.rs | 0 .../proc-macro/two-crate-types-2.rs | 0 .../auxiliary/incremental_proc_macro_aux.rs | 0 .../incremental_proc_macro.rs | 0 .../auxiliary/cond_plugin.rs | 0 .../auxiliary/hello_macro.rs | 0 .../auxiliary/proc_macro_def.rs | 0 .../{run-pass-fulldeps => run-pass}/macro-quote-cond.rs | 0 .../{run-pass-fulldeps => run-pass}/macro-quote-test.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/add-impl.rs | 0 .../proc-macro/append-impl.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/attr-args.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/attr-cfg.rs | 0 .../proc-macro/attr-on-trait.rs | 0 .../proc-macro/auxiliary/add-impl.rs | 0 .../proc-macro/auxiliary/append-impl.rs | 0 .../proc-macro/auxiliary/attr-args.rs | 0 .../proc-macro/auxiliary/attr-cfg.rs | 0 .../proc-macro/auxiliary/attr-on-trait.rs | 0 .../proc-macro/auxiliary/bang-macro.rs | 0 .../proc-macro/auxiliary/count_compound_ops.rs | 0 .../proc-macro/auxiliary/derive-a.rs | 0 .../proc-macro/auxiliary/derive-atob.rs | 0 .../proc-macro/auxiliary/derive-attr-cfg.rs | 0 .../proc-macro/auxiliary/derive-b.rs | 0 .../proc-macro/auxiliary/derive-ctod.rs | 0 .../proc-macro/auxiliary/derive-nothing.rs | 0 .../proc-macro/auxiliary/derive-reexport.rs | 0 .../proc-macro/auxiliary/derive-same-struct.rs | 0 .../proc-macro/auxiliary/double.rs | 0 .../proc-macro/auxiliary/empty-crate.rs | 0 .../proc-macro/auxiliary/expand-with-a-macro.rs | 0 .../proc-macro/auxiliary/hygiene_example.rs | 0 .../proc-macro/auxiliary/hygiene_example_codegen.rs | 0 .../proc-macro/auxiliary/issue-39889.rs | 0 .../proc-macro/auxiliary/issue-42708.rs | 0 .../proc-macro/auxiliary/span-api-tests.rs | 0 .../proc-macro/auxiliary/span-test-macros.rs | 0 .../proc-macro/bang-macro.rs | 0 .../proc-macro/count_compound_ops.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/crate-var.rs | 0 .../proc-macro/derive-attr-cfg.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/derive-b.rs | 0 .../proc-macro/derive-same-struct.rs | 0 .../proc-macro/derive-test.rs | 0 .../proc-macro/empty-crate.rs | 0 .../proc-macro/expand-with-a-macro.rs | 0 .../proc-macro/hygiene_example.rs | 0 .../proc-macro/issue-39889.rs | 0 .../proc-macro/issue-42708.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/load-two.rs | 0 .../{run-pass-fulldeps => run-pass}/proc-macro/smoke.rs | 0 .../proc-macro/span-api-tests.rs | 0 .../proc-macro/struct-field-macro.rs | 0 .../proc-macro/use-reexport.rs | 0 src/test/{run-pass-fulldeps => run-pass}/proc_macro.rs | 0 .../{ui-fulldeps => ui}/custom-derive/auxiliary/plugin.rs | 0 src/test/{ui-fulldeps => ui}/custom-derive/issue-36935.rs | 0 .../{ui-fulldeps => ui}/custom-derive/issue-36935.stderr | 0 .../proc-macro}/auxiliary/attr_proc_macro.rs | 0 .../proc-macro}/auxiliary/bang_proc_macro.rs | 0 .../proc-macro}/auxiliary/derive-clona.rs | 0 .../{ui-fulldeps => ui/proc-macro}/auxiliary/derive-foo.rs | 0 .../proc-macro/auxiliary/derive-panic.rs | 0 .../proc-macro/auxiliary/parent-source-spans.rs | 0 .../proc-macro/auxiliary/three-equals.rs | 0 src/test/{ui-fulldeps => ui}/proc-macro/load-panic.rs | 0 src/test/{ui-fulldeps => ui}/proc-macro/load-panic.stderr | 0 .../{ui-fulldeps => ui}/proc-macro/parent-source-spans.rs | 0 .../proc-macro/parent-source-spans.stderr | 0 src/test/{ui-fulldeps => ui/proc-macro}/resolve-error.rs | 0 .../{ui-fulldeps => ui/proc-macro}/resolve-error.stderr | 0 src/test/{ui-fulldeps => ui}/proc-macro/signature.rs | 0 src/test/{ui-fulldeps => ui}/proc-macro/signature.stderr | 0 src/test/{ui-fulldeps => ui}/proc-macro/three-equals.rs | 0 src/test/{ui-fulldeps => ui}/proc-macro/three-equals.stderr | 0 119 files changed, 1 insertion(+), 7 deletions(-) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/attribute-with-error.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/attribute.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/attributes-included.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/attr_proc_macro.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/attribute-with-error.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/attributes-included.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/bang_proc_macro.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/bang_proc_macro2.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-a-b.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-a.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-b.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-bad.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-clona.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-foo.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-unstable-2.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/derive-unstable.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/issue-41211.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/auxiliary/issue_38586.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/define-two.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/derive-bad.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/derive-still-gated.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/expand-to-unstable-2.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/expand-to-unstable.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/export-macro.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/exports.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/feature-gate-proc_macro.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/illegal-proc-macro-derive-use.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/import.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/issue-37788.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/issue-38586.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/issue-41211.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/item-error.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/lints_in_proc_macros.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/macro-use-attr.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/macro-use-bang.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/no-macro-use-attr.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/proc-macro-attributes.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/proc-macro-custom-attr-mutex.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/pub-at-crate-root.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/shadow-builtin.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/shadow.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/two-crate-types-1.rs (100%) rename src/test/{compile-fail-fulldeps => compile-fail}/proc-macro/two-crate-types-2.rs (100%) rename src/test/{incremental-fulldeps => incremental}/auxiliary/incremental_proc_macro_aux.rs (100%) rename src/test/{incremental-fulldeps => incremental}/incremental_proc_macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/auxiliary/cond_plugin.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/auxiliary/hello_macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/auxiliary/proc_macro_def.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/macro-quote-cond.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/macro-quote-test.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/add-impl.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/append-impl.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/attr-args.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/attr-cfg.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/attr-on-trait.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/add-impl.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/append-impl.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/attr-args.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/attr-cfg.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/attr-on-trait.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/bang-macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/count_compound_ops.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-a.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-atob.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-attr-cfg.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-b.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-ctod.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-nothing.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-reexport.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/derive-same-struct.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/double.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/empty-crate.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/expand-with-a-macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/hygiene_example.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/hygiene_example_codegen.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/issue-39889.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/issue-42708.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/span-api-tests.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/auxiliary/span-test-macros.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/bang-macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/count_compound_ops.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/crate-var.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/derive-attr-cfg.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/derive-b.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/derive-same-struct.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/derive-test.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/empty-crate.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/expand-with-a-macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/hygiene_example.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/issue-39889.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/issue-42708.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/load-two.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/smoke.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/span-api-tests.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/struct-field-macro.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc-macro/use-reexport.rs (100%) rename src/test/{run-pass-fulldeps => run-pass}/proc_macro.rs (100%) rename src/test/{ui-fulldeps => ui}/custom-derive/auxiliary/plugin.rs (100%) rename src/test/{ui-fulldeps => ui}/custom-derive/issue-36935.rs (100%) rename src/test/{ui-fulldeps => ui}/custom-derive/issue-36935.stderr (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/auxiliary/attr_proc_macro.rs (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/auxiliary/bang_proc_macro.rs (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/auxiliary/derive-clona.rs (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/auxiliary/derive-foo.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/auxiliary/derive-panic.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/auxiliary/parent-source-spans.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/auxiliary/three-equals.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/load-panic.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/load-panic.stderr (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/parent-source-spans.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/parent-source-spans.stderr (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/resolve-error.rs (100%) rename src/test/{ui-fulldeps => ui/proc-macro}/resolve-error.stderr (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/signature.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/signature.stderr (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/three-equals.rs (100%) rename src/test/{ui-fulldeps => ui}/proc-macro/three-equals.stderr (100%) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437eef..4006ad17e2016 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -306,7 +306,7 @@ impl<'a> Builder<'a> { test::CompileFail, test::ParseFail, test::RunFail, test::RunPassValgrind, test::MirOpt, test::Codegen, test::CodegenUnits, test::Incremental, test::Debuginfo, test::UiFullDeps, test::RunPassFullDeps, test::RunFailFullDeps, - test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty, + test::CompileFailFullDeps, test::Rustdoc, test::Pretty, test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake, test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de938ec8e8306..193b3e6712438 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -704,12 +704,6 @@ host_test!(CompileFailFullDeps { suite: "compile-fail-fulldeps" }); -host_test!(IncrementalFullDeps { - path: "src/test/incremental-fulldeps", - mode: "incremental", - suite: "incremental-fulldeps" -}); - host_test!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs b/src/test/compile-fail/proc-macro/attribute-with-error.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs rename to src/test/compile-fail/proc-macro/attribute-with-error.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs b/src/test/compile-fail/proc-macro/attribute.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/attribute.rs rename to src/test/compile-fail/proc-macro/attribute.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs b/src/test/compile-fail/proc-macro/attributes-included.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/attributes-included.rs rename to src/test/compile-fail/proc-macro/attributes-included.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attr_proc_macro.rs b/src/test/compile-fail/proc-macro/auxiliary/attr_proc_macro.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attr_proc_macro.rs rename to src/test/compile-fail/proc-macro/auxiliary/attr_proc_macro.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attribute-with-error.rs b/src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attribute-with-error.rs rename to src/test/compile-fail/proc-macro/auxiliary/attribute-with-error.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs b/src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/attributes-included.rs rename to src/test/compile-fail/proc-macro/auxiliary/attributes-included.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs b/src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs rename to src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro2.rs b/src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro2.rs rename to src/test/compile-fail/proc-macro/auxiliary/bang_proc_macro2.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-b.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-a-b.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-a.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-a.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-b.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-b.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-b.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-bad.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-clona.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-clona.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-clona.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-foo.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-foo.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-foo.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-unstable-2.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs b/src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs rename to src/test/compile-fail/proc-macro/auxiliary/derive-unstable.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs b/src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs rename to src/test/compile-fail/proc-macro/auxiliary/issue-41211.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_38586.rs b/src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue_38586.rs rename to src/test/compile-fail/proc-macro/auxiliary/issue_38586.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs b/src/test/compile-fail/proc-macro/define-two.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/define-two.rs rename to src/test/compile-fail/proc-macro/define-two.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail/proc-macro/derive-bad.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs rename to src/test/compile-fail/proc-macro/derive-bad.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs b/src/test/compile-fail/proc-macro/derive-still-gated.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs rename to src/test/compile-fail/proc-macro/derive-still-gated.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail/proc-macro/expand-to-unstable-2.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs rename to src/test/compile-fail/proc-macro/expand-to-unstable-2.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail/proc-macro/expand-to-unstable.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs rename to src/test/compile-fail/proc-macro/expand-to-unstable.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs b/src/test/compile-fail/proc-macro/export-macro.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/export-macro.rs rename to src/test/compile-fail/proc-macro/export-macro.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/exports.rs b/src/test/compile-fail/proc-macro/exports.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/exports.rs rename to src/test/compile-fail/proc-macro/exports.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs b/src/test/compile-fail/proc-macro/feature-gate-proc_macro.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs rename to src/test/compile-fail/proc-macro/feature-gate-proc_macro.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs b/src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/illegal-proc-macro-derive-use.rs rename to src/test/compile-fail/proc-macro/illegal-proc-macro-derive-use.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/import.rs b/src/test/compile-fail/proc-macro/import.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/import.rs rename to src/test/compile-fail/proc-macro/import.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs b/src/test/compile-fail/proc-macro/issue-37788.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/issue-37788.rs rename to src/test/compile-fail/proc-macro/issue-37788.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs b/src/test/compile-fail/proc-macro/issue-38586.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/issue-38586.rs rename to src/test/compile-fail/proc-macro/issue-38586.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs b/src/test/compile-fail/proc-macro/issue-41211.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs rename to src/test/compile-fail/proc-macro/issue-41211.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/item-error.rs b/src/test/compile-fail/proc-macro/item-error.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/item-error.rs rename to src/test/compile-fail/proc-macro/item-error.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail/proc-macro/lints_in_proc_macros.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs rename to src/test/compile-fail/proc-macro/lints_in_proc_macros.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/macro-use-attr.rs b/src/test/compile-fail/proc-macro/macro-use-attr.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/macro-use-attr.rs rename to src/test/compile-fail/proc-macro/macro-use-attr.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs b/src/test/compile-fail/proc-macro/macro-use-bang.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs rename to src/test/compile-fail/proc-macro/macro-use-bang.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/no-macro-use-attr.rs b/src/test/compile-fail/proc-macro/no-macro-use-attr.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/no-macro-use-attr.rs rename to src/test/compile-fail/proc-macro/no-macro-use-attr.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs b/src/test/compile-fail/proc-macro/proc-macro-attributes.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs rename to src/test/compile-fail/proc-macro/proc-macro-attributes.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-custom-attr-mutex.rs b/src/test/compile-fail/proc-macro/proc-macro-custom-attr-mutex.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-custom-attr-mutex.rs rename to src/test/compile-fail/proc-macro/proc-macro-custom-attr-mutex.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs b/src/test/compile-fail/proc-macro/pub-at-crate-root.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/pub-at-crate-root.rs rename to src/test/compile-fail/proc-macro/pub-at-crate-root.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs b/src/test/compile-fail/proc-macro/shadow-builtin.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs rename to src/test/compile-fail/proc-macro/shadow-builtin.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow.rs b/src/test/compile-fail/proc-macro/shadow.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/shadow.rs rename to src/test/compile-fail/proc-macro/shadow.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs b/src/test/compile-fail/proc-macro/two-crate-types-1.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs rename to src/test/compile-fail/proc-macro/two-crate-types-1.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs b/src/test/compile-fail/proc-macro/two-crate-types-2.rs similarity index 100% rename from src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs rename to src/test/compile-fail/proc-macro/two-crate-types-2.rs diff --git a/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs b/src/test/incremental/auxiliary/incremental_proc_macro_aux.rs similarity index 100% rename from src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs rename to src/test/incremental/auxiliary/incremental_proc_macro_aux.rs diff --git a/src/test/incremental-fulldeps/incremental_proc_macro.rs b/src/test/incremental/incremental_proc_macro.rs similarity index 100% rename from src/test/incremental-fulldeps/incremental_proc_macro.rs rename to src/test/incremental/incremental_proc_macro.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass/auxiliary/cond_plugin.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs rename to src/test/run-pass/auxiliary/cond_plugin.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs b/src/test/run-pass/auxiliary/hello_macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/hello_macro.rs rename to src/test/run-pass/auxiliary/hello_macro.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass/auxiliary/proc_macro_def.rs similarity index 100% rename from src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs rename to src/test/run-pass/auxiliary/proc_macro_def.rs diff --git a/src/test/run-pass-fulldeps/macro-quote-cond.rs b/src/test/run-pass/macro-quote-cond.rs similarity index 100% rename from src/test/run-pass-fulldeps/macro-quote-cond.rs rename to src/test/run-pass/macro-quote-cond.rs diff --git a/src/test/run-pass-fulldeps/macro-quote-test.rs b/src/test/run-pass/macro-quote-test.rs similarity index 100% rename from src/test/run-pass-fulldeps/macro-quote-test.rs rename to src/test/run-pass/macro-quote-test.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass/proc-macro/add-impl.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/add-impl.rs rename to src/test/run-pass/proc-macro/add-impl.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass/proc-macro/append-impl.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/append-impl.rs rename to src/test/run-pass/proc-macro/append-impl.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-args.rs b/src/test/run-pass/proc-macro/attr-args.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/attr-args.rs rename to src/test/run-pass/proc-macro/attr-args.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs b/src/test/run-pass/proc-macro/attr-cfg.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs rename to src/test/run-pass/proc-macro/attr-cfg.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs b/src/test/run-pass/proc-macro/attr-on-trait.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/attr-on-trait.rs rename to src/test/run-pass/proc-macro/attr-on-trait.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass/proc-macro/auxiliary/add-impl.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs rename to src/test/run-pass/proc-macro/auxiliary/add-impl.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass/proc-macro/auxiliary/append-impl.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs rename to src/test/run-pass/proc-macro/auxiliary/append-impl.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-args.rs b/src/test/run-pass/proc-macro/auxiliary/attr-args.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-args.rs rename to src/test/run-pass/proc-macro/auxiliary/attr-args.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs rename to src/test/run-pass/proc-macro/auxiliary/attr-cfg.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-on-trait.rs b/src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-on-trait.rs rename to src/test/run-pass/proc-macro/auxiliary/attr-on-trait.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs b/src/test/run-pass/proc-macro/auxiliary/bang-macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs rename to src/test/run-pass/proc-macro/auxiliary/bang-macro.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs b/src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs rename to src/test/run-pass/proc-macro/auxiliary/count_compound_ops.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass/proc-macro/auxiliary/derive-a.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-a.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs b/src/test/run-pass/proc-macro/auxiliary/derive-atob.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-atob.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-attr-cfg.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs b/src/test/run-pass/proc-macro/auxiliary/derive-b.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-b.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-b.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-ctod.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs b/src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-nothing.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-nothing.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs b/src/test/run-pass/proc-macro/auxiliary/derive-reexport.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-reexport.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-reexport.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs rename to src/test/run-pass/proc-macro/auxiliary/derive-same-struct.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs b/src/test/run-pass/proc-macro/auxiliary/double.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs rename to src/test/run-pass/proc-macro/auxiliary/double.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs b/src/test/run-pass/proc-macro/auxiliary/empty-crate.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/empty-crate.rs rename to src/test/run-pass/proc-macro/auxiliary/empty-crate.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs rename to src/test/run-pass/proc-macro/auxiliary/expand-with-a-macro.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example.rs rename to src/test/run-pass/proc-macro/auxiliary/hygiene_example.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs rename to src/test/run-pass/proc-macro/auxiliary/hygiene_example_codegen.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-39889.rs b/src/test/run-pass/proc-macro/auxiliary/issue-39889.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-39889.rs rename to src/test/run-pass/proc-macro/auxiliary/issue-39889.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs b/src/test/run-pass/proc-macro/auxiliary/issue-42708.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-42708.rs rename to src/test/run-pass/proc-macro/auxiliary/issue-42708.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/span-api-tests.rs b/src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/span-api-tests.rs rename to src/test/run-pass/proc-macro/auxiliary/span-api-tests.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/span-test-macros.rs b/src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/auxiliary/span-test-macros.rs rename to src/test/run-pass/proc-macro/auxiliary/span-test-macros.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs b/src/test/run-pass/proc-macro/bang-macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/bang-macro.rs rename to src/test/run-pass/proc-macro/bang-macro.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs b/src/test/run-pass/proc-macro/count_compound_ops.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/count_compound_ops.rs rename to src/test/run-pass/proc-macro/count_compound_ops.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass/proc-macro/crate-var.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/crate-var.rs rename to src/test/run-pass/proc-macro/crate-var.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs b/src/test/run-pass/proc-macro/derive-attr-cfg.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs rename to src/test/run-pass/proc-macro/derive-attr-cfg.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs b/src/test/run-pass/proc-macro/derive-b.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/derive-b.rs rename to src/test/run-pass/proc-macro/derive-b.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass/proc-macro/derive-same-struct.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs rename to src/test/run-pass/proc-macro/derive-same-struct.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-test.rs b/src/test/run-pass/proc-macro/derive-test.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/derive-test.rs rename to src/test/run-pass/proc-macro/derive-test.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/empty-crate.rs b/src/test/run-pass/proc-macro/empty-crate.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/empty-crate.rs rename to src/test/run-pass/proc-macro/empty-crate.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs b/src/test/run-pass/proc-macro/expand-with-a-macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs rename to src/test/run-pass/proc-macro/expand-with-a-macro.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs b/src/test/run-pass/proc-macro/hygiene_example.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs rename to src/test/run-pass/proc-macro/hygiene_example.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-39889.rs b/src/test/run-pass/proc-macro/issue-39889.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/issue-39889.rs rename to src/test/run-pass/proc-macro/issue-39889.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/issue-42708.rs b/src/test/run-pass/proc-macro/issue-42708.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/issue-42708.rs rename to src/test/run-pass/proc-macro/issue-42708.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass/proc-macro/load-two.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/load-two.rs rename to src/test/run-pass/proc-macro/load-two.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/smoke.rs b/src/test/run-pass/proc-macro/smoke.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/smoke.rs rename to src/test/run-pass/proc-macro/smoke.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/span-api-tests.rs b/src/test/run-pass/proc-macro/span-api-tests.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/span-api-tests.rs rename to src/test/run-pass/proc-macro/span-api-tests.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs b/src/test/run-pass/proc-macro/struct-field-macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/struct-field-macro.rs rename to src/test/run-pass/proc-macro/struct-field-macro.rs diff --git a/src/test/run-pass-fulldeps/proc-macro/use-reexport.rs b/src/test/run-pass/proc-macro/use-reexport.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc-macro/use-reexport.rs rename to src/test/run-pass/proc-macro/use-reexport.rs diff --git a/src/test/run-pass-fulldeps/proc_macro.rs b/src/test/run-pass/proc_macro.rs similarity index 100% rename from src/test/run-pass-fulldeps/proc_macro.rs rename to src/test/run-pass/proc_macro.rs diff --git a/src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs b/src/test/ui/custom-derive/auxiliary/plugin.rs similarity index 100% rename from src/test/ui-fulldeps/custom-derive/auxiliary/plugin.rs rename to src/test/ui/custom-derive/auxiliary/plugin.rs diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.rs b/src/test/ui/custom-derive/issue-36935.rs similarity index 100% rename from src/test/ui-fulldeps/custom-derive/issue-36935.rs rename to src/test/ui/custom-derive/issue-36935.rs diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui/custom-derive/issue-36935.stderr similarity index 100% rename from src/test/ui-fulldeps/custom-derive/issue-36935.stderr rename to src/test/ui/custom-derive/issue-36935.stderr diff --git a/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs rename to src/test/ui/proc-macro/auxiliary/attr_proc_macro.rs diff --git a/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs b/src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs rename to src/test/ui/proc-macro/auxiliary/bang_proc_macro.rs diff --git a/src/test/ui-fulldeps/auxiliary/derive-clona.rs b/src/test/ui/proc-macro/auxiliary/derive-clona.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/derive-clona.rs rename to src/test/ui/proc-macro/auxiliary/derive-clona.rs diff --git a/src/test/ui-fulldeps/auxiliary/derive-foo.rs b/src/test/ui/proc-macro/auxiliary/derive-foo.rs similarity index 100% rename from src/test/ui-fulldeps/auxiliary/derive-foo.rs rename to src/test/ui/proc-macro/auxiliary/derive-foo.rs diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/derive-panic.rs b/src/test/ui/proc-macro/auxiliary/derive-panic.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/auxiliary/derive-panic.rs rename to src/test/ui/proc-macro/auxiliary/derive-panic.rs diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs b/src/test/ui/proc-macro/auxiliary/parent-source-spans.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs rename to src/test/ui/proc-macro/auxiliary/parent-source-spans.rs diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs b/src/test/ui/proc-macro/auxiliary/three-equals.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs rename to src/test/ui/proc-macro/auxiliary/three-equals.rs diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.rs b/src/test/ui/proc-macro/load-panic.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/load-panic.rs rename to src/test/ui/proc-macro/load-panic.rs diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui/proc-macro/load-panic.stderr similarity index 100% rename from src/test/ui-fulldeps/proc-macro/load-panic.stderr rename to src/test/ui/proc-macro/load-panic.stderr diff --git a/src/test/ui-fulldeps/proc-macro/parent-source-spans.rs b/src/test/ui/proc-macro/parent-source-spans.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/parent-source-spans.rs rename to src/test/ui/proc-macro/parent-source-spans.rs diff --git a/src/test/ui-fulldeps/proc-macro/parent-source-spans.stderr b/src/test/ui/proc-macro/parent-source-spans.stderr similarity index 100% rename from src/test/ui-fulldeps/proc-macro/parent-source-spans.stderr rename to src/test/ui/proc-macro/parent-source-spans.stderr diff --git a/src/test/ui-fulldeps/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs similarity index 100% rename from src/test/ui-fulldeps/resolve-error.rs rename to src/test/ui/proc-macro/resolve-error.rs diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr similarity index 100% rename from src/test/ui-fulldeps/resolve-error.stderr rename to src/test/ui/proc-macro/resolve-error.stderr diff --git a/src/test/ui-fulldeps/proc-macro/signature.rs b/src/test/ui/proc-macro/signature.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/signature.rs rename to src/test/ui/proc-macro/signature.rs diff --git a/src/test/ui-fulldeps/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr similarity index 100% rename from src/test/ui-fulldeps/proc-macro/signature.stderr rename to src/test/ui/proc-macro/signature.stderr diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.rs b/src/test/ui/proc-macro/three-equals.rs similarity index 100% rename from src/test/ui-fulldeps/proc-macro/three-equals.rs rename to src/test/ui/proc-macro/three-equals.rs diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr similarity index 100% rename from src/test/ui-fulldeps/proc-macro/three-equals.stderr rename to src/test/ui/proc-macro/three-equals.stderr