Ban custom inner attributes in expressions and statements
This commit is contained in:
parent
cb473c2c5b
commit
fe60f19f7e
5 changed files with 246 additions and 162 deletions
|
@ -206,30 +206,36 @@ ast_fragments! {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum SupportsMacroExpansion {
|
||||
No,
|
||||
Yes { supports_inner_attrs: bool },
|
||||
}
|
||||
|
||||
impl AstFragmentKind {
|
||||
crate fn dummy(self, span: Span) -> AstFragment {
|
||||
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 {
|
||||
pub fn supports_macro_expansion(self) -> SupportsMacroExpansion {
|
||||
match self {
|
||||
AstFragmentKind::OptExpr
|
||||
| AstFragmentKind::Expr
|
||||
| AstFragmentKind::Pat
|
||||
| AstFragmentKind::Ty
|
||||
| AstFragmentKind::Stmts
|
||||
| AstFragmentKind::Items
|
||||
| AstFragmentKind::Ty
|
||||
| AstFragmentKind::Pat => SupportsMacroExpansion::Yes { supports_inner_attrs: false },
|
||||
AstFragmentKind::Items
|
||||
| AstFragmentKind::TraitItems
|
||||
| AstFragmentKind::ImplItems
|
||||
| AstFragmentKind::ForeignItems => true,
|
||||
| AstFragmentKind::ForeignItems => {
|
||||
SupportsMacroExpansion::Yes { supports_inner_attrs: true }
|
||||
}
|
||||
AstFragmentKind::Arms
|
||||
| AstFragmentKind::Fields
|
||||
| AstFragmentKind::FieldPats
|
||||
| AstFragmentKind::GenericParams
|
||||
| AstFragmentKind::Params
|
||||
| AstFragmentKind::StructFields
|
||||
| AstFragmentKind::Variants => false,
|
||||
| AstFragmentKind::Variants => SupportsMacroExpansion::No,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_errors::struct_span_err;
|
|||
use rustc_expand::base::Annotatable;
|
||||
use rustc_expand::base::{Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind};
|
||||
use rustc_expand::compile_declarative_macro;
|
||||
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind};
|
||||
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
|
||||
use rustc_feature::is_builtin_attr_name;
|
||||
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
|
||||
use rustc_hir::def_id;
|
||||
|
@ -278,12 +278,12 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
|||
|
||||
// Derives are not included when `invocations` are collected, so we have to add them here.
|
||||
let parent_scope = &ParentScope { derives, ..parent_scope };
|
||||
let require_inert = !invoc.fragment_kind.supports_macro_expansion();
|
||||
let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion();
|
||||
let node_id = self.lint_node_id(eager_expansion_root);
|
||||
let (ext, res) = self.smart_resolve_macro_path(
|
||||
path,
|
||||
kind,
|
||||
require_inert,
|
||||
supports_macro_expansion,
|
||||
inner_attr,
|
||||
parent_scope,
|
||||
node_id,
|
||||
|
@ -457,7 +457,7 @@ impl<'a> Resolver<'a> {
|
|||
&mut self,
|
||||
path: &ast::Path,
|
||||
kind: MacroKind,
|
||||
require_inert: bool,
|
||||
supports_macro_expansion: SupportsMacroExpansion,
|
||||
inner_attr: bool,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
node_id: NodeId,
|
||||
|
@ -505,8 +505,17 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
let unexpected_res = if ext.macro_kind() != kind {
|
||||
Some((kind.article(), kind.descr_expected()))
|
||||
} else if require_inert && matches!(res, Res::Def(..)) {
|
||||
Some(("a", "non-macro attribute"))
|
||||
} else if matches!(res, Res::Def(..)) {
|
||||
match supports_macro_expansion {
|
||||
SupportsMacroExpansion::No => Some(("a", "non-macro attribute")),
|
||||
SupportsMacroExpansion::Yes { supports_inner_attrs } => {
|
||||
if inner_attr && !supports_inner_attrs {
|
||||
Some(("a", "non-macro inner attribute"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue