Assert that all attributes are actually checked via CheckAttrVisitor
and aren't accidentally usable on completely unrelated HIR nodes
Co-authored-by: Jieyou Xu <jieyouxu@outlook.com>
This commit is contained in:
parent
fd8d6fbe50
commit
ed010dd32c
@ -703,21 +703,21 @@ pub struct BuiltinAttribute {
|
|||||||
EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
|
EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
|
||||||
),
|
),
|
||||||
gated!(
|
gated!(
|
||||||
panic_runtime, Normal, template!(Word), WarnFollowing,
|
panic_runtime, CrateLevel, template!(Word), WarnFollowing,
|
||||||
EncodeCrossCrate::No, experimental!(panic_runtime)
|
EncodeCrossCrate::No, experimental!(panic_runtime)
|
||||||
),
|
),
|
||||||
gated!(
|
gated!(
|
||||||
needs_panic_runtime, Normal, template!(Word), WarnFollowing,
|
needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing,
|
||||||
EncodeCrossCrate::No, experimental!(needs_panic_runtime)
|
EncodeCrossCrate::No, experimental!(needs_panic_runtime)
|
||||||
),
|
),
|
||||||
gated!(
|
gated!(
|
||||||
compiler_builtins, Normal, template!(Word), WarnFollowing,
|
compiler_builtins, CrateLevel, template!(Word), WarnFollowing,
|
||||||
EncodeCrossCrate::No,
|
EncodeCrossCrate::No,
|
||||||
"the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
|
"the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
|
||||||
which contains compiler-rt intrinsics and will never be stable",
|
which contains compiler-rt intrinsics and will never be stable",
|
||||||
),
|
),
|
||||||
gated!(
|
gated!(
|
||||||
profiler_runtime, Normal, template!(Word), WarnFollowing,
|
profiler_runtime, CrateLevel, template!(Word), WarnFollowing,
|
||||||
EncodeCrossCrate::No,
|
EncodeCrossCrate::No,
|
||||||
"the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
|
"the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
|
||||||
which contains the profiler runtime and will never be stable",
|
which contains the profiler runtime and will never be stable",
|
||||||
|
@ -100,6 +100,10 @@ passes_continue_labeled_block =
|
|||||||
.label = labeled blocks cannot be `continue`'d
|
.label = labeled blocks cannot be `continue`'d
|
||||||
.block_label = labeled block the `continue` points to
|
.block_label = labeled block the `continue` points to
|
||||||
|
|
||||||
|
passes_coroutine_on_non_closure =
|
||||||
|
attribute should be applied to closures
|
||||||
|
.label = not a closure
|
||||||
|
|
||||||
passes_coverage_not_fn_or_closure =
|
passes_coverage_not_fn_or_closure =
|
||||||
attribute should be applied to a function definition or closure
|
attribute should be applied to a function definition or closure
|
||||||
.label = not a function or closure
|
.label = not a function or closure
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
|
TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
|
||||||
};
|
};
|
||||||
use rustc_macros::LintDiagnostic;
|
use rustc_macros::LintDiagnostic;
|
||||||
use rustc_middle::bug;
|
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
|
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::traits::ObligationCause;
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::lint::builtin::{
|
use rustc_session::lint::builtin::{
|
||||||
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
|
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||||
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
|
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
|
||||||
@ -239,7 +239,59 @@ fn check_attributes(
|
|||||||
self.check_generic_attr(hir_id, attr, target, Target::Fn);
|
self.check_generic_attr(hir_id, attr, target, Target::Fn);
|
||||||
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
|
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
|
||||||
}
|
}
|
||||||
_ => {}
|
[sym::coroutine] => {
|
||||||
|
self.check_coroutine(attr, target);
|
||||||
|
}
|
||||||
|
[
|
||||||
|
// ok
|
||||||
|
sym::allow
|
||||||
|
| sym::expect
|
||||||
|
| sym::warn
|
||||||
|
| sym::deny
|
||||||
|
| sym::forbid
|
||||||
|
| sym::cfg
|
||||||
|
// need to be fixed
|
||||||
|
| sym::cfi_encoding // FIXME(cfi_encoding)
|
||||||
|
| sym::may_dangle // FIXME(dropck_eyepatch)
|
||||||
|
| sym::pointee // FIXME(derive_smart_pointer)
|
||||||
|
| sym::linkage // FIXME(linkage)
|
||||||
|
| sym::no_sanitize // FIXME(no_sanitize)
|
||||||
|
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
|
||||||
|
| sym::used // handled elsewhere to restrict to static items
|
||||||
|
| sym::repr // handled elsewhere to restrict to type decls items
|
||||||
|
| sym::instruction_set // broken on stable!!!
|
||||||
|
| sym::windows_subsystem // broken on stable!!!
|
||||||
|
| sym::patchable_function_entry // FIXME(patchable_function_entry)
|
||||||
|
| sym::deprecated_safe // FIXME(deprecated_safe)
|
||||||
|
// internal
|
||||||
|
| sym::prelude_import
|
||||||
|
| sym::panic_handler
|
||||||
|
| sym::allow_internal_unsafe
|
||||||
|
| sym::fundamental
|
||||||
|
| sym::lang
|
||||||
|
| sym::needs_allocator
|
||||||
|
| sym::default_lib_allocator
|
||||||
|
| sym::start
|
||||||
|
| sym::custom_mir,
|
||||||
|
] => {}
|
||||||
|
[name, ..] => {
|
||||||
|
match BUILTIN_ATTRIBUTE_MAP.get(name) {
|
||||||
|
// checked below
|
||||||
|
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
|
||||||
|
Some(_) => {
|
||||||
|
// FIXME: differentiate between unstable and internal attributes just like we do with features instead
|
||||||
|
// of just accepting `rustc_` attributes by name. That should allow trimming the above list, too.
|
||||||
|
if !name.as_str().starts_with("rustc_") {
|
||||||
|
span_bug!(
|
||||||
|
attr.span,
|
||||||
|
"builtin attribute {name:?} not handled by `CheckAttrVisitor`"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[] => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let builtin = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
|
let builtin = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
|
||||||
@ -376,6 +428,7 @@ fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) {
|
|||||||
|
|
||||||
/// Checks that `#[optimize(..)]` is applied to a function/closure/method,
|
/// Checks that `#[optimize(..)]` is applied to a function/closure/method,
|
||||||
/// or to an impl block or module.
|
/// or to an impl block or module.
|
||||||
|
// FIXME(#128488): this should probably be elevated to an error?
|
||||||
fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||||
match target {
|
match target {
|
||||||
Target::Fn
|
Target::Fn
|
||||||
@ -2279,6 +2332,15 @@ fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) {
|
|||||||
self.abort.set(true);
|
self.abort.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_coroutine(&self, attr: &Attribute, target: Target) {
|
||||||
|
match target {
|
||||||
|
Target::Closure => return,
|
||||||
|
_ => {
|
||||||
|
self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr.span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
||||||
|
@ -636,6 +636,13 @@ pub struct Confusables {
|
|||||||
pub attr_span: Span,
|
pub attr_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(passes_coroutine_on_non_closure)]
|
||||||
|
pub struct CoroutineOnNonClosure {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(passes_empty_confusables)]
|
#[diag(passes_empty_confusables)]
|
||||||
pub(crate) struct EmptyConfusables {
|
pub(crate) struct EmptyConfusables {
|
||||||
|
Loading…
Reference in New Issue
Block a user