diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index cb5e1e600d3d2..ea0b7ae5a1cbd 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -28,6 +28,18 @@ pub enum CtorKind { Fictive, } +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum NonMacroAttrKind { + /// Single-segment attribute defined by the language (`#[inline]`) + Builtin, + /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`). + Tool, + /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`). + DeriveHelper, + /// Single-segment custom attribute not registered in any way (`#[my_attr]`). + Custom, +} + #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Def { // Type namespace @@ -68,7 +80,7 @@ pub enum Def { // Macro namespace Macro(DefId, MacroKind), - NonMacroAttr, // e.g. `#[inline]` or `#[rustfmt::skip]` + NonMacroAttr(NonMacroAttrKind), // e.g. `#[inline]` or `#[rustfmt::skip]` GlobalAsm(DefId), @@ -242,6 +254,17 @@ impl CtorKind { } } +impl NonMacroAttrKind { + fn descr(self) -> &'static str { + match self { + NonMacroAttrKind::Builtin => "built-in attribute", + NonMacroAttrKind::Tool => "tool attribute", + NonMacroAttrKind::DeriveHelper => "derive helper attribute", + NonMacroAttrKind::Custom => "custom attribute", + } + } +} + impl Def { pub fn def_id(&self) -> DefId { match *self { @@ -262,7 +285,7 @@ impl Def { Def::PrimTy(..) | Def::SelfTy(..) | Def::ToolMod | - Def::NonMacroAttr | + Def::NonMacroAttr(..) | Def::Err => { bug!("attempted .def_id() on invalid def: {:?}", self) } @@ -304,7 +327,7 @@ impl Def { Def::Macro(.., macro_kind) => macro_kind.descr(), Def::GlobalAsm(..) => "global asm", Def::ToolMod => "tool module", - Def::NonMacroAttr => "non-macro attribute", + Def::NonMacroAttr(attr_kind) => attr_kind.descr(), Def::Err => "unresolved item", } } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index fe87053681ae8..4af68a499071f 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -988,6 +988,13 @@ impl_stable_hash_for!(enum hir::def::CtorKind { Fictive }); +impl_stable_hash_for!(enum hir::def::NonMacroAttrKind { + Builtin, + Tool, + DeriveHelper, + Custom, +}); + impl_stable_hash_for!(enum hir::def::Def { Mod(def_id), Struct(def_id), @@ -1017,7 +1024,7 @@ impl_stable_hash_for!(enum hir::def::Def { Macro(def_id, macro_kind), GlobalAsm(def_id), ToolMod, - NonMacroAttr, + NonMacroAttr(attr_kind), Err }); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c782f2072b9aa..0be1bf3011e78 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -630,8 +630,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { pub fn get_macro(&mut self, def: Def) -> Lrc { let def_id = match def { Def::Macro(def_id, ..) => def_id, - Def::NonMacroAttr => return Lrc::new(SyntaxExtension::NonMacroAttr), - _ => panic!("Expected Def::Macro(..) or Def::NonMacroAttr"), + Def::NonMacroAttr(attr_kind) => return Lrc::new(SyntaxExtension::NonMacroAttr { + mark_used: attr_kind == NonMacroAttrKind::Tool, + }), + _ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"), }; if let Some(ext) = self.macro_map.get(&def_id) { return ext.clone(); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a7fcc89f6b974..d96967725f45e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3485,8 +3485,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let binding = if let Some(module) = module { self.resolve_ident_in_module(module, ident, ns, record_used, path_span) } else if opt_ns == Some(MacroNS) { - self.resolve_lexical_macro_path_segment(ident, ns, record_used, path_span) - .map(MacroBinding::binding) + assert!(ns == TypeNS); + self.resolve_lexical_macro_path_segment(ident, ns, record_used, record_used, + false, path_span).map(MacroBinding::binding) } else { let record_used_id = if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None }; @@ -3514,7 +3515,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { if let Some(next_module) = binding.module() { module = Some(next_module); } else if def == Def::ToolMod && i + 1 != path.len() { - return PathResult::NonModule(PathResolution::new(Def::NonMacroAttr)) + let def = Def::NonMacroAttr(NonMacroAttrKind::Tool); + return PathResult::NonModule(PathResolution::new(def)); } else if def == Def::Err { return PathResult::NonModule(err_path_resolution()); } else if opt_ns.is_some() && (is_last || maybe_assoc) { @@ -4548,6 +4550,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let result = self.resolve_lexical_macro_path_segment(ident, MacroNS, false, + false, + true, attr.path.span); if let Ok(binding) = result { if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 993874d7c0be8..d680b2d9f7d74 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -15,18 +15,17 @@ use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; use resolve_imports::ImportResolver; use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace}; -use rustc::hir::def::{Def, Export}; +use rustc::hir::def::{Def, Export, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; use rustc::{ty, lint}; use rustc::middle::cstore::CrateStore; use syntax::ast::{self, Name, Ident}; -use syntax::attr::{self, HasAttrs}; +use syntax::attr; use syntax::errors::DiagnosticBuilder; -use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator}; +use syntax::ext::base::{self, Determinacy, MultiModifier, MultiDecorator}; use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver}; -use syntax::ext::expand::{self, AstFragment, AstFragmentKind, Invocation, InvocationKind}; +use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, Mark}; -use syntax::ext::placeholders::placeholder; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{self, feature_err, emit_feature_err, is_builtin_attr_name, GateIssue}; use syntax::fold::{self, Folder}; @@ -320,7 +319,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { None } - fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) + fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool) -> Result>, Determinacy> { let def = match invoc.kind { InvocationKind::Attr { attr: None, .. } => return Ok(None), @@ -329,17 +328,37 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { if let Def::Macro(_, MacroKind::ProcMacroStub) = def { self.report_proc_macro_stub(invoc.span()); return Err(Determinacy::Determined); - } else if let Def::NonMacroAttr = def { - if let InvocationKind::Attr { .. } = invoc.kind { - if !self.session.features_untracked().tool_attributes { - feature_err(&self.session.parse_sess, "tool_attributes", - invoc.span(), GateIssue::Language, - "tool attributes are unstable").emit(); + } else if let Def::NonMacroAttr(attr_kind) = def { + // Note that not only attributes, but anything in macro namespace can result in a + // `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report the error + // below for these cases. + let is_attr_invoc = + if let InvocationKind::Attr { .. } = invoc.kind { true } else { false }; + let path = invoc.path().expect("no path for non-macro attr"); + match attr_kind { + NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper | + NonMacroAttrKind::Custom if is_attr_invoc => { + if attr_kind == NonMacroAttrKind::Tool && + !self.session.features_untracked().tool_attributes { + feature_err(&self.session.parse_sess, "tool_attributes", + invoc.span(), GateIssue::Language, + "tool attributes are unstable").emit(); + } + if attr_kind == NonMacroAttrKind::Custom && + !self.session.features_untracked().custom_attribute { + let msg = format!("The attribute `{}` is currently unknown to the compiler \ + and may have meaning added to it in the future", path); + feature_err(&self.session.parse_sess, "custom_attribute", invoc.span(), + GateIssue::Language, &msg).emit(); + } + return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr { + mark_used: attr_kind == NonMacroAttrKind::Tool, + }))); + } + _ => { + self.report_non_macro_attr(path.span, def); + return Err(Determinacy::Determined); } - return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr))); - } else { - self.report_non_macro_attr(invoc.path_span()); - return Err(Determinacy::Determined); } } let def_id = def.def_id(); @@ -363,8 +382,8 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { if let Def::Macro(_, MacroKind::ProcMacroStub) = def { self.report_proc_macro_stub(path.span); return Err(Determinacy::Determined); - } else if let Def::NonMacroAttr = def { - self.report_non_macro_attr(path.span); + } else if let Def::NonMacroAttr(..) = def { + self.report_non_macro_attr(path.span, def); return Err(Determinacy::Determined); } self.unused_macros.remove(&def.def_id()); @@ -396,15 +415,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> { "can't use a procedural macro from the same crate that defines it"); } - fn report_non_macro_attr(&self, span: Span) { - self.session.span_err(span, - "expected a macro, found non-macro attribute"); + fn report_non_macro_attr(&self, span: Span, def: Def) { + self.session.span_err(span, &format!("expected a macro, found {}", def.kind_name())); } - fn resolve_invoc_to_def(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) + fn resolve_invoc_to_def(&mut self, invoc: &Invocation, scope: Mark, force: bool) -> Result { - let (attr, traits, item) = match invoc.kind { - InvocationKind::Attr { ref mut attr, ref traits, ref mut item } => (attr, traits, item), + let (attr, traits) = match invoc.kind { + InvocationKind::Attr { ref attr, ref traits, .. } => (attr, traits), InvocationKind::Bang { ref mac, .. } => { return self.resolve_macro_to_def(scope, &mac.node.path, MacroKind::Bang, force); } @@ -413,62 +431,43 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } }; - let path = attr.as_ref().unwrap().path.clone(); - let mut determinacy = Determinacy::Determined; - match self.resolve_macro_to_def(scope, &path, MacroKind::Attr, force) { - Ok(def) => return Ok(def), - Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined, - Err(Determinacy::Determined) if force => return Err(Determinacy::Determined), - Err(Determinacy::Determined) => {} + let def = self.resolve_macro_to_def(scope, &path, MacroKind::Attr, force); + if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = def {} else { + return def; } - // Ok at this point we've determined that the `attr` above doesn't - // actually resolve at this time, so we may want to report an error. - // It could be the case, though, that `attr` won't ever resolve! If - // there's a custom derive that could be used it might declare `attr` as - // a custom attribute accepted by the derive. In this case we don't want - // to report this particular invocation as unresolved, but rather we'd - // want to move on to the next invocation. + // At this point we've found that the `attr` is determinately unresolved and thus can be + // interpreted as a custom attribute. Normally custom attributes are feature gated, but + // it may be a custom attribute whitelisted by a derive macro and they do not require + // a feature gate. // - // This loop here looks through all of the derive annotations in scope - // and tries to resolve them. If they themselves successfully resolve - // *and* the resolve mentions that this attribute's name is a registered - // custom attribute then we flag this attribute as known and update - // `invoc` above to point to the next invocation. - // - // By then returning `Undetermined` we should continue resolution to - // resolve the next attribute. - let attr_name = match path.segments.len() { - 1 => path.segments[0].ident.name, - _ => return Err(determinacy), - }; + // So here we look through all of the derive annotations in scope and try to resolve them. + // If they themselves successfully resolve *and* one of the resolved derive macros + // whitelists this attribute's name, then this is a registered attribute and we can convert + // it from a "generic custom attrite" into a "known derive helper attribute". + enum ConvertToDeriveHelper { Yes, No, DontKnow } + let mut convert_to_derive_helper = ConvertToDeriveHelper::No; + let attr_name = path.segments[0].ident.name; for path in traits { match self.resolve_macro(scope, path, MacroKind::Derive, force) { Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext { if inert_attrs.contains(&attr_name) { - // FIXME(jseyfried) Avoid `mem::replace` here. - let dummy_item = placeholder(AstFragmentKind::Items, ast::DUMMY_NODE_ID) - .make_items().pop().unwrap(); - let dummy_item = Annotatable::Item(dummy_item); - *item = mem::replace(item, dummy_item).map_attrs(|mut attrs| { - let inert_attr = attr.take().unwrap(); - attr::mark_known(&inert_attr); - if self.use_extern_macros { - *attr = expand::find_attr_invoc(&mut attrs); - } - attrs.push(inert_attr); - attrs - }); - return Err(Determinacy::Undetermined) + convert_to_derive_helper = ConvertToDeriveHelper::Yes; + break } }, - Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined, + Err(Determinacy::Undetermined) => + convert_to_derive_helper = ConvertToDeriveHelper::DontKnow, Err(Determinacy::Determined) => {} } } - Err(determinacy) + match convert_to_derive_helper { + ConvertToDeriveHelper::Yes => Ok(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)), + ConvertToDeriveHelper::No => def, + ConvertToDeriveHelper::DontKnow => Err(Determinacy::determined(force)), + } } fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) @@ -481,7 +480,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { "generic arguments in macro path"); }); } - if kind != MacroKind::Bang && path.segments.len() > 1 && def != Ok(Def::NonMacroAttr) { + if kind != MacroKind::Bang && path.segments.len() > 1 && + def != Ok(Def::NonMacroAttr(NonMacroAttrKind::Tool)) { if !self.session.features_untracked().proc_macro_path_invoc { emit_feature_err( &self.session.parse_sess, @@ -550,10 +550,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution { Ok(Def::Macro(binding.def_id, MacroKind::Bang)) } else { - match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, span) { + match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force, + kind == MacroKind::Attr, span) { Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()), - Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined), - Err(_) => { + Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), + Err(Determinacy::Determined) => { self.found_unresolved_macro = true; Err(Determinacy::Determined) } @@ -574,6 +575,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { mut ident: Ident, ns: Namespace, record_used: bool, + force: bool, + is_attr: bool, path_span: Span) -> Result, Determinacy> { // General principles: @@ -604,6 +607,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // 3. Builtin attributes (closed, controlled). assert!(ns == TypeNS || ns == MacroNS); + assert!(force || !record_used); // `record_used` implies `force` ident = ident.modern(); // Names from inner scope that can't shadow names from outer scopes, e.g. @@ -647,8 +651,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } WhereToResolve::BuiltinAttrs => { if is_builtin_attr_name(ident.name) { - let binding = (Def::NonMacroAttr, ty::Visibility::Public, - ident.span, Mark::root()).to_name_binding(self.arenas); + let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin), + ty::Visibility::Public, ident.span, Mark::root()) + .to_name_binding(self.arenas); Ok(MacroBinding::Global(binding)) } else { Err(Determinacy::Determined) @@ -776,7 +781,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Err(Determinacy::Determined) => { continue_search!(); } - Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), + Err(Determinacy::Undetermined) => return Err(Determinacy::determined(force)), } } @@ -785,7 +790,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Ok(previous_result); } - if record_used { Err(Determinacy::Determined) } else { Err(Determinacy::Undetermined) } + let determinacy = Determinacy::determined(force); + if determinacy == Determinacy::Determined && is_attr { + // For single-segment attributes interpret determinate "no resolution" as a custom + // attribute. (Lexical resolution implies the first segment and is_attr should imply + // the last segment, so we are certainly working with a single-segment attribute here.) + assert!(ns == MacroNS); + let binding = (Def::NonMacroAttr(NonMacroAttrKind::Custom), + ty::Visibility::Public, ident.span, Mark::root()) + .to_name_binding(self.arenas); + Ok(MacroBinding::Global(binding)) + } else { + Err(determinacy) + } } pub fn resolve_legacy_scope(&mut self, @@ -869,7 +886,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let span = ident.span; let legacy_scope = &self.invocations[&mark].legacy_scope; let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident, true); - let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, span); + let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, true, true, + kind == MacroKind::Attr, span); let check_consistency = |this: &Self, binding: MacroBinding| { if let Some(def) = def { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 6e49951ff298a..24551e87d36b3 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -812,7 +812,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { HirDef::Macro(..) | HirDef::GlobalAsm(..) | HirDef::ToolMod | - HirDef::NonMacroAttr | + HirDef::NonMacroAttr(..) | HirDef::Err => None, } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8450daa3f7c94..de391ee4219a4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -589,7 +589,7 @@ impl MacroKind { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known. - NonMacroAttr, + NonMacroAttr { mark_used: bool }, /// A syntax extension that is attached to an item and creates new items /// based upon it. @@ -670,7 +670,7 @@ impl SyntaxExtension { SyntaxExtension::IdentTT(..) | SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, - SyntaxExtension::NonMacroAttr | + SyntaxExtension::NonMacroAttr { .. } | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => @@ -700,7 +700,7 @@ impl SyntaxExtension { SyntaxExtension::AttrProcMacro(.., edition) | SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff - SyntaxExtension::NonMacroAttr | + SyntaxExtension::NonMacroAttr { .. } | SyntaxExtension::IdentTT(..) | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | @@ -726,7 +726,7 @@ pub trait Resolver { fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec, allow_derive: bool) -> Option; - fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) + fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool) -> Result>, Determinacy>; fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result, Determinacy>; @@ -739,6 +739,12 @@ pub enum Determinacy { Undetermined, } +impl Determinacy { + pub fn determined(determined: bool) -> Determinacy { + if determined { Determinacy::Determined } else { Determinacy::Undetermined } + } +} + pub struct DummyResolver; impl Resolver for DummyResolver { @@ -754,7 +760,7 @@ impl Resolver for DummyResolver { fn resolve_imports(&mut self) {} fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec, _allow_derive: bool) -> Option { None } - fn resolve_invoc(&mut self, _invoc: &mut Invocation, _scope: Mark, _force: bool) + fn resolve_invoc(&mut self, _invoc: &Invocation, _scope: Mark, _force: bool) -> Result>, Determinacy> { Err(Determinacy::Determined) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 8bd30e434767b..12941a8566987 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -244,19 +244,12 @@ impl Invocation { } } - pub fn path_span(&self) -> Span { + pub fn path(&self) -> Option<&Path> { match self.kind { - InvocationKind::Bang { ref mac, .. } => mac.node.path.span, - InvocationKind::Attr { attr: Some(ref attr), .. } => attr.path.span, - InvocationKind::Attr { attr: None, .. } => DUMMY_SP, - InvocationKind::Derive { ref path, .. } => path.span, - } - } - - pub fn attr_id(&self) -> Option { - match self.kind { - InvocationKind::Attr { attr: Some(ref attr), .. } => Some(attr.id), - _ => None, + InvocationKind::Bang { ref mac, .. } => Some(&mac.node.path), + InvocationKind::Attr { attr: Some(ref attr), .. } => Some(&attr.path), + InvocationKind::Attr { attr: None, .. } => None, + InvocationKind::Derive { ref path, .. } => Some(path), } } } @@ -338,7 +331,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let mut undetermined_invocations = Vec::new(); let (mut progress, mut force) = (false, !self.monotonic); loop { - let mut invoc = if let Some(invoc) = invocations.pop() { + let invoc = if let Some(invoc) = invocations.pop() { invoc } else { self.resolve_imports(); @@ -350,20 +343,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let scope = if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark }; - let attr_id_before = invoc.attr_id(); - let ext = match self.cx.resolver.resolve_invoc(&mut invoc, scope, force) { + let ext = match self.cx.resolver.resolve_invoc(&invoc, scope, force) { Ok(ext) => Some(ext), Err(Determinacy::Determined) => None, Err(Determinacy::Undetermined) => { - // Sometimes attributes which we thought were invocations - // end up being custom attributes for custom derives. If - // that's the case our `invoc` will have changed out from - // under us. If this is the case we're making progress so we - // want to flag it as such, and we test this by looking if - // the `attr_id()` method has been changing over time. - if invoc.attr_id() != attr_id_before { - progress = true; - } undetermined_invocations.push(invoc); continue } @@ -533,6 +516,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> Option { + if invoc.fragment_kind == AstFragmentKind::ForeignItems && + !self.cx.ecfg.macros_in_extern_enabled() { + if let SyntaxExtension::NonMacroAttr { .. } = *ext {} else { + emit_feature_err(&self.cx.parse_sess, "macros_in_extern", + invoc.span(), GateIssue::Language, + "macro invocations in `extern {}` blocks are experimental"); + } + } + let result = match invoc.kind { InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext)?, InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext)?, @@ -565,7 +557,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => unreachable!(), }; - attr::mark_used(&attr); + if let NonMacroAttr { mark_used: false } = *ext {} else { + // Macro attrs are always used when expanded, + // non-macro attrs are considered used when the field says so. + attr::mark_used(&attr); + } invoc.expansion_data.mark.set_expn_info(ExpnInfo { call_site: attr.span, def_site: None, @@ -577,7 +573,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); match *ext { - NonMacroAttr => { + NonMacroAttr { .. } => { attr::mark_known(&attr); let item = item.map_attrs(|mut attrs| { attrs.push(attr); attrs }); Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) @@ -827,7 +823,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } MultiDecorator(..) | MultiModifier(..) | - AttrProcMacro(..) | SyntaxExtension::NonMacroAttr => { + AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); @@ -1497,20 +1493,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { foreign_item: ast::ForeignItem) -> SmallVector { let (attr, traits, foreign_item) = self.classify_item(foreign_item); - let explain = if self.cx.ecfg.use_extern_macros_enabled() { - feature_gate::EXPLAIN_PROC_MACROS_IN_EXTERN - } else { - feature_gate::EXPLAIN_MACROS_IN_EXTERN - }; - - if attr.is_some() || !traits.is_empty() { - if !self.cx.ecfg.macros_in_extern_enabled() { - if let Some(ref attr) = attr { - emit_feature_err(&self.cx.parse_sess, "macros_in_extern", attr.span, - GateIssue::Language, explain); - } - } - + if attr.is_some() || !traits.is_empty() { let item = Annotatable::ForeignItem(P(foreign_item)); return self.collect_attr(attr, traits, item, AstFragmentKind::ForeignItems) .make_foreign_items(); @@ -1518,12 +1501,6 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { if let ast::ForeignItemKind::Macro(mac) = foreign_item.node { self.check_attributes(&foreign_item.attrs); - - if !self.cx.ecfg.macros_in_extern_enabled() { - emit_feature_err(&self.cx.parse_sess, "macros_in_extern", foreign_item.span, - GateIssue::Language, explain); - } - return self.collect_bang(mac, foreign_item.span, AstFragmentKind::ForeignItems) .make_foreign_items(); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 193e560893f37..119505896d69a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -32,7 +32,7 @@ use attr; use codemap::Spanned; use edition::{ALL_EDITIONS, Edition}; use syntax_pos::{Span, DUMMY_SP}; -use errors::{DiagnosticBuilder, Handler, FatalError}; +use errors::{DiagnosticBuilder, Handler}; use visit::{self, FnKind, Visitor}; use parse::ParseSess; use symbol::{keywords, Symbol}; @@ -83,8 +83,14 @@ macro_rules! declare_features { } pub fn use_extern_macros(&self) -> bool { - // The `decl_macro` and `tool_attributes` features imply `use_extern_macros`. - self.use_extern_macros || self.decl_macro || self.tool_attributes + // A number of "advanced" macro features enable + // macro modularization (`use_extern_macros`) implicitly. + self.use_extern_macros || self.decl_macro || + self.tool_attributes || self.custom_attribute || + self.macros_in_extern || self.proc_macro_path_invoc || + self.proc_macro_mod || self.proc_macro_expr || + self.proc_macro_non_items || self.proc_macro_gen || + self.stmt_expr_attributes } } }; @@ -698,7 +704,7 @@ pub fn is_builtin_attr_name(name: ast::Name) -> bool { } pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { - BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| attr.check_name(builtin_name)) || + BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| attr.path == builtin_name) || attr.name().as_str().starts_with("rustc_") } @@ -1348,13 +1354,6 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str = pub const EXPLAIN_MACRO_AT_MOST_ONCE_REP: &'static str = "using the `?` macro Kleene operator for \"at most one\" repetition is unstable"; -pub const EXPLAIN_MACROS_IN_EXTERN: &'static str = - "macro invocations in `extern {}` blocks are experimental."; - -// mention proc-macros when enabled -pub const EXPLAIN_PROC_MACROS_IN_EXTERN: &'static str = - "macro and proc-macro invocations in `extern {}` blocks are experimental."; - struct PostExpansionVisitor<'a> { context: &'a Context<'a>, } @@ -1898,9 +1897,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } let mut features = Features::new(); - - let mut feature_checker = FeatureChecker::default(); - let mut edition_enabled_features = FxHashMap(); for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() { @@ -1966,7 +1962,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], ).emit(); } else { set(&mut features, mi.span); - feature_checker.collect(&features, mi.span); features.declared_lang_features.push((name, mi.span, None)); } continue @@ -1989,45 +1984,9 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } } - feature_checker.check(span_handler); - features } -/// A collector for mutually exclusive and interdependent features and their flag spans. -#[derive(Default)] -struct FeatureChecker { - use_extern_macros: Option, - custom_attribute: Option, -} - -impl FeatureChecker { - // If this method turns out to be a hotspot due to branching, - // the branching can be eliminated by modifying `set!()` to set these spans - // only for the features that need to be checked for mutual exclusion. - fn collect(&mut self, features: &Features, span: Span) { - if features.use_extern_macros() { - // If self.use_extern_macros is None, set to Some(span) - self.use_extern_macros = self.use_extern_macros.or(Some(span)); - } - - if features.custom_attribute { - self.custom_attribute = self.custom_attribute.or(Some(span)); - } - } - - fn check(self, handler: &Handler) { - if let (Some(pm_span), Some(ca_span)) = (self.use_extern_macros, self.custom_attribute) { - handler.struct_span_err(pm_span, "Cannot use `#![feature(use_extern_macros)]` and \ - `#![feature(custom_attribute)] at the same time") - .span_note(ca_span, "`#![feature(custom_attribute)]` declared here") - .emit(); - - FatalError.raise(); - } - } -} - pub fn check_crate(krate: &ast::Crate, sess: &ParseSess, features: &Features, diff --git a/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs b/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs index 64af21dbe10dc..91b72510e3e54 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attr-invalid-exprs.rs @@ -13,7 +13,7 @@ //! Attributes producing expressions in invalid locations -#![feature(use_extern_macros, stmt_expr_attributes, proc_macro_expr)] +#![feature(stmt_expr_attributes, proc_macro_expr)] extern crate attr_stmt_expr; use attr_stmt_expr::{duplicate, no_output}; diff --git a/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs b/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs index 05b5c918ef015..52b2a473ecd75 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs @@ -11,7 +11,7 @@ // aux-build:attr-stmt-expr.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_expr)] +#![feature(proc_macro_expr)] extern crate attr_stmt_expr; use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr}; diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs index 8fced7d8c70da..f71d4b86f1e01 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs @@ -15,7 +15,7 @@ #![feature(use_extern_macros)] #![emit_unchanged] -//~^ ERROR: cannot find attribute macro `emit_unchanged` in this scope +//~^ ERROR attribute `emit_unchanged` is currently unknown to the compiler extern crate issue_41211; use issue_41211::emit_unchanged; diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs index 51112f202c897..eaa64c6ba3692 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-50493.rs @@ -11,8 +11,6 @@ // aux-build:issue_50493.rs // ignore-stage1 -#![feature(proc_macro)] - #[macro_use] extern crate issue_50493; 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 6473b69b4591d..6e9d231ea99a4 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 @@ -11,7 +11,7 @@ // aux-build:bang_proc_macro2.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] #![allow(unused_macros)] extern crate bang_proc_macro2; diff --git a/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs b/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs index 9a35dc0edc448..e418ecc114cc1 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/macros-in-extern.rs @@ -26,13 +26,13 @@ fn main() { #[link(name = "rust_test_helpers", kind = "static")] extern { #[no_output] - //~^ ERROR macro and proc-macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental fn some_definitely_unknown_symbol_which_should_be_removed(); #[nop_attr] - //~^ ERROR macro and proc-macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental fn rust_get_test_int() -> isize; emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); - //~^ ERROR macro and proc-macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental } diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs index 51b1bfca294e4..9a0171c2ae5ea 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs @@ -16,7 +16,7 @@ // gate-test-proc_macro_mod // gate-test-proc_macro_gen -#![feature(use_extern_macros, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] extern crate proc_macro_gates as foo; diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs index ef6d4557f4cd7..dc182414a1ddc 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates2.rs @@ -10,7 +10,7 @@ // aux-build:proc-macro-gates.rs -#![feature(use_extern_macros, stmt_expr_attributes)] +#![feature(stmt_expr_attributes)] extern crate proc_macro_gates as foo; diff --git a/src/test/compile-fail/macro-with-seps-err-msg.rs b/src/test/compile-fail/macro-with-seps-err-msg.rs index 6567a100d8c06..1281adce5c58e 100644 --- a/src/test/compile-fail/macro-with-seps-err-msg.rs +++ b/src/test/compile-fail/macro-with-seps-err-msg.rs @@ -10,10 +10,6 @@ // gate-test-use_extern_macros -#![feature(proc_macro_path_invoc)] - fn main() { globnar::brotz!(); //~ ERROR non-ident macro paths are experimental - #[derive(foo::Bar)] struct T; //~ ERROR non-ident macro paths are experimental - ::foo!(); //~ ERROR non-ident macro paths are experimental } diff --git a/src/test/compile-fail/macros-in-extern.rs b/src/test/compile-fail/macros-in-extern.rs index b6e273881ccd6..40053853b15a7 100644 --- a/src/test/compile-fail/macros-in-extern.rs +++ b/src/test/compile-fail/macros-in-extern.rs @@ -34,9 +34,9 @@ fn main() { #[link(name = "rust_test_helpers", kind = "static")] extern { returns_isize!(rust_get_test_int); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental takes_u32_returns_u32!(rust_dbg_extern_identity_u32); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental emits_nothing!(); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental } diff --git a/src/test/compile-fail/stmt_expr_attrs_no_feature.rs b/src/test/compile-fail/stmt_expr_attrs_no_feature.rs index d8626dfd39ee8..896817bb85832 100644 --- a/src/test/compile-fail/stmt_expr_attrs_no_feature.rs +++ b/src/test/compile-fail/stmt_expr_attrs_no_feature.rs @@ -20,7 +20,7 @@ fn main() { #[attr] fn a() {} - #[attr] + #[attr] //~ ERROR attributes on expressions are experimental { } diff --git a/src/test/compile-fail/unknown-tool-name.rs b/src/test/compile-fail/unknown-tool-name.rs index c4d22e6d39210..99c336c28cd29 100644 --- a/src/test/compile-fail/unknown-tool-name.rs +++ b/src/test/compile-fail/unknown-tool-name.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(use_extern_macros, proc_macro_path_invoc)] +#![feature(proc_macro_path_invoc)] #[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo` fn main() {} diff --git a/src/test/pretty/attr-literals.rs b/src/test/pretty/attr-literals.rs index ba8c580cb0a01..ce157e3632c70 100644 --- a/src/test/pretty/attr-literals.rs +++ b/src/test/pretty/attr-literals.rs @@ -18,6 +18,6 @@ fn main() { #[align = 8] fn f() { } - #[vec(1, 2, 3)] + #[vector(1, 2, 3)] fn g() { } } diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs index ec6f54fb1378f..94c5b208a3707 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs @@ -11,7 +11,7 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs b/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs index 545eabe00ff2e..b54543c73fbd2 100644 --- a/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs +++ b/src/test/run-pass-fulldeps/auxiliary/hello_macro.rs @@ -11,7 +11,7 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(use_extern_macros, proc_macro_non_items, proc_macro_quote)] +#![feature(proc_macro_non_items, proc_macro_quote)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs index 9a5bffb92a493..9faa7366ec5f1 100644 --- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs +++ b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs @@ -11,7 +11,7 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/macro-quote-cond.rs b/src/test/run-pass-fulldeps/macro-quote-cond.rs index f1dcec8af6906..3eb7e8cc9a46d 100644 --- a/src/test/run-pass-fulldeps/macro-quote-cond.rs +++ b/src/test/run-pass-fulldeps/macro-quote-cond.rs @@ -11,7 +11,7 @@ // aux-build:cond_plugin.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate cond_plugin; diff --git a/src/test/run-pass-fulldeps/macro-quote-test.rs b/src/test/run-pass-fulldeps/macro-quote-test.rs index 2349fa68c65f0..1005a6bfc50c7 100644 --- a/src/test/run-pass-fulldeps/macro-quote-test.rs +++ b/src/test/run-pass-fulldeps/macro-quote-test.rs @@ -13,7 +13,7 @@ // aux-build:hello_macro.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items, proc_macro_gen)] +#![feature(proc_macro_non_items, proc_macro_gen)] extern crate hello_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs b/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs index 3356828c04b99..b5272e6608bbf 100644 --- a/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs +++ b/src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs @@ -11,7 +11,7 @@ // aux-build:attr-stmt-expr.rs // ignore-stage1 -#![feature(use_extern_macros, stmt_expr_attributes, proc_macro_expr)] +#![feature(stmt_expr_attributes, proc_macro_expr)] extern crate attr_stmt_expr; use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr, diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs index c6bcc37ac4a54..a84e029f9d87d 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs @@ -10,7 +10,7 @@ // no-prefer-dynamic -#![feature(proc_macro_non_items, proc_macro_quote, use_extern_macros)] +#![feature(proc_macro_non_items, proc_macro_quote)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs index 8f95bdd9c3919..43c1d5fcc8d49 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/hygiene_example_codegen.rs @@ -10,7 +10,7 @@ // no-prefer-dynamic -#![feature(use_extern_macros, proc_macro_quote, proc_macro_non_items)] +#![feature(proc_macro_quote, proc_macro_non_items)] #![crate_type = "proc-macro"] extern crate proc_macro as proc_macro_renamed; // This does not break `quote!` 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 f9d17a9decbb6..955b6ab986d07 100644 --- a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs +++ b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs @@ -11,7 +11,7 @@ // aux-build:bang-macro.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate bang_macro; use bang_macro::rewrite; diff --git a/src/test/run-pass-fulldeps/proc-macro/call-site.rs b/src/test/run-pass-fulldeps/proc-macro/call-site.rs index 505994f66e7e5..dfe97eb587cfb 100644 --- a/src/test/run-pass-fulldeps/proc-macro/call-site.rs +++ b/src/test/run-pass-fulldeps/proc-macro/call-site.rs @@ -11,7 +11,7 @@ // aux-build:call-site.rs // ignore-stage1 -#![feature(proc_macro_non_items, use_extern_macros)] +#![feature(proc_macro_non_items)] extern crate call_site; use call_site::*; 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 f4a51d0624ae6..6601d66e586a3 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 @@ -11,7 +11,7 @@ // aux-build:count_compound_ops.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate count_compound_ops; use count_compound_ops::count_compound_ops; 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 35d5084d9f650..4a7c8f3e8343b 100644 --- a/src/test/run-pass-fulldeps/proc-macro/derive-b.rs +++ b/src/test/run-pass-fulldeps/proc-macro/derive-b.rs @@ -11,7 +11,7 @@ // aux-build:derive-b.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_path_invoc)] +#![feature(proc_macro_path_invoc)] extern crate derive_b; 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 5ee164415a1a5..579e8c337733a 100644 --- a/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs +++ b/src/test/run-pass-fulldeps/proc-macro/hygiene_example.rs @@ -12,7 +12,7 @@ // aux-build:hygiene_example.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate hygiene_example; use hygiene_example::hello; diff --git a/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs b/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs index e5f8c844b6b70..bd76cc380544f 100644 --- a/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs +++ b/src/test/run-pass-fulldeps/proc-macro/macros-in-extern.rs @@ -12,7 +12,7 @@ // ignore-stage1 // ignore-wasm32 -#![feature(use_extern_macros, macros_in_extern)] +#![feature(macros_in_extern)] extern crate test_macros; diff --git a/src/test/run-pass-fulldeps/proc_macro.rs b/src/test/run-pass-fulldeps/proc_macro.rs index 46b62d7e34a52..c9d7b0423ec59 100644 --- a/src/test/run-pass-fulldeps/proc_macro.rs +++ b/src/test/run-pass-fulldeps/proc_macro.rs @@ -12,7 +12,7 @@ // ignore-stage1 // ignore-cross-compile -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate proc_macro_def; diff --git a/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs b/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs index db0c19e96f821..679cb7728680d 100644 --- a/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs +++ b/src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs @@ -10,7 +10,7 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] + #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs b/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs index 89ac11b309d75..6484725814a10 100644 --- a/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs +++ b/src/test/ui-fulldeps/auxiliary/bang_proc_macro.rs @@ -10,7 +10,7 @@ // force-host // no-prefer-dynamic -#![feature(proc_macro)] + #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/auxiliary/lifetimes.rs b/src/test/ui-fulldeps/auxiliary/lifetimes.rs index ecf0a56edf766..fc59a622bfab0 100644 --- a/src/test/ui-fulldeps/auxiliary/lifetimes.rs +++ b/src/test/ui-fulldeps/auxiliary/lifetimes.rs @@ -10,7 +10,6 @@ // no-prefer-dynamic -#![feature(proc_macro)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/lifetimes.rs b/src/test/ui-fulldeps/lifetimes.rs index 3200e8fb2b162..6879848d269b0 100644 --- a/src/test/ui-fulldeps/lifetimes.rs +++ b/src/test/ui-fulldeps/lifetimes.rs @@ -10,7 +10,7 @@ // aux-build:lifetimes.rs -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate lifetimes; diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs index 632dba42ad00f..1ed8ef5202735 100644 --- a/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs +++ b/src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs @@ -11,7 +11,6 @@ // run-pass // no-prefer-dynamic -#![feature(proc_macro)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/proc-macro/generate-mod.rs b/src/test/ui-fulldeps/proc-macro/generate-mod.rs index ee0077c3ed3ff..b0cccd8728bd1 100644 --- a/src/test/ui-fulldeps/proc-macro/generate-mod.rs +++ b/src/test/ui-fulldeps/proc-macro/generate-mod.rs @@ -12,7 +12,7 @@ // aux-build:generate-mod.rs -#![feature(use_extern_macros, proc_macro_gen, proc_macro_path_invoc)] +#![feature(proc_macro_gen, proc_macro_path_invoc)] extern crate generate_mod; diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs b/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs index c06f98ed5ff46..8b940a0f40585 100644 --- a/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs +++ b/src/test/ui-fulldeps/proc-macro/invalid-attributes.rs @@ -11,7 +11,6 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] -#![feature(proc_macro)] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr b/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr index c480bcb5df982..5fd87362db23b 100644 --- a/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr +++ b/src/test/ui-fulldeps/proc-macro/invalid-attributes.stderr @@ -1,35 +1,35 @@ error: `#[proc_macro]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:20:1 + --> $DIR/invalid-attributes.rs:19:1 | LL | #[proc_macro = "test"] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^^^^^^^^ error: `#[proc_macro]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:23:1 + --> $DIR/invalid-attributes.rs:22:1 | LL | #[proc_macro()] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^ error: `#[proc_macro]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:26:1 + --> $DIR/invalid-attributes.rs:25:1 | LL | #[proc_macro(x)] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^^ error: `#[proc_macro_attribute]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:29:1 + --> $DIR/invalid-attributes.rs:28:1 | LL | #[proc_macro_attribute = "test"] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[proc_macro_attribute]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:32:1 + --> $DIR/invalid-attributes.rs:31:1 | LL | #[proc_macro_attribute()] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[proc_macro_attribute]` attribute does not take any arguments - --> $DIR/invalid-attributes.rs:35:1 + --> $DIR/invalid-attributes.rs:34:1 | LL | #[proc_macro_attribute(x)] //~ ERROR: does not take any arguments | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs b/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs index 21d625ae09d8b..e7bb05de88c8a 100644 --- a/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs +++ b/src/test/ui-fulldeps/proc-macro/macro-namespace-reserved.rs @@ -10,7 +10,7 @@ // no-prefer-dynamic -#![feature(proc_macro, decl_macro)] +#![feature(decl_macro)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/proc-macro/non-root.rs b/src/test/ui-fulldeps/proc-macro/non-root.rs index 288c63b4c7781..2440488578814 100644 --- a/src/test/ui-fulldeps/proc-macro/non-root.rs +++ b/src/test/ui-fulldeps/proc-macro/non-root.rs @@ -10,7 +10,6 @@ // no-prefer-dynamic -#![feature(proc_macro)] #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/src/test/ui-fulldeps/proc-macro/non-root.stderr b/src/test/ui-fulldeps/proc-macro/non-root.stderr index 8c14f644d7a64..23222a2b85145 100644 --- a/src/test/ui-fulldeps/proc-macro/non-root.stderr +++ b/src/test/ui-fulldeps/proc-macro/non-root.stderr @@ -1,5 +1,5 @@ error: functions tagged with `#[proc_macro]` must currently reside in the root of the crate - --> $DIR/non-root.rs:21:5 + --> $DIR/non-root.rs:20:5 | LL | pub fn foo(arg: TokenStream) -> TokenStream { arg } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui-fulldeps/proc-macro/three-equals.rs b/src/test/ui-fulldeps/proc-macro/three-equals.rs index ee5f3b33a0648..f6b0e90da0014 100644 --- a/src/test/ui-fulldeps/proc-macro/three-equals.rs +++ b/src/test/ui-fulldeps/proc-macro/three-equals.rs @@ -11,7 +11,7 @@ // aux-build:three-equals.rs // ignore-stage1 -#![feature(use_extern_macros, proc_macro_non_items)] +#![feature(proc_macro_non_items)] extern crate three_equals; diff --git a/src/test/ui-fulldeps/resolve-error.rs b/src/test/ui-fulldeps/resolve-error.rs index df9b263534f60..1940151357c8f 100644 --- a/src/test/ui-fulldeps/resolve-error.rs +++ b/src/test/ui-fulldeps/resolve-error.rs @@ -13,7 +13,7 @@ // aux-build:attr_proc_macro.rs // aux-build:bang_proc_macro.rs -#![feature(use_extern_macros)] +#![feature(custom_attribute)] #[macro_use] extern crate derive_foo; @@ -37,12 +37,10 @@ macro_rules! attr_proc_mac { //~^ ERROR cannot find struct Foo; -#[attr_proc_macra] -//~^ ERROR cannot find +#[attr_proc_macra] // OK, interpreted as a custom attribute struct Bar; -#[FooWithLongNan] -//~^ ERROR cannot find +#[FooWithLongNan] // OK, interpreted as a custom attribute struct Asdf; #[derive(Dlone)] diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui-fulldeps/resolve-error.stderr index caa7966461487..278409c688ab9 100644 --- a/src/test/ui-fulldeps/resolve-error.stderr +++ b/src/test/ui-fulldeps/resolve-error.stderr @@ -4,59 +4,47 @@ error: cannot find derive macro `FooWithLongNan` in this scope LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` -error: cannot find attribute macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:40:3 - | -LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro` - -error: cannot find attribute macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:44:3 - | -LL | #[FooWithLongNan] - | ^^^^^^^^^^^^^^ - error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:48:10 + --> $DIR/resolve-error.rs:46:10 | LL | #[derive(Dlone)] | ^^^^^ help: try: `Clone` error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:52:10 + --> $DIR/resolve-error.rs:50:10 | LL | #[derive(Dlona)] | ^^^^^ help: try: `Clona` error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:56:10 + --> $DIR/resolve-error.rs:54:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ error: cannot find macro `FooWithLongNama!` in this scope - --> $DIR/resolve-error.rs:61:5 + --> $DIR/resolve-error.rs:59:5 | LL | FooWithLongNama!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope - --> $DIR/resolve-error.rs:64:5 + --> $DIR/resolve-error.rs:62:5 | LL | attr_proc_macra!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope - --> $DIR/resolve-error.rs:67:5 + --> $DIR/resolve-error.rs:65:5 | LL | Dlona!(); | ^^^^^ error: cannot find macro `bang_proc_macrp!` in this scope - --> $DIR/resolve-error.rs:70:5 + --> $DIR/resolve-error.rs:68:5 | LL | bang_proc_macrp!(); | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` -error: aborting due to 10 previous errors +error: aborting due to 8 previous errors diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-custom-attr-mutex.rs b/src/test/ui/custom-attribute-multisegment.rs similarity index 50% rename from src/test/compile-fail-fulldeps/proc-macro/proc-macro-custom-attr-mutex.rs rename to src/test/ui/custom-attribute-multisegment.rs index 9ed665b6e68f6..ad8e0e76e1413 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-custom-attr-mutex.rs +++ b/src/test/ui/custom-attribute-multisegment.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,18 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:attr_proc_macro.rs -// ignore-tidy-linelength +// Unresolved multi-segment attributes are not treated as custom. -#![feature(use_extern_macros, custom_attribute)] -//~^ ERROR Cannot use `#![feature(use_extern_macros)]` and `#![feature(custom_attribute)] at the same time +#![feature(custom_attribute, proc_macro_path_invoc)] -extern crate attr_proc_macro; -use attr_proc_macro::attr_proc_macro; +mod existent {} -#[attr_proc_macro] -fn foo() {} - -fn main() { - foo(); -} +#[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent` +fn main() {} diff --git a/src/test/ui/custom-attribute-multisegment.stderr b/src/test/ui/custom-attribute-multisegment.stderr new file mode 100644 index 0000000000000..ff72d1c36d852 --- /dev/null +++ b/src/test/ui/custom-attribute-multisegment.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve. Could not find `nonexistent` in `existent` + --> $DIR/custom-attribute-multisegment.rs:17:13 + | +LL | #[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent` + | ^^^^^^^^^^^ Could not find `nonexistent` in `existent` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/feature-gate-macros_in_extern.rs b/src/test/ui/feature-gate-macros_in_extern.rs index 5271f75b6328c..77080e3c348f9 100644 --- a/src/test/ui/feature-gate-macros_in_extern.rs +++ b/src/test/ui/feature-gate-macros_in_extern.rs @@ -27,9 +27,9 @@ macro_rules! emits_nothing( #[link(name = "rust_test_helpers", kind = "static")] extern { returns_isize!(rust_get_test_int); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental takes_u32_returns_u32!(rust_dbg_extern_identity_u32); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental emits_nothing!(); - //~^ ERROR macro invocations in `extern {}` blocks are experimental. + //~^ ERROR macro invocations in `extern {}` blocks are experimental } diff --git a/src/test/ui/feature-gate-macros_in_extern.stderr b/src/test/ui/feature-gate-macros_in_extern.stderr index 5d7e01fbbb752..23b63078dbf8e 100644 --- a/src/test/ui/feature-gate-macros_in_extern.stderr +++ b/src/test/ui/feature-gate-macros_in_extern.stderr @@ -1,4 +1,4 @@ -error[E0658]: macro and proc-macro invocations in `extern {}` blocks are experimental. (see issue #49476) +error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476) --> $DIR/feature-gate-macros_in_extern.rs:29:5 | LL | returns_isize!(rust_get_test_int); @@ -6,7 +6,7 @@ LL | returns_isize!(rust_get_test_int); | = help: add #![feature(macros_in_extern)] to the crate attributes to enable -error[E0658]: macro and proc-macro invocations in `extern {}` blocks are experimental. (see issue #49476) +error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476) --> $DIR/feature-gate-macros_in_extern.rs:31:5 | LL | takes_u32_returns_u32!(rust_dbg_extern_identity_u32); @@ -14,7 +14,7 @@ LL | takes_u32_returns_u32!(rust_dbg_extern_identity_u32); | = help: add #![feature(macros_in_extern)] to the crate attributes to enable -error[E0658]: macro and proc-macro invocations in `extern {}` blocks are experimental. (see issue #49476) +error[E0658]: macro invocations in `extern {}` blocks are experimental (see issue #49476) --> $DIR/feature-gate-macros_in_extern.rs:33:5 | LL | emits_nothing!(); diff --git a/src/test/ui/imports/macros.rs b/src/test/ui/imports/macros.rs index 5d6a11913849a..ed5907800e9de 100644 --- a/src/test/ui/imports/macros.rs +++ b/src/test/ui/imports/macros.rs @@ -10,7 +10,7 @@ // aux-build:two_macros.rs -#![feature(item_like_imports, use_extern_macros)] +#![feature(use_extern_macros)] extern crate two_macros; // two identity macros `m` and `n` diff --git a/src/test/ui/issue-11692-2.rs b/src/test/ui/issue-11692-2.rs index c595b0fb2c2d8..50525e03acf50 100644 --- a/src/test/ui/issue-11692-2.rs +++ b/src/test/ui/issue-11692-2.rs @@ -10,5 +10,5 @@ fn main() { concat!(test!()); - //~^ ERROR expected a macro, found non-macro attribute + //~^ ERROR expected a macro, found built-in attribute } diff --git a/src/test/ui/issue-11692-2.stderr b/src/test/ui/issue-11692-2.stderr index 3d080bd46dcc9..0c130943fd873 100644 --- a/src/test/ui/issue-11692-2.stderr +++ b/src/test/ui/issue-11692-2.stderr @@ -1,4 +1,4 @@ -error: expected a macro, found non-macro attribute +error: expected a macro, found built-in attribute --> $DIR/issue-11692-2.rs:12:13 | LL | concat!(test!()); diff --git a/src/test/ui/macro-path-prelude-fail-3.rs b/src/test/ui/macro-path-prelude-fail-3.rs index 4cf90019d40eb..bdbc7bd660fcd 100644 --- a/src/test/ui/macro-path-prelude-fail-3.rs +++ b/src/test/ui/macro-path-prelude-fail-3.rs @@ -10,9 +10,9 @@ #![feature(use_extern_macros)] -#[derive(inline)] //~ ERROR expected a macro, found non-macro attribute +#[derive(inline)] //~ ERROR expected a macro, found built-in attribute struct S; fn main() { - inline!(); //~ ERROR expected a macro, found non-macro attribute + inline!(); //~ ERROR expected a macro, found built-in attribute } diff --git a/src/test/ui/macro-path-prelude-fail-3.stderr b/src/test/ui/macro-path-prelude-fail-3.stderr index bd1015b7ee10e..396bba2408f32 100644 --- a/src/test/ui/macro-path-prelude-fail-3.stderr +++ b/src/test/ui/macro-path-prelude-fail-3.stderr @@ -1,13 +1,13 @@ -error: expected a macro, found non-macro attribute +error: expected a macro, found built-in attribute --> $DIR/macro-path-prelude-fail-3.rs:13:10 | -LL | #[derive(inline)] //~ ERROR expected a macro, found non-macro attribute +LL | #[derive(inline)] //~ ERROR expected a macro, found built-in attribute | ^^^^^^ -error: expected a macro, found non-macro attribute +error: expected a macro, found built-in attribute --> $DIR/macro-path-prelude-fail-3.rs:17:5 | -LL | inline!(); //~ ERROR expected a macro, found non-macro attribute +LL | inline!(); //~ ERROR expected a macro, found built-in attribute | ^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/tool-attributes-disabled-2.rs b/src/test/ui/tool-attributes-disabled-2.rs index 160dda05b1ed6..2d97e160f4914 100644 --- a/src/test/ui/tool-attributes-disabled-2.rs +++ b/src/test/ui/tool-attributes-disabled-2.rs @@ -11,9 +11,5 @@ // If macro modularization (`use_extern_macros`) is not enabled, // then tool attributes are treated as custom attributes. -// compile-pass - -#![feature(custom_attribute)] - -#[rustfmt::bar] +#[rustfmt::bar] //~ ERROR attribute `rustfmt::bar` is currently unknown to the compiler fn main() {} diff --git a/src/test/ui/tool-attributes-disabled-2.stderr b/src/test/ui/tool-attributes-disabled-2.stderr new file mode 100644 index 0000000000000..b327773dd6adc --- /dev/null +++ b/src/test/ui/tool-attributes-disabled-2.stderr @@ -0,0 +1,11 @@ +error[E0658]: The attribute `rustfmt::bar` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/tool-attributes-disabled-2.rs:14:1 + | +LL | #[rustfmt::bar] //~ ERROR attribute `rustfmt::bar` is currently unknown to the compiler + | ^^^^^^^^^^^^^^^ + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes-misplaced-1.rs index b335535242379..7a6b9ae9943bc 100644 --- a/src/test/ui/tool-attributes-misplaced-1.rs +++ b/src/test/ui/tool-attributes-misplaced-1.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(tool_attributes)] +#![feature(tool_attributes, custom_attribute)] type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt` -type B = rustfmt::skip; //~ ERROR expected type, found non-macro attribute `rustfmt::skip` +type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip` #[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` in this scope struct S; -#[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope +#[rustfmt] // OK, interpreted as a custom attribute fn check() {} #[rustfmt::skip] // OK @@ -24,5 +24,5 @@ fn main() { rustfmt; //~ ERROR expected value, found tool module `rustfmt` rustfmt!(); //~ ERROR cannot find macro `rustfmt!` in this scope - rustfmt::skip; //~ ERROR expected value, found non-macro attribute `rustfmt::skip` + rustfmt::skip; //~ ERROR expected value, found tool attribute `rustfmt::skip` } diff --git a/src/test/ui/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes-misplaced-1.stderr index b9e61121406ed..60188aebce77c 100644 --- a/src/test/ui/tool-attributes-misplaced-1.stderr +++ b/src/test/ui/tool-attributes-misplaced-1.stderr @@ -4,12 +4,6 @@ error: cannot find derive macro `rustfmt` in this scope LL | #[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` in this scope | ^^^^^^^ -error: cannot find attribute macro `rustfmt` in this scope - --> $DIR/tool-attributes-misplaced-1.rs:19:3 - | -LL | #[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope - | ^^^^^^^ - error: cannot find macro `rustfmt!` in this scope --> $DIR/tool-attributes-misplaced-1.rs:25:5 | @@ -22,10 +16,10 @@ error[E0573]: expected type, found tool module `rustfmt` LL | type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt` | ^^^^^^^ not a type -error[E0573]: expected type, found non-macro attribute `rustfmt::skip` +error[E0573]: expected type, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-1.rs:14:10 | -LL | type B = rustfmt::skip; //~ ERROR expected type, found non-macro attribute `rustfmt::skip` +LL | type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip` | ^^^^^^^^^^^^^ not a type error[E0423]: expected value, found tool module `rustfmt` @@ -34,13 +28,13 @@ error[E0423]: expected value, found tool module `rustfmt` LL | rustfmt; //~ ERROR expected value, found tool module `rustfmt` | ^^^^^^^ not a value -error[E0423]: expected value, found non-macro attribute `rustfmt::skip` +error[E0423]: expected value, found tool attribute `rustfmt::skip` --> $DIR/tool-attributes-misplaced-1.rs:27:5 | -LL | rustfmt::skip; //~ ERROR expected value, found non-macro attribute `rustfmt::skip` +LL | rustfmt::skip; //~ ERROR expected value, found tool attribute `rustfmt::skip` | ^^^^^^^^^^^^^ not a value -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors Some errors occurred: E0423, E0573. For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/tool-attributes-misplaced-2.rs b/src/test/ui/tool-attributes-misplaced-2.rs index 3bb0e3dc34382..102edf2813b21 100644 --- a/src/test/ui/tool-attributes-misplaced-2.rs +++ b/src/test/ui/tool-attributes-misplaced-2.rs @@ -10,9 +10,9 @@ #![feature(tool_attributes)] -#[derive(rustfmt::skip)] //~ ERROR expected a macro, found non-macro attribute +#[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute struct S; fn main() { - rustfmt::skip!(); //~ ERROR expected a macro, found non-macro attribute + rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute } diff --git a/src/test/ui/tool-attributes-misplaced-2.stderr b/src/test/ui/tool-attributes-misplaced-2.stderr index 66452267e947b..5b968cd6b8ecd 100644 --- a/src/test/ui/tool-attributes-misplaced-2.stderr +++ b/src/test/ui/tool-attributes-misplaced-2.stderr @@ -1,13 +1,13 @@ -error: expected a macro, found non-macro attribute +error: expected a macro, found tool attribute --> $DIR/tool-attributes-misplaced-2.rs:13:10 | -LL | #[derive(rustfmt::skip)] //~ ERROR expected a macro, found non-macro attribute +LL | #[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute | ^^^^^^^^^^^^^ -error: expected a macro, found non-macro attribute +error: expected a macro, found tool attribute --> $DIR/tool-attributes-misplaced-2.rs:17:5 | -LL | rustfmt::skip!(); //~ ERROR expected a macro, found non-macro attribute +LL | rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors