let mut is_valid = true;
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
- is_valid &= if self.tcx.sess.check_name(attr, sym::inline) {
- self.check_inline(hir_id, attr, span, target)
- } else if self.tcx.sess.check_name(attr, sym::non_exhaustive) {
- self.check_non_exhaustive(hir_id, attr, span, target)
- } else if self.tcx.sess.check_name(attr, sym::marker) {
- self.check_marker(hir_id, attr, span, target)
- } else if self.tcx.sess.check_name(attr, sym::target_feature) {
- 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);
+ is_valid &= match attr.name_or_empty() {
+ sym::inline => self.check_inline(hir_id, attr, span, target),
+ sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
+ sym::marker => self.check_marker(hir_id, attr, span, target),
+ sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
+ sym::track_caller => {
+ self.check_track_caller(hir_id, &attr.span, attrs, 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 {
// ```
let hints: Vec<_> = attrs
.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())
.flatten()
.collect();
let mut is_transparent = false;
for hint in &hints {
+ if !hint.is_meta_item() {
+ struct_span_err!(
+ self.tcx.sess,
+ hint.span(),
+ E0565,
+ "meta item in `repr` must be an identifier"
+ )
+ .emit();
+ continue;
+ }
+
let (article, allowed_targets) = match hint.name_or_empty() {
- _ if !matches!(target, Target::Struct | Target::Enum | Target::Union) => {
- ("a", "struct, enum, or union")
- }
- name @ sym::C | name @ sym::align => {
- is_c |= name == sym::C;
+ sym::C => {
+ is_c = true;
match target {
Target::Struct | Target::Union | Target::Enum => continue,
_ => ("a", "struct, enum, or union"),
}
}
+ sym::align => {
+ if let (Target::Fn, true) = (target, !self.tcx.features().fn_align) {
+ feature_err(
+ &self.tcx.sess.parse_sess,
+ sym::fn_align,
+ hint.span(),
+ "`repr(align)` attributes on functions are unstable",
+ )
+ .emit();
+ }
+
+ match target {
+ Target::Struct | Target::Union | Target::Enum | Target::Fn => continue,
+ _ => ("a", "struct, enum, function, or union"),
+ }
+ }
sym::packed => {
if target != Target::Struct && target != Target::Union {
("a", "struct or union")
continue;
}
}
- _ => continue,
+ _ => {
+ struct_span_err!(
+ self.tcx.sess,
+ hint.span(),
+ E0552,
+ "unrecognized representation hint"
+ )
+ .emit();
+
+ continue;
+ }
};
struct_span_err!(
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {
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
.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");