Auto merge of #84091 - tmiasko:check-attrs-sym, r=davidtwco
Match against attribute name when validating attributes Extract attribute name once and match it against symbols that are being validated, instead of using `Session::check_name` for each symbol individually. Assume that all validated attributes are used, instead of marking them as such, since the attribute check should be exhaustive.
This commit is contained in:
commit
1a6c98e4d6
@ -100,6 +100,7 @@ pub struct Path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<Symbol> for Path {
|
impl PartialEq<Symbol> for Path {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, symbol: &Symbol) -> bool {
|
fn eq(&self, symbol: &Symbol) -> bool {
|
||||||
self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
|
self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#),
|
template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#),
|
||||||
),
|
),
|
||||||
ungated!(link_name, AssumedUsed, template!(NameValueStr: "name")),
|
ungated!(link_name, AssumedUsed, template!(NameValueStr: "name")),
|
||||||
ungated!(no_link, Normal, template!(Word)),
|
ungated!(no_link, AssumedUsed, template!(Word)),
|
||||||
ungated!(repr, Normal, template!(List: "C")),
|
ungated!(repr, AssumedUsed, template!(List: "C")),
|
||||||
ungated!(export_name, AssumedUsed, template!(NameValueStr: "name")),
|
ungated!(export_name, AssumedUsed, template!(NameValueStr: "name")),
|
||||||
ungated!(link_section, AssumedUsed, template!(NameValueStr: "name")),
|
ungated!(link_section, AssumedUsed, template!(NameValueStr: "name")),
|
||||||
ungated!(no_mangle, AssumedUsed, template!(Word)),
|
ungated!(no_mangle, AssumedUsed, template!(Word)),
|
||||||
@ -317,7 +317,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
"custom test frameworks are an unstable feature",
|
"custom test frameworks are an unstable feature",
|
||||||
),
|
),
|
||||||
// RFC #1268
|
// RFC #1268
|
||||||
gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)),
|
gated!(marker, AssumedUsed, template!(Word), marker_trait_attr, experimental!(marker)),
|
||||||
gated!(
|
gated!(
|
||||||
thread_local, AssumedUsed, template!(Word),
|
thread_local, AssumedUsed, template!(Word),
|
||||||
"`#[thread_local]` is an experimental feature, and does not currently handle destructors",
|
"`#[thread_local]` is an experimental feature, and does not currently handle destructors",
|
||||||
|
@ -69,55 +69,48 @@ impl CheckAttrVisitor<'tcx> {
|
|||||||
let mut is_valid = true;
|
let mut is_valid = true;
|
||||||
let attrs = self.tcx.hir().attrs(hir_id);
|
let attrs = self.tcx.hir().attrs(hir_id);
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
is_valid &= if self.tcx.sess.check_name(attr, sym::inline) {
|
is_valid &= match attr.name_or_empty() {
|
||||||
self.check_inline(hir_id, attr, span, target)
|
sym::inline => self.check_inline(hir_id, attr, span, target),
|
||||||
} else if self.tcx.sess.check_name(attr, sym::non_exhaustive) {
|
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
|
||||||
self.check_non_exhaustive(hir_id, attr, span, target)
|
sym::marker => self.check_marker(hir_id, attr, span, target),
|
||||||
} else if self.tcx.sess.check_name(attr, sym::marker) {
|
sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
|
||||||
self.check_marker(hir_id, attr, span, target)
|
sym::track_caller => {
|
||||||
} else if self.tcx.sess.check_name(attr, sym::target_feature) {
|
self.check_track_caller(hir_id, &attr.span, attrs, span, target)
|
||||||
self.check_target_feature(hir_id, attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::track_caller) {
|
|
||||||
self.check_track_caller(hir_id, &attr.span, attrs, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::doc) {
|
|
||||||
self.check_doc_attrs(attr, hir_id, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::no_link) {
|
|
||||||
self.check_no_link(hir_id, &attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::export_name) {
|
|
||||||
self.check_export_name(hir_id, &attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) {
|
|
||||||
self.check_rustc_args_required_const(&attr, span, target, item)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_start) {
|
|
||||||
self.check_rustc_layout_scalar_valid_range(&attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_end) {
|
|
||||||
self.check_rustc_layout_scalar_valid_range(&attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) {
|
|
||||||
self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {
|
|
||||||
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::naked) {
|
|
||||||
self.check_naked(hir_id, attr, span, target)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_legacy_const_generics) {
|
|
||||||
self.check_rustc_legacy_const_generics(&attr, span, target, item)
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_clean)
|
|
||||||
|| self.tcx.sess.check_name(attr, sym::rustc_dirty)
|
|
||||||
|| self.tcx.sess.check_name(attr, sym::rustc_if_this_changed)
|
|
||||||
|| self.tcx.sess.check_name(attr, sym::rustc_then_this_would_need)
|
|
||||||
{
|
|
||||||
self.check_rustc_dirty_clean(&attr)
|
|
||||||
} else {
|
|
||||||
// lint-only checks
|
|
||||||
if self.tcx.sess.check_name(attr, sym::cold) {
|
|
||||||
self.check_cold(hir_id, attr, span, target);
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::link_name) {
|
|
||||||
self.check_link_name(hir_id, attr, span, target);
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::link_section) {
|
|
||||||
self.check_link_section(hir_id, attr, span, target);
|
|
||||||
} else if self.tcx.sess.check_name(attr, sym::no_mangle) {
|
|
||||||
self.check_no_mangle(hir_id, attr, span, target);
|
|
||||||
}
|
}
|
||||||
true
|
sym::doc => self.check_doc_attrs(attr, hir_id, target),
|
||||||
|
sym::no_link => self.check_no_link(hir_id, &attr, span, target),
|
||||||
|
sym::export_name => self.check_export_name(hir_id, &attr, span, target),
|
||||||
|
sym::rustc_args_required_const => {
|
||||||
|
self.check_rustc_args_required_const(&attr, span, target, item)
|
||||||
|
}
|
||||||
|
sym::rustc_layout_scalar_valid_range_start
|
||||||
|
| sym::rustc_layout_scalar_valid_range_end => {
|
||||||
|
self.check_rustc_layout_scalar_valid_range(&attr, span, target)
|
||||||
|
}
|
||||||
|
sym::allow_internal_unstable => {
|
||||||
|
self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs)
|
||||||
|
}
|
||||||
|
sym::rustc_allow_const_fn_unstable => {
|
||||||
|
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
|
||||||
|
}
|
||||||
|
sym::naked => self.check_naked(hir_id, attr, span, target),
|
||||||
|
sym::rustc_legacy_const_generics => {
|
||||||
|
self.check_rustc_legacy_const_generics(&attr, span, target, item)
|
||||||
|
}
|
||||||
|
sym::rustc_clean
|
||||||
|
| sym::rustc_dirty
|
||||||
|
| sym::rustc_if_this_changed
|
||||||
|
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
|
||||||
|
_ => true,
|
||||||
};
|
};
|
||||||
|
// lint-only checks
|
||||||
|
match attr.name_or_empty() {
|
||||||
|
sym::cold => self.check_cold(hir_id, attr, span, target),
|
||||||
|
sym::link_name => self.check_link_name(hir_id, attr, span, target),
|
||||||
|
sym::link_section => self.check_link_section(hir_id, attr, span, target),
|
||||||
|
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_valid {
|
if !is_valid {
|
||||||
@ -1116,7 +1109,7 @@ impl CheckAttrVisitor<'tcx> {
|
|||||||
// ```
|
// ```
|
||||||
let hints: Vec<_> = attrs
|
let hints: Vec<_> = attrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| self.tcx.sess.check_name(attr, sym::repr))
|
.filter(|attr| attr.has_name(sym::repr))
|
||||||
.filter_map(|attr| attr.meta_item_list())
|
.filter_map(|attr| attr.meta_item_list())
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
@ -1287,7 +1280,7 @@ impl CheckAttrVisitor<'tcx> {
|
|||||||
|
|
||||||
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {
|
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if self.tcx.sess.check_name(attr, sym::used) && target != Target::Static {
|
if attr.has_name(sym::used) && target != Target::Static {
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.span_err(attr.span, "attribute must be applied to a `static` variable");
|
.span_err(attr.span, "attribute must be applied to a `static` variable");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user