Auto merge of #53053 - petrochenkov:custattr, r=alexcrichton
resolve: Support custom attributes when macro modularization is enabled Basically, if resolution of a single-segment attribute is a determined error, then we interpret it as a custom attribute. Since custom attributes are integrated into general macro resolution, `feature(custom_attribute)` now requires and implicitly enables macro modularization (`feature(use_extern_macros)`). Actually, a few other "advanced" macro features now implicitly enable macro modularization too (and one bug was found and fixed in process of enabling it). The first two commits are preliminary cleanups/refactorings.
This commit is contained in:
commit
ffb09dfb3a
66 changed files with 295 additions and 320 deletions
|
@ -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]`
|
||||
|
||||
// Both namespaces
|
||||
Err,
|
||||
|
@ -240,6 +252,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 {
|
||||
|
@ -259,7 +282,7 @@ impl Def {
|
|||
Def::PrimTy(..) |
|
||||
Def::SelfTy(..) |
|
||||
Def::ToolMod |
|
||||
Def::NonMacroAttr |
|
||||
Def::NonMacroAttr(..) |
|
||||
Def::Err => {
|
||||
bug!("attempted .def_id() on invalid def: {:?}", self)
|
||||
}
|
||||
|
@ -300,7 +323,7 @@ impl Def {
|
|||
Def::SelfTy(..) => "self type",
|
||||
Def::Macro(.., macro_kind) => macro_kind.descr(),
|
||||
Def::ToolMod => "tool module",
|
||||
Def::NonMacroAttr => "non-macro attribute",
|
||||
Def::NonMacroAttr(attr_kind) => attr_kind.descr(),
|
||||
Def::Err => "unresolved item",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -990,6 +990,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),
|
||||
|
@ -1018,7 +1025,7 @@ impl_stable_hash_for!(enum hir::def::Def {
|
|||
Label(node_id),
|
||||
Macro(def_id, macro_kind),
|
||||
ToolMod,
|
||||
NonMacroAttr,
|
||||
NonMacroAttr(attr_kind),
|
||||
Err
|
||||
});
|
||||
|
||||
|
|
|
@ -630,8 +630,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
pub fn get_macro(&mut self, def: Def) -> Lrc<SyntaxExtension> {
|
||||
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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<Option<Lrc<SyntaxExtension>>, 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<Def, Determinacy> {
|
||||
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<MacroBinding<'a>, 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 {
|
||||
|
|
|
@ -811,7 +811,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
HirDef::Label(..) |
|
||||
HirDef::Macro(..) |
|
||||
HirDef::ToolMod |
|
||||
HirDef::NonMacroAttr |
|
||||
HirDef::NonMacroAttr(..) |
|
||||
HirDef::Err => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Attribute>, allow_derive: bool)
|
||||
-> Option<Attribute>;
|
||||
|
||||
fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
|
||||
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
|
||||
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
|
||||
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
|
||||
-> Result<Lrc<SyntaxExtension>, 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<Attribute>, _allow_derive: bool)
|
||||
-> Option<Attribute> { 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<Option<Lrc<SyntaxExtension>>, Determinacy> {
|
||||
Err(Determinacy::Determined)
|
||||
}
|
||||
|
|
|
@ -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<ast::AttrId> {
|
||||
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<AstFragment> {
|
||||
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<ast::ForeignItem> {
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -714,7 +720,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_")
|
||||
}
|
||||
|
||||
|
@ -1364,13 +1370,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>,
|
||||
}
|
||||
|
@ -1914,9 +1913,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() {
|
||||
|
@ -1982,7 +1978,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
|
||||
|
@ -2005,45 +2000,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<Span>,
|
||||
custom_attribute: Option<Span>,
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
// aux-build:issue_50493.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate issue_50493;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ fn main() {
|
|||
#[attr]
|
||||
fn a() {}
|
||||
|
||||
#[attr]
|
||||
#[attr] //~ ERROR attributes on expressions are experimental
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -18,6 +18,6 @@ fn main() {
|
|||
#[align = 8]
|
||||
fn f() { }
|
||||
|
||||
#[vec(1, 2, 3)]
|
||||
#[vector(1, 2, 3)]
|
||||
fn g() { }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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!`
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// ignore-stage1
|
||||
// ignore-wasm32
|
||||
|
||||
#![feature(use_extern_macros, macros_in_extern)]
|
||||
#![feature(macros_in_extern)]
|
||||
|
||||
extern crate test_macros;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// aux-build:lifetimes.rs
|
||||
|
||||
#![feature(use_extern_macros, proc_macro_non_items)]
|
||||
#![feature(proc_macro_non_items)]
|
||||
|
||||
extern crate lifetimes;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
// run-pass
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
|
|
@ -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
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro, decl_macro)]
|
||||
#![feature(decl_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
|
|
@ -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 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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() {}
|
9
src/test/ui/custom-attribute-multisegment.stderr
Normal file
9
src/test/ui/custom-attribute-multisegment.stderr
Normal file
|
@ -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`.
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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!();
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
|
@ -10,5 +10,5 @@
|
|||
|
||||
fn main() {
|
||||
concat!(test!());
|
||||
//~^ ERROR expected a macro, found non-macro attribute
|
||||
//~^ ERROR expected a macro, found built-in attribute
|
||||
}
|
||||
|
|
|
@ -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!());
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
|
11
src/test/ui/tool-attributes-disabled-2.stderr
Normal file
11
src/test/ui/tool-attributes-disabled-2.stderr
Normal file
|
@ -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`.
|
|
@ -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`
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue