diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index c0f7714ca211a..d408fef75153e 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -19,12 +19,15 @@ #![feature(nll)] #![feature(staged_api)] +#![feature(allow_internal_unstable)] #![feature(const_fn)] +#![feature(decl_macro)] #![feature(extern_types)] #![feature(in_band_lifetimes)] #![feature(optin_builtin_traits)] #![feature(mem_take)] #![feature(non_exhaustive)] +#![feature(rustc_attrs)] #![feature(specialization)] #![recursion_limit="256"] @@ -222,11 +225,10 @@ pub mod token_stream { /// /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term. /// To quote `$` itself, use `$$`. -/// -/// This is a dummy macro, the actual implementation is in `quote::quote`.` #[unstable(feature = "proc_macro_quote", issue = "54722")] -#[macro_export] -macro_rules! quote { () => {} } +#[allow_internal_unstable(proc_macro_def_site)] +#[cfg_attr(not(bootstrap), rustc_builtin_macro)] +pub macro quote ($($t:tt)*) { /* compiler built-in */ } #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index e3d31b78f4a09..144e2d6bac43b 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -57,9 +57,9 @@ macro_rules! quote { } /// Quote a `TokenStream` into a `TokenStream`. -/// This is the actual `quote!()` proc macro. +/// This is the actual implementation of the `quote!()` proc macro. /// -/// It is manually loaded in `CStore::load_macro_untracked`. +/// It is loaded by the compiler in `register_builtin_macros`. #[unstable(feature = "proc_macro_quote", issue = "54722")] pub fn quote(stream: TokenStream) -> TokenStream { if stream.is_empty() { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index efc77699313e0..5bf4067431f24 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -95,11 +95,6 @@ pub struct CrateMetadata { pub raw_proc_macros: Option<&'static [ProcMacro]>, } -pub struct FullProcMacro { - pub name: ast::Name, - pub ext: Lrc -} - pub struct CStore { metas: RwLock>>>, /// Map from NodeId's of local extern crate statements to crate numbers @@ -109,7 +104,7 @@ pub struct CStore { pub enum LoadedMacro { MacroDef(ast::Item), - ProcMacro(Lrc), + ProcMacro(SyntaxExtension), } impl CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 7aeeef00ea934..5bfb315da473f 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -30,11 +30,9 @@ use syntax::ast; use syntax::attr; use syntax::source_map; use syntax::edition::Edition; -use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; -use syntax::ext::proc_macro::BangProcMacro; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::Symbol; use syntax_pos::{Span, FileName}; use rustc_data_structures::bit_set::BitSet; @@ -436,15 +434,7 @@ impl cstore::CStore { pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { let data = self.get_crate_data(id.krate); if data.is_proc_macro_crate() { - return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext); - } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote { - let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })); - let ext = SyntaxExtension { - allow_internal_unstable: Some([sym::proc_macro_def_site][..].into()), - ..SyntaxExtension::default(kind, data.root.edition) - }; - return LoadedMacro::ProcMacro(Lrc::new(ext)); + return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess)); } let def = data.get_macro(id.index); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 5b9cb966af235..c777b5ea409a4 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1,6 +1,6 @@ // Decoding metadata from a single crate's metadata -use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro}; +use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; use crate::schema::*; use rustc_data_structures::indexed_vec::IndexVec; @@ -512,27 +512,8 @@ impl<'a, 'tcx> CrateMetadata { self.entry(index).span.decode((self, sess)) } - - pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro { - if sess.opts.debugging_opts.dual_proc_macros { - let host_lib = self.host_lib.as_ref().unwrap(); - self.load_proc_macro( - &host_lib.metadata.get_root(), - id, - sess - ) - } else { - self.load_proc_macro(&self.root, id, sess) - } - } - - fn load_proc_macro(&self, root: &CrateRoot<'_>, - id: DefIndex, - sess: &Session) - -> FullProcMacro { - - let raw_macro = self.raw_proc_macro(id); - let (name, kind, helper_attrs) = match *raw_macro { + crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension { + let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) { ProcMacro::CustomDerive { trait_name, attributes, client } => { let helper_attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); @@ -551,17 +532,21 @@ impl<'a, 'tcx> CrateMetadata { name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new() ) }; + let edition = if sess.opts.debugging_opts.dual_proc_macros { + self.host_lib.as_ref().unwrap().metadata.get_root().edition + } else { + self.root.edition + }; - let span = self.get_span(id, sess); - - FullProcMacro { - name: Symbol::intern(name), - ext: Lrc::new(SyntaxExtension { - span, - helper_attrs, - ..SyntaxExtension::default(kind, root.edition) - }) - } + SyntaxExtension::new( + &sess.parse_sess, + kind, + self.get_span(id, sess), + helper_attrs, + edition, + Symbol::intern(name), + &self.get_attributes(&self.entry(id), sess), + ) } pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9a794ade729c2..165a4c707bb6d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -150,12 +150,12 @@ impl<'a> Resolver<'a> { return Some(ext.clone()); } - let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) { - LoadedMacro::MacroDef(macro_def) => macro_def, - LoadedMacro::ProcMacro(ext) => return Some(ext), - }; + let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) { + LoadedMacro::MacroDef(item) => + self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)), + LoadedMacro::ProcMacro(ext) => ext, + }); - let ext = self.compile_macro(¯o_def, self.cstore.crate_edition_untracked(def_id.krate)); self.macro_map.insert(def_id, ext.clone()); Some(ext) } @@ -1104,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let expansion = parent_scope.expansion; let (ext, ident, span, is_legacy) = match &item.node { ItemKind::MacroDef(def) => { - let ext = self.r.compile_macro(item, self.r.session.edition()); + let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition())); (ext, item.ident, item.span, def.legacy) } ItemKind::Fn(..) => match Self::proc_macro_stub(item) { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 719167eb057b2..cc78e928380a8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -800,7 +800,7 @@ impl<'a> Resolver<'a> { /// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined /// extension partially or entirely for built-in macros and legacy plugin macros. - crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> Lrc { + crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension { let mut result = macro_rules::compile( &self.session.parse_sess, self.session.features_untracked(), item, edition ); @@ -822,6 +822,6 @@ impl<'a> Resolver<'a> { } } - Lrc::new(result) + result } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a63c4181d5e03..10ff1b17285fe 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,11 +1,11 @@ use crate::ast::{self, NodeId, Attribute, Name, PatKind}; -use crate::attr::{HasAttrs, Stability, Deprecation}; +use crate::attr::{self, HasAttrs, Stability, Deprecation}; use crate::source_map::SourceMap; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; use crate::ext::hygiene::{ExpnId, Transparency}; use crate::mut_visit::{self, MutVisitor}; -use crate::parse::{self, parser, DirectoryOwnership}; +use crate::parse::{self, parser, ParseSess, DirectoryOwnership}; use crate::parse::token; use crate::ptr::P; use crate::symbol::{kw, sym, Ident, Symbol}; @@ -601,6 +601,69 @@ impl SyntaxExtension { } } + /// Constructs a syntax extension with the given properties + /// and other properties converted from attributes. + pub fn new( + sess: &ParseSess, + kind: SyntaxExtensionKind, + span: Span, + helper_attrs: Vec, + edition: Edition, + name: Name, + attrs: &[ast::Attribute], + ) -> SyntaxExtension { + let allow_internal_unstable = + attr::find_by_name(attrs, sym::allow_internal_unstable).map(|attr| { + attr.meta_item_list() + .map(|list| { + list.iter() + .filter_map(|it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.span_diagnostic.span_err( + it.span(), "allow internal unstable expects feature names" + ) + } + name + }) + .collect::>() + .into() + }) + .unwrap_or_else(|| { + sess.span_diagnostic.span_warn( + attr.span, + "allow_internal_unstable expects list of feature names. In the future \ + this will become a hard error. Please use `allow_internal_unstable(\ + foo, bar)` to only allow the `foo` and `bar` features", + ); + vec![sym::allow_internal_unstable_backcompat_hack].into() + }) + }); + + let mut local_inner_macros = false; + if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) { + if let Some(l) = macro_export.meta_item_list() { + local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); + } + } + + let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro); + + SyntaxExtension { + kind, + span, + allow_internal_unstable, + allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe), + local_inner_macros, + stability: attr::find_stability(&sess, attrs, span), + deprecation: attr::find_deprecation(&sess, attrs, span), + helper_attrs, + edition, + is_builtin, + is_derive_copy: is_builtin && name == sym::Copy, + } + } + pub fn dummy_bang(edition: Edition) -> SyntaxExtension { fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree]) -> Box { diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index b1bbd2aaac971..1a26b17dac782 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> { impl<'a> Rustc<'a> { pub fn new(cx: &'a ExtCtxt<'_>) -> Self { - // No way to determine def location for a proc macro right now, so use call location. - let location = cx.current_expansion.id.expn_data().call_site; + let expn_data = cx.current_expansion.id.expn_data(); Rustc { sess: cx.parse_sess, - def_site: cx.with_def_site_ctxt(location), - call_site: cx.with_call_site_ctxt(location), + def_site: cx.with_def_site_ctxt(expn_data.def_site), + call_site: cx.with_call_site_ctxt(expn_data.call_site), } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 37cb8467ff5ee..46ffa52f7f572 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1,3 +1,5 @@ +use crate::ast; +use crate::attr::{self, TransparencyError}; use crate::edition::Edition; use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind}; @@ -15,7 +17,6 @@ use crate::parse::token::{self, NtTT, Token}; use crate::parse::{Directory, ParseSess}; use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree}; -use crate::{ast, attr, attr::TransparencyError}; use errors::{DiagnosticBuilder, FatalError}; use log::debug; @@ -290,6 +291,7 @@ pub fn compile( def: &ast::Item, edition: Edition, ) -> SyntaxExtension { + let diag = &sess.span_diagnostic; let lhs_nm = ast::Ident::new(sym::lhs, def.span); let rhs_nm = ast::Ident::new(sym::rhs, def.span); let tt_spec = ast::Ident::new(sym::tt, def.span); @@ -423,13 +425,9 @@ pub fn compile( let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => - sess.span_diagnostic.span_err( - span, &format!("unknown macro transparency: `{}`", value) - ), + diag.span_err(span, &format!("unknown macro transparency: `{}`", value)), Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => - sess.span_diagnostic.span_err( - vec![old_span, new_span], "multiple macro transparency attributes" - ), + diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"), None => {} } @@ -437,57 +435,15 @@ pub fn compile( name: def.ident, span: def.span, transparency, lhses, rhses, valid }); - let allow_internal_unstable = - attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| { - attr.meta_item_list() - .map(|list| { - list.iter() - .filter_map(|it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.span_diagnostic.span_err( - it.span(), - "allow internal unstable expects feature names", - ) - } - name - }) - .collect::>() - .into() - }) - .unwrap_or_else(|| { - sess.span_diagnostic.span_warn( - attr.span, - "allow_internal_unstable expects list of feature names. In the \ - future this will become a hard error. Please use `allow_internal_unstable(\ - foo, bar)` to only allow the `foo` and `bar` features", - ); - vec![sym::allow_internal_unstable_backcompat_hack].into() - }) - }); - - let mut local_inner_macros = false; - if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } - - let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro); - - SyntaxExtension { - kind: SyntaxExtensionKind::LegacyBang(expander), - span: def.span, - allow_internal_unstable, - allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), - local_inner_macros, - stability: attr::find_stability(&sess, &def.attrs, def.span), - deprecation: attr::find_deprecation(&sess, &def.attrs, def.span), - helper_attrs: Vec::new(), + SyntaxExtension::new( + sess, + SyntaxExtensionKind::LegacyBang(expander), + def.span, + Vec::new(), edition, - is_builtin, - is_derive_copy: is_builtin && def.ident.name == sym::Copy, - } + def.ident.name, + &def.attrs, + ) } fn check_lhs_nt_follows( diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 25ad2d4404cac..2b20cb88796c3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -375,10 +375,11 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; } else if !parser.token.span.is_dummy() { - if let FileName::Real(mut path) = - sess.source_map().span_to_unmapped_path(parser.token.span) { - path.pop(); - parser.directory.path = Cow::from(path); + if let Some(FileName::Real(path)) = + &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path { + if let Some(directory_path) = path.parent() { + parser.directory.path = Cow::from(directory_path.to_path_buf()); + } } } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 4add2261c6cda..1a6176916623b 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -7,13 +7,18 @@ #![feature(decl_macro)] #![feature(mem_take)] #![feature(nll)] +#![feature(proc_macro_internals)] +#![feature(proc_macro_quote)] #![feature(rustc_diagnostic_macros)] +extern crate proc_macro; + use crate::deriving::*; use syntax::ast::Ident; use syntax::edition::Edition; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn}; +use syntax::ext::proc_macro::BangProcMacro; use syntax::symbol::sym; mod error_codes; @@ -100,4 +105,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e RustcDecodable: decodable::expand_deriving_rustc_decodable, RustcEncodable: encodable::expand_deriving_rustc_encodable, } + + let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); + register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }))); } diff --git a/src/test/ui/auxiliary/cond_plugin.rs b/src/test/ui/auxiliary/cond_plugin.rs index 1f97b556a0767..2819541bf6966 100644 --- a/src/test/ui/auxiliary/cond_plugin.rs +++ b/src/test/ui/auxiliary/cond_plugin.rs @@ -3,6 +3,7 @@ #![crate_type = "proc-macro"] #![feature(proc_macro_hygiene)] +#![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/src/test/ui/auxiliary/proc_macro_def.rs b/src/test/ui/auxiliary/proc_macro_def.rs index dfc5a42d19c69..49cfb5518ba9c 100644 --- a/src/test/ui/auxiliary/proc_macro_def.rs +++ b/src/test/ui/auxiliary/proc_macro_def.rs @@ -3,6 +3,7 @@ #![crate_type = "proc-macro"] #![feature(proc_macro_hygiene)] +#![feature(proc_macro_quote)] extern crate proc_macro; diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs index b50ed7ca92ad5..c460db36f1aa3 100644 --- a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs +++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs @@ -6,7 +6,7 @@ extern crate proc_macro; -use proc_macro::{quote, Span, TokenStream}; +use proc_macro::{quote, Span, TokenStream, TokenTree}; fn assert_same_span(a: Span, b: Span) { assert_eq!(a.start(), b.start()); @@ -24,12 +24,22 @@ pub fn make_foo(_: TokenStream) -> TokenStream { }; // Check that all spans are equal. - let mut span = None; + // FIXME: `quote!` gives def-site spans to idents and literals, + // but leaves (default) call-site spans on groups and punctuation. + let mut span_call = None; + let mut span_def = None; for tt in result.clone() { - match span { - None => span = Some(tt.span()), - Some(span) => assert_same_span(tt.span(), span), + match tt { + TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def { + None => span_def = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } + TokenTree::Punct(..) | TokenTree::Group(..) => match span_call { + None => span_call = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } } + } result diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr index 250773a1853ec..0eef4a2a678b6 100644 --- a/src/test/ui/macros/same-sequence-span.stderr +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -17,11 +17,15 @@ LL | $(= $z:tt)* error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | -LL | proc_macro_sequence::make_foo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | proc_macro_sequence::make_foo!(); + | ^-------------------------------- + | | + | _in this macro invocation | | - | not allowed after `expr` fragments - | in this macro invocation +LL | | +LL | | +LL | | fn main() {} +... | | = note: allowed there are: `=>`, `,` or `;` diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs new file mode 100644 index 0000000000000..055781d2c6048 --- /dev/null +++ b/src/test/ui/proc-macro/attributes-on-definitions.rs @@ -0,0 +1,12 @@ +// check-pass +// aux-build:attributes-on-definitions.rs + +#![forbid(unsafe_code)] + +extern crate attributes_on_definitions; + +attributes_on_definitions::with_attrs!(); +//~^ WARN use of deprecated item +// No errors about the use of unstable and unsafe code inside the macro. + +fn main() {} diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr new file mode 100644 index 0000000000000..c61e043b22971 --- /dev/null +++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr @@ -0,0 +1,8 @@ +warning: use of deprecated item 'attributes_on_definitions::with_attrs': test + --> $DIR/attributes-on-definitions.rs:8:1 + | +LL | attributes_on_definitions::with_attrs!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(deprecated)]` on by default + diff --git a/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs new file mode 100644 index 0000000000000..93a339840d621 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs @@ -0,0 +1,23 @@ +// force-host +// no-prefer-dynamic + +#![feature(allow_internal_unsafe)] +#![feature(allow_internal_unstable)] + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +#[allow_internal_unstable(proc_macro_internals)] +#[allow_internal_unsafe] +#[deprecated(since = "1.0.0", note = "test")] +pub fn with_attrs(_: TokenStream) -> TokenStream { + " + extern crate proc_macro; + use ::proc_macro::bridge; + + fn contains_unsafe() { unsafe {} } + ".parse().unwrap() +} diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr index a0c1f9cd5c05f..e7f705c7feb67 100644 --- a/src/test/ui/proc-macro/multispan.stderr +++ b/src/test/ui/proc-macro/multispan.stderr @@ -1,8 +1,19 @@ error: hello to you, too! - --> $DIR/multispan.rs:14:5 - | -LL | hello!(hi); - | ^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:14:5 + | +LL | hello!(hi); + | ----------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:14:12 @@ -11,10 +22,21 @@ LL | hello!(hi); | ^^ error: hello to you, too! - --> $DIR/multispan.rs:17:5 - | -LL | hello!(hi hi); - | ^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:17:5 + | +LL | hello!(hi hi); + | -------------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:17:12 @@ -23,10 +45,21 @@ LL | hello!(hi hi); | ^^ ^^ error: hello to you, too! - --> $DIR/multispan.rs:20:5 - | -LL | hello!(hi hi hi); - | ^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:20:5 + | +LL | hello!(hi hi hi); + | ----------------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:20:12 @@ -35,10 +68,21 @@ LL | hello!(hi hi hi); | ^^ ^^ ^^ error: hello to you, too! - --> $DIR/multispan.rs:23:5 - | -LL | hello!(hi hey hi yo hi beep beep hi hi); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:23:5 + | +LL | hello!(hi hey hi yo hi beep beep hi hi); + | ---------------------------------------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:23:12 @@ -47,10 +91,21 @@ LL | hello!(hi hey hi yo hi beep beep hi hi); | ^^ ^^ ^^ ^^ ^^ error: hello to you, too! - --> $DIR/multispan.rs:24:5 - | -LL | hello!(hi there, hi how are you? hi... hi.); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:24:5 + | +LL | hello!(hi there, hi how are you? hi... hi.); + | -------------------------------------------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:24:12 @@ -59,10 +114,21 @@ LL | hello!(hi there, hi how are you? hi... hi.); | ^^ ^^ ^^ ^^ error: hello to you, too! - --> $DIR/multispan.rs:25:5 - | -LL | hello!(whoah. hi di hi di ho); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:25:5 + | +LL | hello!(whoah. hi di hi di ho); + | ------------------------------ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:25:19 @@ -71,10 +137,21 @@ LL | hello!(whoah. hi di hi di ho); | ^^ ^^ error: hello to you, too! - --> $DIR/multispan.rs:26:5 - | -LL | hello!(hi good hi and good bye); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/multispan.rs:31:1 + | +LL | / pub fn hello(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | } +LL | | +LL | | TokenStream::new() +LL | | } + | |_^ + | + ::: $DIR/multispan.rs:26:5 + | +LL | hello!(hi good hi and good bye); + | -------------------------------- in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:26:12 diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr index 0a6cbe13098a8..0698b0f475424 100644 --- a/src/test/ui/proc-macro/three-equals.stderr +++ b/src/test/ui/proc-macro/three-equals.stderr @@ -1,8 +1,19 @@ error: found 2 equal signs, need exactly 3 - --> $DIR/three-equals.rs:15:5 - | -LL | three_equals!(==); - | ^^^^^^^^^^^^^^^^^^ in this macro invocation + --> $DIR/auxiliary/three-equals.rs:42:1 + | +LL | / pub fn three_equals(input: TokenStream) -> TokenStream { +LL | | if let Err(diag) = parse(input) { +LL | | diag.emit(); +LL | | return TokenStream::new(); +... | +LL | | "3".parse().unwrap() +LL | | } + | |_^ + | + ::: $DIR/three-equals.rs:15:5 + | +LL | three_equals!(==); + | ------------------ in this macro invocation | = help: input must be: `===`