Rollup merge of #79185 - petrochenkov:derattr2, r=Aaron1011
expand/resolve: Pre-requisites to "Turn `#[derive]` into a regular macro attribute" Miscellaneous refactorings and error reporting changes extracted from https://github.com/rust-lang/rust/pull/79078. Unlike https://github.com/rust-lang/rust/pull/79078 this PR doesn't make any observable changes to the language or library. r? ```@Aaron1011```
This commit is contained in:
commit
8216b359e5
33 changed files with 480 additions and 653 deletions
|
@ -1,7 +1,7 @@
|
||||||
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
|
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
|
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
|
||||||
use rustc_feature::AttributeTemplate;
|
use rustc_feature::AttributeTemplate;
|
||||||
use rustc_parse::validate_attr;
|
use rustc_parse::validate_attr;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
@ -31,7 +31,7 @@ impl MultiItemModifier for Expander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
ecx: &mut ExtCtxt<'_>,
|
ecx: &mut ExtCtxt<'_>,
|
||||||
_span: Span,
|
span: Span,
|
||||||
meta_item: &ast::MetaItem,
|
meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
|
@ -49,11 +49,14 @@ impl MultiItemModifier for Expander {
|
||||||
None => return ExpandResult::Ready(Vec::new()),
|
None => return ExpandResult::Ready(Vec::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let failure_msg = "cannot determine whether the path is accessible or not";
|
|
||||||
match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
|
match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
|
||||||
Ok(true) => ExpandResult::Ready(vec![item]),
|
Ok(true) => ExpandResult::Ready(vec![item]),
|
||||||
Ok(false) => ExpandResult::Ready(Vec::new()),
|
Ok(false) => ExpandResult::Ready(Vec::new()),
|
||||||
Err(_) => ExpandResult::Retry(item, failure_msg.into()),
|
Err(Indeterminate) if ecx.force_mode => {
|
||||||
|
ecx.span_err(span, "cannot determine whether the path is accessible or not");
|
||||||
|
ExpandResult::Ready(vec![item])
|
||||||
|
}
|
||||||
|
Err(Indeterminate) => ExpandResult::Retry(item),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,13 +407,7 @@ impl<'a> TraitDef<'a> {
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => unreachable!(),
|
||||||
// Non-ADT derive is an error, but it should have been
|
|
||||||
// set earlier; see
|
|
||||||
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
|
|
||||||
// librustc_expand/base.rs:Annotatable::derive_allowed()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let container_id = cx.current_expansion.id.expn_data().parent;
|
let container_id = cx.current_expansion.id.expn_data().parent;
|
||||||
let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
||||||
|
@ -475,12 +469,7 @@ impl<'a> TraitDef<'a> {
|
||||||
);
|
);
|
||||||
push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
|
push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => unreachable!(),
|
||||||
// Non-Item derive is an error, but it should have been
|
|
||||||
// set earlier; see
|
|
||||||
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
|
|
||||||
// librustc_expand/base.rs:Annotatable::derive_allowed()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,13 +98,7 @@ fn inject_impl_of_structural_trait(
|
||||||
) {
|
) {
|
||||||
let item = match *item {
|
let item = match *item {
|
||||||
Annotatable::Item(ref item) => item,
|
Annotatable::Item(ref item) => item,
|
||||||
_ => {
|
_ => unreachable!(),
|
||||||
// Non-Item derive is an error, but it should have been
|
|
||||||
// set earlier; see
|
|
||||||
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
|
|
||||||
// librustc_expand/base.rs:Annotatable::derive_allowed()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let generics = match item.kind {
|
let generics = match item.kind {
|
||||||
|
|
|
@ -251,8 +251,7 @@ pub enum ExpandResult<T, U> {
|
||||||
/// Expansion produced a result (possibly dummy).
|
/// Expansion produced a result (possibly dummy).
|
||||||
Ready(T),
|
Ready(T),
|
||||||
/// Expansion could not produce a result and needs to be retried.
|
/// Expansion could not produce a result and needs to be retried.
|
||||||
/// The string is an explanation that will be printed if we are stuck in an infinite retry loop.
|
Retry(U),
|
||||||
Retry(U, String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `meta_item` is the attribute, and `item` is the item being modified.
|
// `meta_item` is the attribute, and `item` is the item being modified.
|
||||||
|
@ -889,8 +888,10 @@ pub trait ResolverExpand {
|
||||||
/// Some parent node that is close enough to the given macro call.
|
/// Some parent node that is close enough to the given macro call.
|
||||||
fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId;
|
fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId;
|
||||||
|
|
||||||
|
// Resolver interfaces for specific built-in macros.
|
||||||
|
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
|
||||||
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
|
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
|
||||||
fn add_derive_copy(&mut self, expn_id: ExpnId);
|
/// Path resolution logic for `#[cfg_accessible(path)]`.
|
||||||
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
|
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,6 +920,9 @@ pub struct ExtCtxt<'a> {
|
||||||
pub root_path: PathBuf,
|
pub root_path: PathBuf,
|
||||||
pub resolver: &'a mut dyn ResolverExpand,
|
pub resolver: &'a mut dyn ResolverExpand,
|
||||||
pub current_expansion: ExpansionData,
|
pub current_expansion: ExpansionData,
|
||||||
|
/// Error recovery mode entered when expansion is stuck
|
||||||
|
/// (or during eager expansion, but that's a hack).
|
||||||
|
pub force_mode: bool,
|
||||||
pub expansions: FxHashMap<Span, Vec<String>>,
|
pub expansions: FxHashMap<Span, Vec<String>>,
|
||||||
/// Called directly after having parsed an external `mod foo;` in expansion.
|
/// Called directly after having parsed an external `mod foo;` in expansion.
|
||||||
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
|
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
|
||||||
|
@ -945,6 +949,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
directory_ownership: DirectoryOwnership::Owned { relative: None },
|
directory_ownership: DirectoryOwnership::Owned { relative: None },
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
},
|
},
|
||||||
|
force_mode: false,
|
||||||
expansions: FxHashMap::default(),
|
expansions: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Conditional compilation stripping.
|
//! Conditional compilation stripping.
|
||||||
|
|
||||||
|
use crate::base::Annotatable;
|
||||||
|
|
||||||
use rustc_ast::attr::HasAttrs;
|
use rustc_ast::attr::HasAttrs;
|
||||||
use rustc_ast::mut_visit::*;
|
use rustc_ast::mut_visit::*;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
@ -496,6 +498,49 @@ impl<'a> StripUnconfigured<'a> {
|
||||||
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
|
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
|
||||||
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
|
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
|
||||||
|
// Since the item itself has already been configured by the InvocationCollector,
|
||||||
|
// we know that fold result vector will contain exactly one element
|
||||||
|
match item {
|
||||||
|
Annotatable::Item(item) => Annotatable::Item(self.flat_map_item(item).pop().unwrap()),
|
||||||
|
Annotatable::TraitItem(item) => {
|
||||||
|
Annotatable::TraitItem(self.flat_map_trait_item(item).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::ImplItem(item) => {
|
||||||
|
Annotatable::ImplItem(self.flat_map_impl_item(item).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::ForeignItem(item) => {
|
||||||
|
Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::Stmt(stmt) => {
|
||||||
|
Annotatable::Stmt(stmt.map(|stmt| self.flat_map_stmt(stmt).pop().unwrap()))
|
||||||
|
}
|
||||||
|
Annotatable::Expr(mut expr) => Annotatable::Expr({
|
||||||
|
self.visit_expr(&mut expr);
|
||||||
|
expr
|
||||||
|
}),
|
||||||
|
Annotatable::Arm(arm) => Annotatable::Arm(self.flat_map_arm(arm).pop().unwrap()),
|
||||||
|
Annotatable::Field(field) => {
|
||||||
|
Annotatable::Field(self.flat_map_field(field).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::FieldPat(fp) => {
|
||||||
|
Annotatable::FieldPat(self.flat_map_field_pattern(fp).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::GenericParam(param) => {
|
||||||
|
Annotatable::GenericParam(self.flat_map_generic_param(param).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::Param(param) => {
|
||||||
|
Annotatable::Param(self.flat_map_param(param).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::StructField(sf) => {
|
||||||
|
Annotatable::StructField(self.flat_map_struct_field(sf).pop().unwrap())
|
||||||
|
}
|
||||||
|
Annotatable::Variant(v) => {
|
||||||
|
Annotatable::Variant(self.flat_map_variant(v).pop().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MutVisitor for StripUnconfigured<'a> {
|
impl<'a> MutVisitor for StripUnconfigured<'a> {
|
||||||
|
|
|
@ -209,6 +209,28 @@ impl AstFragmentKind {
|
||||||
self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
|
self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fragment supports macro expansion and not just inert attributes, `cfg` and `cfg_attr`.
|
||||||
|
pub fn supports_macro_expansion(self) -> bool {
|
||||||
|
match self {
|
||||||
|
AstFragmentKind::OptExpr
|
||||||
|
| AstFragmentKind::Expr
|
||||||
|
| AstFragmentKind::Pat
|
||||||
|
| AstFragmentKind::Ty
|
||||||
|
| AstFragmentKind::Stmts
|
||||||
|
| AstFragmentKind::Items
|
||||||
|
| AstFragmentKind::TraitItems
|
||||||
|
| AstFragmentKind::ImplItems
|
||||||
|
| AstFragmentKind::ForeignItems => true,
|
||||||
|
AstFragmentKind::Arms
|
||||||
|
| AstFragmentKind::Fields
|
||||||
|
| AstFragmentKind::FieldPats
|
||||||
|
| AstFragmentKind::GenericParams
|
||||||
|
| AstFragmentKind::Params
|
||||||
|
| AstFragmentKind::StructFields
|
||||||
|
| AstFragmentKind::Variants => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
|
fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
|
||||||
self,
|
self,
|
||||||
items: I,
|
items: I,
|
||||||
|
@ -404,6 +426,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
// Recursively expand all macro invocations in this AST fragment.
|
// Recursively expand all macro invocations in this AST fragment.
|
||||||
pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
|
pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
|
||||||
let orig_expansion_data = self.cx.current_expansion.clone();
|
let orig_expansion_data = self.cx.current_expansion.clone();
|
||||||
|
let orig_force_mode = self.cx.force_mode;
|
||||||
self.cx.current_expansion.depth = 0;
|
self.cx.current_expansion.depth = 0;
|
||||||
|
|
||||||
// Collect all macro invocations and replace them with placeholders.
|
// Collect all macro invocations and replace them with placeholders.
|
||||||
|
@ -432,6 +455,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
invocations = mem::take(&mut undetermined_invocations);
|
invocations = mem::take(&mut undetermined_invocations);
|
||||||
force = !mem::replace(&mut progress, false);
|
force = !mem::replace(&mut progress, false);
|
||||||
|
if force && self.monotonic {
|
||||||
|
self.cx.sess.delay_span_bug(
|
||||||
|
invocations.last().unwrap().0.span(),
|
||||||
|
"expansion entered force mode without producing any errors",
|
||||||
|
);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -460,18 +489,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
|
|
||||||
let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
|
let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
|
||||||
self.cx.current_expansion = invoc.expansion_data.clone();
|
self.cx.current_expansion = invoc.expansion_data.clone();
|
||||||
|
self.cx.force_mode = force;
|
||||||
|
|
||||||
// FIXME(jseyfried): Refactor out the following logic
|
// FIXME(jseyfried): Refactor out the following logic
|
||||||
|
let fragment_kind = invoc.fragment_kind;
|
||||||
let (expanded_fragment, new_invocations) = match res {
|
let (expanded_fragment, new_invocations) = match res {
|
||||||
InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
|
InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
|
||||||
ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
|
ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
|
||||||
ExpandResult::Retry(invoc, explanation) => {
|
ExpandResult::Retry(invoc) => {
|
||||||
if force {
|
if force {
|
||||||
// We are stuck, stop retrying and produce a dummy fragment.
|
self.cx.span_bug(
|
||||||
let span = invoc.span();
|
invoc.span(),
|
||||||
self.cx.span_err(span, &explanation);
|
"expansion entered force mode but is still stuck",
|
||||||
let fragment = invoc.fragment_kind.dummy(span);
|
);
|
||||||
self.collect_invocations(fragment, &[])
|
|
||||||
} else {
|
} else {
|
||||||
// Cannot expand, will retry this invocation later.
|
// Cannot expand, will retry this invocation later.
|
||||||
undetermined_invocations
|
undetermined_invocations
|
||||||
|
@ -483,36 +513,45 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
InvocationRes::DeriveContainer(_exts) => {
|
InvocationRes::DeriveContainer(_exts) => {
|
||||||
// FIXME: Consider using the derive resolutions (`_exts`) immediately,
|
// FIXME: Consider using the derive resolutions (`_exts`) immediately,
|
||||||
// instead of enqueuing the derives to be resolved again later.
|
// instead of enqueuing the derives to be resolved again later.
|
||||||
let (derives, item) = match invoc.kind {
|
let (derives, mut item) = match invoc.kind {
|
||||||
InvocationKind::DeriveContainer { derives, item } => (derives, item),
|
InvocationKind::DeriveContainer { derives, item } => (derives, item),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
if !item.derive_allowed() {
|
let (item, derive_placeholders) = if !item.derive_allowed() {
|
||||||
self.error_derive_forbidden_on_non_adt(&derives, &item);
|
self.error_derive_forbidden_on_non_adt(&derives, &item);
|
||||||
}
|
item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
|
||||||
|
(item, Vec::new())
|
||||||
|
} else {
|
||||||
|
let mut item = StripUnconfigured {
|
||||||
|
sess: self.cx.sess,
|
||||||
|
features: self.cx.ecfg.features,
|
||||||
|
}
|
||||||
|
.fully_configure(item);
|
||||||
|
item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
|
||||||
|
|
||||||
let mut item = self.fully_configure(item);
|
invocations.reserve(derives.len());
|
||||||
item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
|
let derive_placeholders = derives
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| {
|
||||||
|
let expn_id = ExpnId::fresh(None);
|
||||||
|
invocations.push((
|
||||||
|
Invocation {
|
||||||
|
kind: InvocationKind::Derive { path, item: item.clone() },
|
||||||
|
fragment_kind,
|
||||||
|
expansion_data: ExpansionData {
|
||||||
|
id: expn_id,
|
||||||
|
..self.cx.current_expansion.clone()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
NodeId::placeholder_from_expn_id(expn_id)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
(item, derive_placeholders)
|
||||||
|
};
|
||||||
|
|
||||||
let mut derive_placeholders = Vec::with_capacity(derives.len());
|
let fragment = fragment_kind.expect_from_annotatables(::std::iter::once(item));
|
||||||
invocations.reserve(derives.len());
|
|
||||||
for path in derives {
|
|
||||||
let expn_id = ExpnId::fresh(None);
|
|
||||||
derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
|
|
||||||
invocations.push((
|
|
||||||
Invocation {
|
|
||||||
kind: InvocationKind::Derive { path, item: item.clone() },
|
|
||||||
fragment_kind: invoc.fragment_kind,
|
|
||||||
expansion_data: ExpansionData {
|
|
||||||
id: expn_id,
|
|
||||||
..invoc.expansion_data.clone()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let fragment =
|
|
||||||
invoc.fragment_kind.expect_from_annotatables(::std::iter::once(item));
|
|
||||||
self.collect_invocations(fragment, &derive_placeholders)
|
self.collect_invocations(fragment, &derive_placeholders)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -526,6 +565,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cx.current_expansion = orig_expansion_data;
|
self.cx.current_expansion = orig_expansion_data;
|
||||||
|
self.cx.force_mode = orig_force_mode;
|
||||||
|
|
||||||
// Finally incorporate all the expanded macros into the input AST fragment.
|
// Finally incorporate all the expanded macros into the input AST fragment.
|
||||||
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
|
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
|
||||||
|
@ -601,48 +641,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
(fragment, invocations)
|
(fragment, invocations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
|
|
||||||
let mut cfg = StripUnconfigured { sess: &self.cx.sess, features: self.cx.ecfg.features };
|
|
||||||
// Since the item itself has already been configured by the InvocationCollector,
|
|
||||||
// we know that fold result vector will contain exactly one element
|
|
||||||
match item {
|
|
||||||
Annotatable::Item(item) => Annotatable::Item(cfg.flat_map_item(item).pop().unwrap()),
|
|
||||||
Annotatable::TraitItem(item) => {
|
|
||||||
Annotatable::TraitItem(cfg.flat_map_trait_item(item).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::ImplItem(item) => {
|
|
||||||
Annotatable::ImplItem(cfg.flat_map_impl_item(item).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::ForeignItem(item) => {
|
|
||||||
Annotatable::ForeignItem(cfg.flat_map_foreign_item(item).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::Stmt(stmt) => {
|
|
||||||
Annotatable::Stmt(stmt.map(|stmt| cfg.flat_map_stmt(stmt).pop().unwrap()))
|
|
||||||
}
|
|
||||||
Annotatable::Expr(mut expr) => Annotatable::Expr({
|
|
||||||
cfg.visit_expr(&mut expr);
|
|
||||||
expr
|
|
||||||
}),
|
|
||||||
Annotatable::Arm(arm) => Annotatable::Arm(cfg.flat_map_arm(arm).pop().unwrap()),
|
|
||||||
Annotatable::Field(field) => {
|
|
||||||
Annotatable::Field(cfg.flat_map_field(field).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::FieldPat(fp) => {
|
|
||||||
Annotatable::FieldPat(cfg.flat_map_field_pattern(fp).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::GenericParam(param) => {
|
|
||||||
Annotatable::GenericParam(cfg.flat_map_generic_param(param).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::Param(param) => {
|
|
||||||
Annotatable::Param(cfg.flat_map_param(param).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::StructField(sf) => {
|
|
||||||
Annotatable::StructField(cfg.flat_map_struct_field(sf).pop().unwrap())
|
|
||||||
}
|
|
||||||
Annotatable::Variant(v) => Annotatable::Variant(cfg.flat_map_variant(v).pop().unwrap()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error_recursion_limit_reached(&mut self) {
|
fn error_recursion_limit_reached(&mut self) {
|
||||||
let expn_data = self.cx.current_expansion.id.expn_data();
|
let expn_data = self.cx.current_expansion.id.expn_data();
|
||||||
let suggested_limit = self.cx.ecfg.recursion_limit * 2;
|
let suggested_limit = self.cx.ecfg.recursion_limit * 2;
|
||||||
|
@ -735,20 +733,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
Ok(meta) => {
|
Ok(meta) => {
|
||||||
let items = match expander.expand(self.cx, span, &meta, item) {
|
let items = match expander.expand(self.cx, span, &meta, item) {
|
||||||
ExpandResult::Ready(items) => items,
|
ExpandResult::Ready(items) => items,
|
||||||
ExpandResult::Retry(item, explanation) => {
|
ExpandResult::Retry(item) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
return ExpandResult::Retry(
|
return ExpandResult::Retry(Invocation {
|
||||||
Invocation {
|
kind: InvocationKind::Attr {
|
||||||
kind: InvocationKind::Attr {
|
attr,
|
||||||
attr,
|
item,
|
||||||
item,
|
derives,
|
||||||
derives,
|
after_derive,
|
||||||
after_derive,
|
|
||||||
},
|
|
||||||
..invoc
|
|
||||||
},
|
},
|
||||||
explanation,
|
..invoc
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fragment_kind.expect_from_annotatables(items)
|
fragment_kind.expect_from_annotatables(items)
|
||||||
|
@ -772,24 +767,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
InvocationKind::Derive { path, item } => match ext {
|
InvocationKind::Derive { path, item } => match ext {
|
||||||
SyntaxExtensionKind::Derive(expander)
|
SyntaxExtensionKind::Derive(expander)
|
||||||
| SyntaxExtensionKind::LegacyDerive(expander) => {
|
| SyntaxExtensionKind::LegacyDerive(expander) => {
|
||||||
if !item.derive_allowed() {
|
|
||||||
return ExpandResult::Ready(fragment_kind.dummy(span));
|
|
||||||
}
|
|
||||||
if let SyntaxExtensionKind::Derive(..) = ext {
|
if let SyntaxExtensionKind::Derive(..) = ext {
|
||||||
self.gate_proc_macro_input(&item);
|
self.gate_proc_macro_input(&item);
|
||||||
}
|
}
|
||||||
let meta = ast::MetaItem { kind: ast::MetaItemKind::Word, span, path };
|
let meta = ast::MetaItem { kind: ast::MetaItemKind::Word, span, path };
|
||||||
let items = match expander.expand(self.cx, span, &meta, item) {
|
let items = match expander.expand(self.cx, span, &meta, item) {
|
||||||
ExpandResult::Ready(items) => items,
|
ExpandResult::Ready(items) => items,
|
||||||
ExpandResult::Retry(item, explanation) => {
|
ExpandResult::Retry(item) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
return ExpandResult::Retry(
|
return ExpandResult::Retry(Invocation {
|
||||||
Invocation {
|
kind: InvocationKind::Derive { path: meta.path, item },
|
||||||
kind: InvocationKind::Derive { path: meta.path, item },
|
..invoc
|
||||||
..invoc
|
});
|
||||||
},
|
|
||||||
explanation,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fragment_kind.expect_from_annotatables(items)
|
fragment_kind.expect_from_annotatables(items)
|
||||||
|
@ -1034,11 +1023,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
|
|
||||||
fn collect_attr(
|
fn collect_attr(
|
||||||
&mut self,
|
&mut self,
|
||||||
attr: Option<ast::Attribute>,
|
(attr, derives, after_derive): (Option<ast::Attribute>, Vec<Path>, bool),
|
||||||
derives: Vec<Path>,
|
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
kind: AstFragmentKind,
|
kind: AstFragmentKind,
|
||||||
after_derive: bool,
|
|
||||||
) -> AstFragment {
|
) -> AstFragment {
|
||||||
self.collect(
|
self.collect(
|
||||||
kind,
|
kind,
|
||||||
|
@ -1054,7 +1041,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
attrs: &mut Vec<ast::Attribute>,
|
attrs: &mut Vec<ast::Attribute>,
|
||||||
after_derive: &mut bool,
|
after_derive: &mut bool,
|
||||||
) -> Option<ast::Attribute> {
|
) -> Option<ast::Attribute> {
|
||||||
let attr = attrs
|
attrs
|
||||||
.iter()
|
.iter()
|
||||||
.position(|a| {
|
.position(|a| {
|
||||||
if a.has_name(sym::derive) {
|
if a.has_name(sym::derive) {
|
||||||
|
@ -1062,29 +1049,14 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
}
|
}
|
||||||
!self.cx.sess.is_attr_known(a) && !is_builtin_attr(a)
|
!self.cx.sess.is_attr_known(a) && !is_builtin_attr(a)
|
||||||
})
|
})
|
||||||
.map(|i| attrs.remove(i));
|
.map(|i| attrs.remove(i))
|
||||||
if let Some(attr) = &attr {
|
|
||||||
if !self.cx.ecfg.custom_inner_attributes()
|
|
||||||
&& attr.style == ast::AttrStyle::Inner
|
|
||||||
&& !attr.has_name(sym::test)
|
|
||||||
{
|
|
||||||
feature_err(
|
|
||||||
&self.cx.sess.parse_sess,
|
|
||||||
sym::custom_inner_attributes,
|
|
||||||
attr.span,
|
|
||||||
"non-builtin inner attributes are unstable",
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
|
/// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
|
||||||
fn classify_item(
|
fn take_first_attr(
|
||||||
&mut self,
|
&mut self,
|
||||||
item: &mut impl HasAttrs,
|
item: &mut impl HasAttrs,
|
||||||
) -> (Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool) {
|
) -> Option<(Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool)> {
|
||||||
let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
|
let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
|
||||||
|
|
||||||
item.visit_attrs(|mut attrs| {
|
item.visit_attrs(|mut attrs| {
|
||||||
|
@ -1092,23 +1064,23 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
traits = collect_derives(&mut self.cx, &mut attrs);
|
traits = collect_derives(&mut self.cx, &mut attrs);
|
||||||
});
|
});
|
||||||
|
|
||||||
(attr, traits, after_derive)
|
if attr.is_some() || !traits.is_empty() { Some((attr, traits, after_derive)) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alternative to `classify_item()` that ignores `#[derive]` so invocations fallthrough
|
/// Alternative to `take_first_attr()` that ignores `#[derive]` so invocations fallthrough
|
||||||
/// to the unused-attributes lint (making it an error on statements and expressions
|
/// to the unused-attributes lint (making it an error on statements and expressions
|
||||||
/// is a breaking change)
|
/// is a breaking change)
|
||||||
fn classify_nonitem(
|
fn take_first_attr_no_derive(
|
||||||
&mut self,
|
&mut self,
|
||||||
nonitem: &mut impl HasAttrs,
|
nonitem: &mut impl HasAttrs,
|
||||||
) -> (Option<ast::Attribute>, /* after_derive */ bool) {
|
) -> Option<(Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool)> {
|
||||||
let (mut attr, mut after_derive) = (None, false);
|
let (mut attr, mut after_derive) = (None, false);
|
||||||
|
|
||||||
nonitem.visit_attrs(|mut attrs| {
|
nonitem.visit_attrs(|mut attrs| {
|
||||||
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
|
attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
|
||||||
});
|
});
|
||||||
|
|
||||||
(attr, after_derive)
|
attr.map(|attr| (Some(attr), Vec::new(), after_derive))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
||||||
|
@ -1152,23 +1124,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
visit_clobber(expr.deref_mut(), |mut expr| {
|
visit_clobber(expr.deref_mut(), |mut expr| {
|
||||||
self.cfg.configure_expr_kind(&mut expr.kind);
|
self.cfg.configure_expr_kind(&mut expr.kind);
|
||||||
|
|
||||||
// ignore derives so they remain unused
|
if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
|
||||||
let (attr, after_derive) = self.classify_nonitem(&mut expr);
|
|
||||||
|
|
||||||
if let Some(ref attr_value) = attr {
|
|
||||||
// Collect the invoc regardless of whether or not attributes are permitted here
|
// Collect the invoc regardless of whether or not attributes are permitted here
|
||||||
// expansion will eat the attribute so it won't error later.
|
// expansion will eat the attribute so it won't error later.
|
||||||
self.cfg.maybe_emit_expr_attr_err(attr_value);
|
attr.0.as_ref().map(|attr| self.cfg.maybe_emit_expr_attr_err(attr));
|
||||||
|
|
||||||
// AstFragmentKind::Expr requires the macro to emit an expression.
|
// AstFragmentKind::Expr requires the macro to emit an expression.
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Expr(P(expr)), AstFragmentKind::Expr)
|
||||||
attr,
|
|
||||||
vec![],
|
|
||||||
Annotatable::Expr(P(expr)),
|
|
||||||
AstFragmentKind::Expr,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_expr()
|
.make_expr()
|
||||||
.into_inner();
|
.into_inner();
|
||||||
}
|
}
|
||||||
|
@ -1186,16 +1149,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
|
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
|
||||||
let mut arm = configure!(self, arm);
|
let mut arm = configure!(self, arm);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut arm);
|
if let Some(attr) = self.take_first_attr(&mut arm) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Arm(arm), AstFragmentKind::Arms)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::Arm(arm),
|
|
||||||
AstFragmentKind::Arms,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_arms();
|
.make_arms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,16 +1161,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
|
fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
|
||||||
let mut field = configure!(self, field);
|
let mut field = configure!(self, field);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut field);
|
if let Some(attr) = self.take_first_attr(&mut field) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Field(field), AstFragmentKind::Fields)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::Field(field),
|
|
||||||
AstFragmentKind::Fields,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_fields();
|
.make_fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,16 +1173,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
|
fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
|
||||||
let mut fp = configure!(self, fp);
|
let mut fp = configure!(self, fp);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut fp);
|
if let Some(attr) = self.take_first_attr(&mut fp) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::FieldPat(fp), AstFragmentKind::FieldPats)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::FieldPat(fp),
|
|
||||||
AstFragmentKind::FieldPats,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_field_patterns();
|
.make_field_patterns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,16 +1185,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
|
fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
|
||||||
let mut p = configure!(self, p);
|
let mut p = configure!(self, p);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut p);
|
if let Some(attr) = self.take_first_attr(&mut p) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Param(p), AstFragmentKind::Params)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::Param(p),
|
|
||||||
AstFragmentKind::Params,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_params();
|
.make_params();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1262,16 +1197,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
|
fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
|
||||||
let mut sf = configure!(self, sf);
|
let mut sf = configure!(self, sf);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut sf);
|
if let Some(attr) = self.take_first_attr(&mut sf) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::StructField(sf), AstFragmentKind::StructFields)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::StructField(sf),
|
|
||||||
AstFragmentKind::StructFields,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_struct_fields();
|
.make_struct_fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1281,16 +1209,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
|
fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
|
||||||
let mut variant = configure!(self, variant);
|
let mut variant = configure!(self, variant);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut variant);
|
if let Some(attr) = self.take_first_attr(&mut variant) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Variant(variant), AstFragmentKind::Variants)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::Variant(variant),
|
|
||||||
AstFragmentKind::Variants,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_variants();
|
.make_variants();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,20 +1223,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
expr.filter_map(|mut expr| {
|
expr.filter_map(|mut expr| {
|
||||||
self.cfg.configure_expr_kind(&mut expr.kind);
|
self.cfg.configure_expr_kind(&mut expr.kind);
|
||||||
|
|
||||||
// Ignore derives so they remain unused.
|
if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
|
||||||
let (attr, after_derive) = self.classify_nonitem(&mut expr);
|
attr.0.as_ref().map(|attr| self.cfg.maybe_emit_expr_attr_err(attr));
|
||||||
|
|
||||||
if let Some(ref attr_value) = attr {
|
|
||||||
self.cfg.maybe_emit_expr_attr_err(attr_value);
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Expr(P(expr)), AstFragmentKind::OptExpr)
|
||||||
attr,
|
|
||||||
vec![],
|
|
||||||
Annotatable::Expr(P(expr)),
|
|
||||||
AstFragmentKind::OptExpr,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_opt_expr()
|
.make_opt_expr()
|
||||||
.map(|expr| expr.into_inner());
|
.map(|expr| expr.into_inner());
|
||||||
}
|
}
|
||||||
|
@ -1354,25 +1266,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
|
|
||||||
// we'll expand attributes on expressions separately
|
// we'll expand attributes on expressions separately
|
||||||
if !stmt.is_expr() {
|
if !stmt.is_expr() {
|
||||||
let (attr, derives, after_derive) = if stmt.is_item() {
|
// FIXME: Handle custom attributes on statements (#15701).
|
||||||
// FIXME: Handle custom attributes on statements (#15701)
|
let attr =
|
||||||
(None, vec![], false)
|
if stmt.is_item() { None } else { self.take_first_attr_no_derive(&mut stmt) };
|
||||||
} else {
|
|
||||||
// ignore derives on non-item statements so it falls through
|
|
||||||
// to the unused-attributes lint
|
|
||||||
let (attr, after_derive) = self.classify_nonitem(&mut stmt);
|
|
||||||
(attr, vec![], after_derive)
|
|
||||||
};
|
|
||||||
|
|
||||||
if attr.is_some() || !derives.is_empty() {
|
if let Some(attr) = attr {
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Stmt(P(stmt)), AstFragmentKind::Stmts)
|
||||||
attr,
|
|
||||||
derives,
|
|
||||||
Annotatable::Stmt(P(stmt)),
|
|
||||||
AstFragmentKind::Stmts,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_stmts();
|
.make_stmts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1412,16 +1312,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||||
let mut item = configure!(self, item);
|
let mut item = configure!(self, item);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut item);
|
if let Some(attr) = self.take_first_attr(&mut item) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::Item(item), AstFragmentKind::Items)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::Item(item),
|
|
||||||
AstFragmentKind::Items,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_items();
|
.make_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1515,16 +1408,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
||||||
let mut item = configure!(self, item);
|
let mut item = configure!(self, item);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut item);
|
if let Some(attr) = self.take_first_attr(&mut item) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::TraitItem(item), AstFragmentKind::TraitItems)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::TraitItem(item),
|
|
||||||
AstFragmentKind::TraitItems,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_trait_items();
|
.make_trait_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,16 +1431,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
||||||
let mut item = configure!(self, item);
|
let mut item = configure!(self, item);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut item);
|
if let Some(attr) = self.take_first_attr(&mut item) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(attr, Annotatable::ImplItem(item), AstFragmentKind::ImplItems)
|
||||||
attr,
|
|
||||||
traits,
|
|
||||||
Annotatable::ImplItem(item),
|
|
||||||
AstFragmentKind::ImplItems,
|
|
||||||
after_derive,
|
|
||||||
)
|
|
||||||
.make_impl_items();
|
.make_impl_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1595,16 +1474,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
&mut self,
|
&mut self,
|
||||||
mut foreign_item: P<ast::ForeignItem>,
|
mut foreign_item: P<ast::ForeignItem>,
|
||||||
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut foreign_item);
|
if let Some(attr) = self.take_first_attr(&mut foreign_item) {
|
||||||
|
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(
|
||||||
attr,
|
attr,
|
||||||
traits,
|
|
||||||
Annotatable::ForeignItem(foreign_item),
|
Annotatable::ForeignItem(foreign_item),
|
||||||
AstFragmentKind::ForeignItems,
|
AstFragmentKind::ForeignItems,
|
||||||
after_derive,
|
|
||||||
)
|
)
|
||||||
.make_foreign_items();
|
.make_foreign_items();
|
||||||
}
|
}
|
||||||
|
@ -1639,15 +1514,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
) -> SmallVec<[ast::GenericParam; 1]> {
|
) -> SmallVec<[ast::GenericParam; 1]> {
|
||||||
let mut param = configure!(self, param);
|
let mut param = configure!(self, param);
|
||||||
|
|
||||||
let (attr, traits, after_derive) = self.classify_item(&mut param);
|
if let Some(attr) = self.take_first_attr(&mut param) {
|
||||||
if attr.is_some() || !traits.is_empty() {
|
|
||||||
return self
|
return self
|
||||||
.collect_attr(
|
.collect_attr(
|
||||||
attr,
|
attr,
|
||||||
traits,
|
|
||||||
Annotatable::GenericParam(param),
|
Annotatable::GenericParam(param),
|
||||||
AstFragmentKind::GenericParams,
|
AstFragmentKind::GenericParams,
|
||||||
after_derive,
|
|
||||||
)
|
)
|
||||||
.make_generic_params();
|
.make_generic_params();
|
||||||
}
|
}
|
||||||
|
@ -1830,7 +1702,4 @@ impl<'feat> ExpansionConfig<'feat> {
|
||||||
fn proc_macro_hygiene(&self) -> bool {
|
fn proc_macro_hygiene(&self) -> bool {
|
||||||
self.features.map_or(false, |features| features.proc_macro_hygiene)
|
self.features.map_or(false, |features| features.proc_macro_hygiene)
|
||||||
}
|
}
|
||||||
fn custom_inner_attributes(&self) -> bool {
|
|
||||||
self.features.map_or(false, |features| features.custom_inner_attributes)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,38 +75,9 @@ impl MultiItemModifier for ProcMacroDerive {
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
let item = match item {
|
let item = match item {
|
||||||
Annotatable::Arm(..)
|
Annotatable::Item(item) => token::NtItem(item),
|
||||||
| Annotatable::Field(..)
|
_ => unreachable!(),
|
||||||
| Annotatable::FieldPat(..)
|
|
||||||
| Annotatable::GenericParam(..)
|
|
||||||
| Annotatable::Param(..)
|
|
||||||
| Annotatable::StructField(..)
|
|
||||||
| Annotatable::Variant(..) => panic!("unexpected annotatable"),
|
|
||||||
Annotatable::Item(item) => item,
|
|
||||||
Annotatable::ImplItem(_)
|
|
||||||
| Annotatable::TraitItem(_)
|
|
||||||
| Annotatable::ForeignItem(_)
|
|
||||||
| Annotatable::Stmt(_)
|
|
||||||
| Annotatable::Expr(_) => {
|
|
||||||
ecx.span_err(
|
|
||||||
span,
|
|
||||||
"proc-macro derives may only be applied to a struct, enum, or union",
|
|
||||||
);
|
|
||||||
return ExpandResult::Ready(Vec::new());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
match item.kind {
|
|
||||||
ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..) => {}
|
|
||||||
_ => {
|
|
||||||
ecx.span_err(
|
|
||||||
span,
|
|
||||||
"proc-macro derives may only be applied to a struct, enum, or union",
|
|
||||||
);
|
|
||||||
return ExpandResult::Ready(Vec::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = token::NtItem(item);
|
|
||||||
let input = if item.pretty_printing_compatibility_hack() {
|
let input = if item.pretty_printing_compatibility_hack() {
|
||||||
TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into()
|
TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,6 +39,9 @@ pub enum NonMacroAttrKind {
|
||||||
Tool,
|
Tool,
|
||||||
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
|
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
|
||||||
DeriveHelper,
|
DeriveHelper,
|
||||||
|
/// Single-segment custom attribute registered by a derive macro
|
||||||
|
/// but used before that derive macro was expanded (deprecated).
|
||||||
|
DeriveHelperCompat,
|
||||||
/// Single-segment custom attribute registered with `#[register_attr]`.
|
/// Single-segment custom attribute registered with `#[register_attr]`.
|
||||||
Registered,
|
Registered,
|
||||||
}
|
}
|
||||||
|
@ -370,7 +373,9 @@ impl NonMacroAttrKind {
|
||||||
match self {
|
match self {
|
||||||
NonMacroAttrKind::Builtin => "built-in attribute",
|
NonMacroAttrKind::Builtin => "built-in attribute",
|
||||||
NonMacroAttrKind::Tool => "tool attribute",
|
NonMacroAttrKind::Tool => "tool attribute",
|
||||||
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
|
NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
|
||||||
|
"derive helper attribute"
|
||||||
|
}
|
||||||
NonMacroAttrKind::Registered => "explicitly registered attribute",
|
NonMacroAttrKind::Registered => "explicitly registered attribute",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,7 +390,9 @@ impl NonMacroAttrKind {
|
||||||
/// Users of some attributes cannot mark them as used, so they are considered always used.
|
/// Users of some attributes cannot mark them as used, so they are considered always used.
|
||||||
pub fn is_used(self) -> bool {
|
pub fn is_used(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true,
|
NonMacroAttrKind::Tool
|
||||||
|
| NonMacroAttrKind::DeriveHelper
|
||||||
|
| NonMacroAttrKind::DeriveHelperCompat => true,
|
||||||
NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
|
NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,14 +312,13 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_needs_tokens(attrs: &[ast::Attribute]) -> bool {
|
pub fn maybe_needs_tokens(attrs: &[ast::Attribute]) -> bool {
|
||||||
|
// One of the attributes may either itself be a macro, or apply derive macros (`derive`),
|
||||||
|
// or expand to macro attributes (`cfg_attr`).
|
||||||
attrs.iter().any(|attr| {
|
attrs.iter().any(|attr| {
|
||||||
if let Some(ident) = attr.ident() {
|
attr.ident().map_or(true, |ident| {
|
||||||
ident.name == sym::derive
|
ident.name == sym::derive
|
||||||
// This might apply a custom attribute/derive
|
|| ident.name == sym::cfg_attr
|
||||||
|| ident.name == sym::cfg_attr
|
|| !rustc_feature::is_builtin_attr_name(ident.name)
|
||||||
|| !rustc_feature::is_builtin_attr_name(ident.name)
|
})
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,7 +609,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scope::DeriveHelpersCompat => {
|
Scope::DeriveHelpersCompat => {
|
||||||
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
|
||||||
if filter_fn(res) {
|
if filter_fn(res) {
|
||||||
for derive in parent_scope.derives {
|
for derive in parent_scope.derives {
|
||||||
let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
|
let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
|
||||||
|
|
|
@ -12,24 +12,24 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_attr::StabilityLevel;
|
use rustc_attr::StabilityLevel;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::ptr_key::PtrKey;
|
use rustc_data_structures::ptr_key::PtrKey;
|
||||||
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
|
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
|
||||||
use rustc_expand::compile_declarative_macro;
|
use rustc_expand::compile_declarative_macro;
|
||||||
use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
|
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind};
|
||||||
use rustc_feature::is_builtin_attr_name;
|
use rustc_feature::is_builtin_attr_name;
|
||||||
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
|
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
|
||||||
use rustc_hir::def_id;
|
use rustc_hir::def_id;
|
||||||
use rustc_middle::middle::stability;
|
use rustc_middle::middle::stability;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_session::lint::builtin::UNUSED_MACROS;
|
use rustc_session::lint::builtin::UNUSED_MACROS;
|
||||||
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind};
|
use rustc_span::hygiene::{self, ExpnData, ExpnId, ExpnKind};
|
||||||
|
use rustc_span::hygiene::{AstPass, MacroKind};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use rustc_data_structures::sync::Lrc;
|
|
||||||
use rustc_span::hygiene::{AstPass, MacroKind};
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
|
@ -241,15 +241,20 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (path, kind, derives, after_derive) = match invoc.kind {
|
let (path, kind, inner_attr, derives, after_derive) = match invoc.kind {
|
||||||
InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => (
|
InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => (
|
||||||
&attr.get_normal_item().path,
|
&attr.get_normal_item().path,
|
||||||
MacroKind::Attr,
|
MacroKind::Attr,
|
||||||
|
attr.style == ast::AttrStyle::Inner,
|
||||||
self.arenas.alloc_ast_paths(derives),
|
self.arenas.alloc_ast_paths(derives),
|
||||||
after_derive,
|
after_derive,
|
||||||
),
|
),
|
||||||
InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang, &[][..], false),
|
InvocationKind::Bang { ref mac, .. } => {
|
||||||
InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive, &[][..], false),
|
(&mac.path, MacroKind::Bang, false, &[][..], false)
|
||||||
|
}
|
||||||
|
InvocationKind::Derive { ref path, .. } => {
|
||||||
|
(path, MacroKind::Derive, false, &[][..], false)
|
||||||
|
}
|
||||||
InvocationKind::DeriveContainer { ref derives, .. } => {
|
InvocationKind::DeriveContainer { ref derives, .. } => {
|
||||||
// Block expansion of the container until we resolve all derives in it.
|
// Block expansion of the container until we resolve all derives in it.
|
||||||
// This is required for two reasons:
|
// This is required for two reasons:
|
||||||
|
@ -281,7 +286,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
ext.helper_attrs.iter().map(|name| Ident::new(*name, span)),
|
ext.helper_attrs.iter().map(|name| Ident::new(*name, span)),
|
||||||
);
|
);
|
||||||
if ext.is_derive_copy {
|
if ext.is_derive_copy {
|
||||||
self.add_derive_copy(invoc_id);
|
self.containers_deriving_copy.insert(invoc_id);
|
||||||
}
|
}
|
||||||
ext
|
ext
|
||||||
}
|
}
|
||||||
|
@ -299,8 +304,17 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
|
|
||||||
// Derives are not included when `invocations` are collected, so we have to add them here.
|
// Derives are not included when `invocations` are collected, so we have to add them here.
|
||||||
let parent_scope = &ParentScope { derives, ..parent_scope };
|
let parent_scope = &ParentScope { derives, ..parent_scope };
|
||||||
|
let require_inert = !invoc.fragment_kind.supports_macro_expansion();
|
||||||
let node_id = self.lint_node_id(eager_expansion_root);
|
let node_id = self.lint_node_id(eager_expansion_root);
|
||||||
let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, node_id, force)?;
|
let (ext, res) = self.smart_resolve_macro_path(
|
||||||
|
path,
|
||||||
|
kind,
|
||||||
|
require_inert,
|
||||||
|
inner_attr,
|
||||||
|
parent_scope,
|
||||||
|
node_id,
|
||||||
|
force,
|
||||||
|
)?;
|
||||||
|
|
||||||
let span = invoc.span();
|
let span = invoc.span();
|
||||||
invoc_id.set_expn_data(ext.expn_data(
|
invoc_id.set_expn_data(ext.expn_data(
|
||||||
|
@ -318,29 +332,6 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
|
self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
match invoc.fragment_kind {
|
|
||||||
AstFragmentKind::Arms
|
|
||||||
| AstFragmentKind::Fields
|
|
||||||
| AstFragmentKind::FieldPats
|
|
||||||
| AstFragmentKind::GenericParams
|
|
||||||
| AstFragmentKind::Params
|
|
||||||
| AstFragmentKind::StructFields
|
|
||||||
| AstFragmentKind::Variants => {
|
|
||||||
if let Res::Def(..) = res {
|
|
||||||
self.session.span_err(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"expected an inert attribute, found {} {}",
|
|
||||||
res.article(),
|
|
||||||
res.descr()
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return Ok(InvocationRes::Single(self.dummy_ext(kind)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(InvocationRes::Single(ext))
|
Ok(InvocationRes::Single(ext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,10 +351,6 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
self.containers_deriving_copy.contains(&expn_id)
|
self.containers_deriving_copy.contains(&expn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_derive_copy(&mut self, expn_id: ExpnId) {
|
|
||||||
self.containers_deriving_copy.insert(expn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The function that implements the resolution logic of `#[cfg_accessible(path)]`.
|
// The function that implements the resolution logic of `#[cfg_accessible(path)]`.
|
||||||
// Returns true if the path can certainly be resolved in one of three namespaces,
|
// Returns true if the path can certainly be resolved in one of three namespaces,
|
||||||
// returns false if the path certainly cannot be resolved in any of the three namespaces.
|
// returns false if the path certainly cannot be resolved in any of the three namespaces.
|
||||||
|
@ -403,10 +390,14 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
|
|
||||||
impl<'a> Resolver<'a> {
|
impl<'a> Resolver<'a> {
|
||||||
/// Resolve macro path with error reporting and recovery.
|
/// Resolve macro path with error reporting and recovery.
|
||||||
|
/// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
|
||||||
|
/// for better error recovery.
|
||||||
fn smart_resolve_macro_path(
|
fn smart_resolve_macro_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
kind: MacroKind,
|
kind: MacroKind,
|
||||||
|
require_inert: bool,
|
||||||
|
inner_attr: bool,
|
||||||
parent_scope: &ParentScope<'a>,
|
parent_scope: &ParentScope<'a>,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
force: bool,
|
force: bool,
|
||||||
|
@ -414,7 +405,6 @@ impl<'a> Resolver<'a> {
|
||||||
let (ext, res) = match self.resolve_macro_path(path, Some(kind), parent_scope, true, force)
|
let (ext, res) = match self.resolve_macro_path(path, Some(kind), parent_scope, true, force)
|
||||||
{
|
{
|
||||||
Ok((Some(ext), res)) => (ext, res),
|
Ok((Some(ext), res)) => (ext, res),
|
||||||
// Use dummy syntax extensions for unresolved macros for better recovery.
|
|
||||||
Ok((None, res)) => (self.dummy_ext(kind), res),
|
Ok((None, res)) => (self.dummy_ext(kind), res),
|
||||||
Err(Determinacy::Determined) => (self.dummy_ext(kind), Res::Err),
|
Err(Determinacy::Determined) => (self.dummy_ext(kind), Res::Err),
|
||||||
Err(Determinacy::Undetermined) => return Err(Indeterminate),
|
Err(Determinacy::Undetermined) => return Err(Indeterminate),
|
||||||
|
@ -451,19 +441,43 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
self.check_stability_and_deprecation(&ext, path, node_id);
|
self.check_stability_and_deprecation(&ext, path, node_id);
|
||||||
|
|
||||||
Ok(if ext.macro_kind() != kind {
|
let unexpected_res = if ext.macro_kind() != kind {
|
||||||
let expected = kind.descr_expected();
|
Some((kind.article(), kind.descr_expected()))
|
||||||
|
} else if require_inert && matches!(res, Res::Def(..)) {
|
||||||
|
Some(("a", "non-macro attribute"))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some((article, expected)) = unexpected_res {
|
||||||
let path_str = pprust::path_to_string(path);
|
let path_str = pprust::path_to_string(path);
|
||||||
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path_str);
|
let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path_str);
|
||||||
self.session
|
self.session
|
||||||
.struct_span_err(path.span, &msg)
|
.struct_span_err(path.span, &msg)
|
||||||
.span_label(path.span, format!("not {} {}", kind.article(), expected))
|
.span_label(path.span, format!("not {} {}", article, expected))
|
||||||
.emit();
|
.emit();
|
||||||
// Use dummy syntax extensions for unexpected macro kinds for better recovery.
|
return Ok((self.dummy_ext(kind), Res::Err));
|
||||||
(self.dummy_ext(kind), Res::Err)
|
}
|
||||||
} else {
|
|
||||||
(ext, res)
|
// We are trying to avoid reporting this error if other related errors were reported.
|
||||||
})
|
if inner_attr
|
||||||
|
&& !self.session.features_untracked().custom_inner_attributes
|
||||||
|
&& path != &sym::test
|
||||||
|
&& res != Res::Err
|
||||||
|
{
|
||||||
|
feature_err(
|
||||||
|
&self.session.parse_sess,
|
||||||
|
sym::custom_inner_attributes,
|
||||||
|
path.span,
|
||||||
|
match res {
|
||||||
|
Res::Def(..) => "inner macro attributes are unstable",
|
||||||
|
Res::NonMacroAttr(..) => "custom inner attributes are unstable",
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((ext, res))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_macro_path(
|
pub fn resolve_macro_path(
|
||||||
|
@ -568,10 +582,9 @@ impl<'a> Resolver<'a> {
|
||||||
struct Flags: u8 {
|
struct Flags: u8 {
|
||||||
const MACRO_RULES = 1 << 0;
|
const MACRO_RULES = 1 << 0;
|
||||||
const MODULE = 1 << 1;
|
const MODULE = 1 << 1;
|
||||||
const DERIVE_HELPER_COMPAT = 1 << 2;
|
const MISC_SUGGEST_CRATE = 1 << 2;
|
||||||
const MISC_SUGGEST_CRATE = 1 << 3;
|
const MISC_SUGGEST_SELF = 1 << 3;
|
||||||
const MISC_SUGGEST_SELF = 1 << 4;
|
const MISC_FROM_PRELUDE = 1 << 4;
|
||||||
const MISC_FROM_PRELUDE = 1 << 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,14 +659,11 @@ impl<'a> Resolver<'a> {
|
||||||
) {
|
) {
|
||||||
Ok((Some(ext), _)) => {
|
Ok((Some(ext), _)) => {
|
||||||
if ext.helper_attrs.contains(&ident.name) {
|
if ext.helper_attrs.contains(&ident.name) {
|
||||||
let binding = (
|
result = ok(
|
||||||
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
|
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
|
||||||
ty::Visibility::Public,
|
|
||||||
derive.span,
|
derive.span,
|
||||||
ExpnId::root(),
|
this.arenas,
|
||||||
)
|
);
|
||||||
.to_name_binding(this.arenas);
|
|
||||||
result = Ok((binding, Flags::DERIVE_HELPER_COMPAT));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,17 +809,15 @@ impl<'a> Resolver<'a> {
|
||||||
let (res, innermost_res) = (binding.res(), innermost_binding.res());
|
let (res, innermost_res) = (binding.res(), innermost_binding.res());
|
||||||
if res != innermost_res {
|
if res != innermost_res {
|
||||||
let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
|
let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
|
||||||
let is_derive_helper_compat = |res, flags: Flags| {
|
let derive_helper_compat =
|
||||||
res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper)
|
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
|
||||||
&& flags.contains(Flags::DERIVE_HELPER_COMPAT)
|
|
||||||
};
|
|
||||||
|
|
||||||
let ambiguity_error_kind = if is_import {
|
let ambiguity_error_kind = if is_import {
|
||||||
Some(AmbiguityKind::Import)
|
Some(AmbiguityKind::Import)
|
||||||
} else if innermost_res == builtin || res == builtin {
|
} else if innermost_res == builtin || res == builtin {
|
||||||
Some(AmbiguityKind::BuiltinAttr)
|
Some(AmbiguityKind::BuiltinAttr)
|
||||||
} else if is_derive_helper_compat(innermost_res, innermost_flags)
|
} else if innermost_res == derive_helper_compat
|
||||||
|| is_derive_helper_compat(res, flags)
|
|| res == derive_helper_compat
|
||||||
{
|
{
|
||||||
Some(AmbiguityKind::DeriveHelper)
|
Some(AmbiguityKind::DeriveHelper)
|
||||||
} else if innermost_flags.contains(Flags::MACRO_RULES)
|
} else if innermost_flags.contains(Flags::MACRO_RULES)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
enum FooEnum {
|
enum FooEnum {
|
||||||
#[test]
|
#[test]
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
Bar(i32),
|
Bar(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FooStruct {
|
struct FooStruct {
|
||||||
#[test]
|
#[test]
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
bar: i32,
|
bar: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,20 +21,20 @@ fn main() {
|
||||||
match foo_struct {
|
match foo_struct {
|
||||||
FooStruct {
|
FooStruct {
|
||||||
#[test] bar
|
#[test] bar
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
} => {}
|
} => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match 1 {
|
match 1 {
|
||||||
0 => {}
|
0 => {}
|
||||||
#[test]
|
#[test]
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _another_foo_strunct = FooStruct {
|
let _another_foo_strunct = FooStruct {
|
||||||
#[test]
|
#[test]
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
bar: 1,
|
bar: 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/attrs-resolution-errors.rs:2:5
|
--> $DIR/attrs-resolution-errors.rs:2:7
|
||||||
|
|
|
|
||||||
LL | #[test]
|
LL | #[test]
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/attrs-resolution-errors.rs:8:5
|
--> $DIR/attrs-resolution-errors.rs:8:7
|
||||||
|
|
|
|
||||||
LL | #[test]
|
LL | #[test]
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/attrs-resolution-errors.rs:23:13
|
--> $DIR/attrs-resolution-errors.rs:23:15
|
||||||
|
|
|
|
||||||
LL | #[test] bar
|
LL | #[test] bar
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/attrs-resolution-errors.rs:30:9
|
--> $DIR/attrs-resolution-errors.rs:30:11
|
||||||
|
|
|
|
||||||
LL | #[test]
|
LL | #[test]
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/attrs-resolution-errors.rs:36:9
|
--> $DIR/attrs-resolution-errors.rs:36:11
|
||||||
|
|
|
|
||||||
LL | #[test]
|
LL | #[test]
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![feature(cfg_accessible)]
|
#![feature(cfg_accessible)]
|
||||||
|
|
||||||
#[cfg_accessible(Z)] //~ ERROR cannot determine whether the path is accessible or not
|
#[cfg_accessible(Z)] // OK, recovered after the other `cfg_accessible` produces an error.
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
#[cfg_accessible(S)] //~ ERROR cannot determine whether the path is accessible or not
|
#[cfg_accessible(S)] //~ ERROR cannot determine whether the path is accessible or not
|
||||||
|
|
|
@ -4,11 +4,5 @@ error: cannot determine whether the path is accessible or not
|
||||||
LL | #[cfg_accessible(S)]
|
LL | #[cfg_accessible(S)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: cannot determine whether the path is accessible or not
|
error: aborting due to previous error
|
||||||
--> $DIR/cfg_accessible-stuck.rs:3:1
|
|
||||||
|
|
|
||||||
LL | #[cfg_accessible(Z)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
|
#![derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Copy`
|
//~| ERROR cannot determine resolution for the derive macro `Copy`
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Copy`
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,14 +12,6 @@ LL | #![derive(Copy)]
|
||||||
|
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
= note: import resolution is stuck, try simplifying macro imports
|
||||||
|
|
||||||
error: cannot determine resolution for the derive macro `Copy`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/issue-36617.rs:1:11
|
|
||||||
|
|
|
||||||
LL | #![derive(Copy)]
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0774`.
|
For more information about this error, try `rustc --explain E0774`.
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
fn foo<#[derive(Debug)] T>() {
|
fn foo<#[derive(Debug)] T>() {
|
||||||
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
||||||
//~| ERROR expected an inert attribute, found a derive macro
|
|
||||||
match 0 {
|
match 0 {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
||||||
//~| ERROR expected an inert attribute, found a derive macro
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,24 +4,12 @@ error[E0774]: `derive` may only be applied to structs, enums and unions
|
||||||
LL | fn foo<#[derive(Debug)] T>() {
|
LL | fn foo<#[derive(Debug)] T>() {
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: expected an inert attribute, found a derive macro
|
|
||||||
--> $DIR/issue-49934-errors.rs:1:17
|
|
||||||
|
|
|
||||||
LL | fn foo<#[derive(Debug)] T>() {
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error[E0774]: `derive` may only be applied to structs, enums and unions
|
error[E0774]: `derive` may only be applied to structs, enums and unions
|
||||||
--> $DIR/issue-49934-errors.rs:5:9
|
--> $DIR/issue-49934-errors.rs:4:9
|
||||||
|
|
|
|
||||||
LL | #[derive(Debug)]
|
LL | #[derive(Debug)]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: expected an inert attribute, found a derive macro
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/issue-49934-errors.rs:5:18
|
|
||||||
|
|
|
||||||
LL | #[derive(Debug)]
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0774`.
|
For more information about this error, try `rustc --explain E0774`.
|
||||||
|
|
|
@ -4,7 +4,6 @@ struct CLI {
|
||||||
#[derive(parse())]
|
#[derive(parse())]
|
||||||
//~^ ERROR traits in `#[derive(...)]` don't accept arguments
|
//~^ ERROR traits in `#[derive(...)]` don't accept arguments
|
||||||
//~| ERROR cannot find derive macro `parse` in this scope
|
//~| ERROR cannot find derive macro `parse` in this scope
|
||||||
//~| ERROR cannot find derive macro `parse` in this scope
|
|
||||||
path: (),
|
path: (),
|
||||||
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
//~^ ERROR `derive` may only be applied to structs, enums and unions
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | #[derive(parse())]
|
||||||
| ^^ help: remove the arguments
|
| ^^ help: remove the arguments
|
||||||
|
|
||||||
error[E0774]: `derive` may only be applied to structs, enums and unions
|
error[E0774]: `derive` may only be applied to structs, enums and unions
|
||||||
--> $DIR/issue-69341-malformed-derive-inert.rs:8:5
|
--> $DIR/issue-69341-malformed-derive-inert.rs:7:5
|
||||||
|
|
|
|
||||||
LL | path: (),
|
LL | path: (),
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -16,12 +16,6 @@ error: cannot find derive macro `parse` in this scope
|
||||||
LL | #[derive(parse())]
|
LL | #[derive(parse())]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: cannot find derive macro `parse` in this scope
|
error: aborting due to 3 previous errors
|
||||||
--> $DIR/issue-69341-malformed-derive-inert.rs:4:14
|
|
||||||
|
|
|
||||||
LL | #[derive(parse())]
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0774`.
|
For more information about this error, try `rustc --explain E0774`.
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
extern crate test_macros;
|
extern crate test_macros;
|
||||||
|
|
||||||
fn _test_inner() {
|
fn _test_inner() {
|
||||||
#![empty_attr] //~ ERROR: non-builtin inner attributes are unstable
|
#![empty_attr] //~ ERROR: inner macro attributes are unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
mod _test2_inner {
|
mod _test2_inner {
|
||||||
#![empty_attr] //~ ERROR: non-builtin inner attributes are unstable
|
#![empty_attr] //~ ERROR: inner macro attributes are unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
#[empty_attr = "y"] //~ ERROR: key-value macro attributes are not supported
|
#[empty_attr = "y"] //~ ERROR: key-value macro attributes are not supported
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
error[E0658]: non-builtin inner attributes are unstable
|
error[E0658]: inner macro attributes are unstable
|
||||||
--> $DIR/proc-macro-gates.rs:10:5
|
--> $DIR/proc-macro-gates.rs:10:8
|
||||||
|
|
|
|
||||||
LL | #![empty_attr]
|
LL | #![empty_attr]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
||||||
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: non-builtin inner attributes are unstable
|
error[E0658]: inner macro attributes are unstable
|
||||||
--> $DIR/proc-macro-gates.rs:14:5
|
--> $DIR/proc-macro-gates.rs:14:8
|
||||||
|
|
|
|
||||||
LL | #![empty_attr]
|
LL | #![empty_attr]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
||||||
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
||||||
|
|
|
@ -10,11 +10,11 @@ extern crate test_macros;
|
||||||
// should either require a feature gate or not be allowed on stable.
|
// should either require a feature gate or not be allowed on stable.
|
||||||
|
|
||||||
fn _test6<#[empty_attr] T>() {}
|
fn _test6<#[empty_attr] T>() {}
|
||||||
//~^ ERROR: expected an inert attribute, found an attribute macro
|
//~^ ERROR: expected non-macro attribute, found attribute macro
|
||||||
|
|
||||||
fn _test7() {
|
fn _test7() {
|
||||||
match 1 {
|
match 1 {
|
||||||
#[empty_attr] //~ ERROR: expected an inert attribute, found an attribute macro
|
#[empty_attr] //~ ERROR: expected non-macro attribute, found attribute macro
|
||||||
0 => {}
|
0 => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `empty_attr`
|
||||||
--> $DIR/proc-macro-gates2.rs:12:11
|
--> $DIR/proc-macro-gates2.rs:12:13
|
||||||
|
|
|
|
||||||
LL | fn _test6<#[empty_attr] T>() {}
|
LL | fn _test6<#[empty_attr] T>() {}
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `empty_attr`
|
||||||
--> $DIR/proc-macro-gates2.rs:17:9
|
--> $DIR/proc-macro-gates2.rs:17:11
|
||||||
|
|
|
|
||||||
LL | #[empty_attr]
|
LL | #[empty_attr]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ extern "C" {
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -19,7 +19,7 @@ type FnType = fn(
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: u32,
|
#[test] a: u32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -34,7 +34,7 @@ pub fn foo(
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: u32,
|
#[test] a: u32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -54,7 +54,7 @@ impl SelfStruct {
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -69,7 +69,7 @@ impl SelfStruct {
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -90,7 +90,7 @@ impl RefStruct {
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -109,7 +109,7 @@ trait RefTrait {
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -124,7 +124,7 @@ trait RefTrait {
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -144,7 +144,7 @@ impl RefTrait for RefStruct {
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: i32,
|
#[test] a: i32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Baz
|
/// Baz
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -161,7 +161,7 @@ fn main() {
|
||||||
/// Foo
|
/// Foo
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[test] a: u32,
|
#[test] a: u32,
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
/// Bar
|
/// Bar
|
||||||
//~^ ERROR documentation comments cannot be applied to function
|
//~^ ERROR documentation comments cannot be applied to function
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
|
@ -1,62 +1,62 @@
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:5:9
|
--> $DIR/param-attrs-builtin-attrs.rs:5:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:21:5
|
--> $DIR/param-attrs-builtin-attrs.rs:21:7
|
||||||
|
|
|
|
||||||
LL | #[test] a: u32,
|
LL | #[test] a: u32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:36:5
|
--> $DIR/param-attrs-builtin-attrs.rs:36:7
|
||||||
|
|
|
|
||||||
LL | #[test] a: u32,
|
LL | #[test] a: u32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:56:9
|
--> $DIR/param-attrs-builtin-attrs.rs:56:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:71:9
|
--> $DIR/param-attrs-builtin-attrs.rs:71:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:92:9
|
--> $DIR/param-attrs-builtin-attrs.rs:92:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:111:9
|
--> $DIR/param-attrs-builtin-attrs.rs:111:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:126:9
|
--> $DIR/param-attrs-builtin-attrs.rs:126:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:146:9
|
--> $DIR/param-attrs-builtin-attrs.rs:146:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: i32,
|
LL | #[test] a: i32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `test`
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:163:9
|
--> $DIR/param-attrs-builtin-attrs.rs:163:11
|
||||||
|
|
|
|
||||||
LL | #[test] a: u32,
|
LL | #[test] a: u32,
|
||||||
| ^^^^^^^
|
| ^^^^ not a non-macro attribute
|
||||||
|
|
||||||
error: documentation comments cannot be applied to function parameters
|
error: documentation comments cannot be applied to function parameters
|
||||||
--> $DIR/param-attrs-builtin-attrs.rs:3:9
|
--> $DIR/param-attrs-builtin-attrs.rs:3:9
|
||||||
|
|
|
@ -8,58 +8,58 @@ use ident_mac::id;
|
||||||
struct W(u8);
|
struct W(u8);
|
||||||
|
|
||||||
extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
|
|
||||||
unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
|
unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
|
|
||||||
type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
|
|
||||||
fn free(#[id] arg1: u8) {
|
fn free(#[id] arg1: u8) {
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
let lam = |#[id] W(x), #[id] y: usize| ();
|
let lam = |#[id] W(x), #[id] y: usize| ();
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
}
|
}
|
||||||
|
|
||||||
impl W {
|
impl W {
|
||||||
fn inherent1(#[id] self, #[id] arg1: u8) {}
|
fn inherent1(#[id] self, #[id] arg1: u8) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
}
|
}
|
||||||
|
|
||||||
trait A {
|
trait A {
|
||||||
fn trait1(#[id] self, #[id] arg1: u8);
|
fn trait1(#[id] self, #[id] arg1: u8);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn trait2(#[id] &self, #[id] arg1: u8);
|
fn trait2(#[id] &self, #[id] arg1: u8);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
||||||
//~^ ERROR expected an inert attribute, found an attribute macro
|
//~^ ERROR expected non-macro attribute, found attribute macro
|
||||||
//~| ERROR expected an inert attribute, found an attribute macro
|
//~| ERROR expected non-macro attribute, found attribute macro
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,176 +1,176 @@
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:10:21
|
--> $DIR/proc-macro-cannot-be-used.rs:10:23
|
||||||
|
|
|
|
||||||
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:10:38
|
--> $DIR/proc-macro-cannot-be-used.rs:10:40
|
||||||
|
|
|
|
||||||
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:14:38
|
--> $DIR/proc-macro-cannot-be-used.rs:14:40
|
||||||
|
|
|
|
||||||
LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
|
LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:17:28
|
--> $DIR/proc-macro-cannot-be-used.rs:17:30
|
||||||
|
|
|
|
||||||
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:17:38
|
--> $DIR/proc-macro-cannot-be-used.rs:17:40
|
||||||
|
|
|
|
||||||
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:21:9
|
--> $DIR/proc-macro-cannot-be-used.rs:21:11
|
||||||
|
|
|
|
||||||
LL | fn free(#[id] arg1: u8) {
|
LL | fn free(#[id] arg1: u8) {
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:23:16
|
--> $DIR/proc-macro-cannot-be-used.rs:23:18
|
||||||
|
|
|
|
||||||
LL | let lam = |#[id] W(x), #[id] y: usize| ();
|
LL | let lam = |#[id] W(x), #[id] y: usize| ();
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:23:28
|
--> $DIR/proc-macro-cannot-be-used.rs:23:30
|
||||||
|
|
|
|
||||||
LL | let lam = |#[id] W(x), #[id] y: usize| ();
|
LL | let lam = |#[id] W(x), #[id] y: usize| ();
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:29:18
|
--> $DIR/proc-macro-cannot-be-used.rs:29:20
|
||||||
|
|
|
|
||||||
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
|
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:29:30
|
--> $DIR/proc-macro-cannot-be-used.rs:29:32
|
||||||
|
|
|
|
||||||
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
|
LL | fn inherent1(#[id] self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:32:18
|
--> $DIR/proc-macro-cannot-be-used.rs:32:20
|
||||||
|
|
|
|
||||||
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:32:31
|
--> $DIR/proc-macro-cannot-be-used.rs:32:33
|
||||||
|
|
|
|
||||||
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
LL | fn inherent2(#[id] &self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:35:22
|
--> $DIR/proc-macro-cannot-be-used.rs:35:24
|
||||||
|
|
|
|
||||||
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:35:42
|
--> $DIR/proc-macro-cannot-be-used.rs:35:44
|
||||||
|
|
|
|
||||||
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
LL | fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:38:22
|
--> $DIR/proc-macro-cannot-be-used.rs:38:24
|
||||||
|
|
|
|
||||||
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:38:45
|
--> $DIR/proc-macro-cannot-be-used.rs:38:47
|
||||||
|
|
|
|
||||||
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
LL | fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:41:38
|
--> $DIR/proc-macro-cannot-be-used.rs:41:40
|
||||||
|
|
|
|
||||||
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:41:54
|
--> $DIR/proc-macro-cannot-be-used.rs:41:56
|
||||||
|
|
|
|
||||||
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:47:15
|
--> $DIR/proc-macro-cannot-be-used.rs:47:17
|
||||||
|
|
|
|
||||||
LL | fn trait1(#[id] self, #[id] arg1: u8);
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:47:27
|
--> $DIR/proc-macro-cannot-be-used.rs:47:29
|
||||||
|
|
|
|
||||||
LL | fn trait1(#[id] self, #[id] arg1: u8);
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:50:15
|
--> $DIR/proc-macro-cannot-be-used.rs:50:17
|
||||||
|
|
|
|
||||||
LL | fn trait2(#[id] &self, #[id] arg1: u8);
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:50:28
|
--> $DIR/proc-macro-cannot-be-used.rs:50:30
|
||||||
|
|
|
|
||||||
LL | fn trait2(#[id] &self, #[id] arg1: u8);
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:53:19
|
--> $DIR/proc-macro-cannot-be-used.rs:53:21
|
||||||
|
|
|
|
||||||
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:53:39
|
--> $DIR/proc-macro-cannot-be-used.rs:53:41
|
||||||
|
|
|
|
||||||
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:56:19
|
--> $DIR/proc-macro-cannot-be-used.rs:56:21
|
||||||
|
|
|
|
||||||
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:56:42
|
--> $DIR/proc-macro-cannot-be-used.rs:56:44
|
||||||
|
|
|
|
||||||
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:56:58
|
--> $DIR/proc-macro-cannot-be-used.rs:56:60
|
||||||
|
|
|
|
||||||
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
LL | fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:60:38
|
--> $DIR/proc-macro-cannot-be-used.rs:60:40
|
||||||
|
|
|
|
||||||
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: expected an inert attribute, found an attribute macro
|
error: expected non-macro attribute, found attribute macro `id`
|
||||||
--> $DIR/proc-macro-cannot-be-used.rs:60:54
|
--> $DIR/proc-macro-cannot-be-used.rs:60:56
|
||||||
|
|
|
|
||||||
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
|
||||||
| ^^^^^
|
| ^^ not a non-macro attribute
|
||||||
|
|
||||||
error: aborting due to 29 previous errors
|
error: aborting due to 29 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#[foo]
|
#[foo]
|
||||||
mod foo {
|
mod foo {
|
||||||
#![foo] //~ ERROR non-builtin inner attributes are unstable
|
#![foo] //~ ERROR custom inner attributes are unstable
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0658]: non-builtin inner attributes are unstable
|
error[E0658]: custom inner attributes are unstable
|
||||||
--> $DIR/issue-36530.rs:9:5
|
--> $DIR/issue-36530.rs:9:8
|
||||||
|
|
|
|
||||||
LL | #![foo]
|
LL | #![foo]
|
||||||
| ^^^^^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
|
||||||
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Debug`
|
//~| ERROR cannot determine resolution for the derive macro `Debug`
|
||||||
//~| ERROR cannot determine resolution for the derive macro `PartialEq`
|
//~| ERROR cannot determine resolution for the derive macro `PartialEq`
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Eq`
|
//~| ERROR cannot determine resolution for the derive macro `Eq`
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Debug`
|
|
||||||
//~| ERROR cannot determine resolution for the derive macro `PartialEq`
|
|
||||||
//~| ERROR cannot determine resolution for the derive macro `Eq`
|
|
||||||
struct DerivedOn;
|
struct DerivedOn;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -28,30 +28,6 @@ LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
|
||||||
|
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
= note: import resolution is stuck, try simplifying macro imports
|
||||||
|
|
||||||
error: cannot determine resolution for the derive macro `Eq`
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/issue-43927-non-ADT-derive.rs:3:29
|
|
||||||
|
|
|
||||||
LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
|
|
||||||
| ^^
|
|
||||||
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
|
||||||
|
|
||||||
error: cannot determine resolution for the derive macro `PartialEq`
|
|
||||||
--> $DIR/issue-43927-non-ADT-derive.rs:3:18
|
|
||||||
|
|
|
||||||
LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
|
||||||
|
|
||||||
error: cannot determine resolution for the derive macro `Debug`
|
|
||||||
--> $DIR/issue-43927-non-ADT-derive.rs:3:11
|
|
||||||
|
|
|
||||||
LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
|
|
||||||
| ^^^^^
|
|
||||||
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0774`.
|
For more information about this error, try `rustc --explain E0774`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue