diff options
Diffstat (limited to 'compiler/rustc_passes/src/check_attr.rs')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 96 |
1 files changed, 32 insertions, 64 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 18b3ab12e2d..3fa5cdc36bc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -160,7 +160,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/ } - Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ + Attribute::Parsed(AttributeKind::Repr { .. }) => { /* handled below this loop and elsewhere */ } Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { self.check_object_lifetime_default(hir_id); @@ -1948,7 +1948,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // #[repr(foo)] // #[repr(bar, align(8))] // ``` - let reprs = find_attr!(attrs, AttributeKind::Repr(r) => r.as_slice()).unwrap_or(&[]); + let (reprs, first_attr_span) = find_attr!(attrs, AttributeKind::Repr { reprs, first_span } => (reprs.as_slice(), Some(*first_span))).unwrap_or((&[], None)); let mut int_reprs = 0; let mut is_explicit_rust = false; @@ -2045,31 +2045,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> { continue; } } - // FIXME(jdonszelmann): move the diagnostic for unused repr attrs here, I think - // it's a better place for it. - ReprAttr::ReprEmpty => { - // catch `repr()` with no arguments, applied to an item (i.e. not `#![repr()]`) - if item.is_some() { - match target { - Target::Struct | Target::Union | Target::Enum => continue, - Target::Fn | Target::Method(_) => { - self.dcx().emit_err(errors::ReprAlignShouldBeAlign { - span: *repr_span, - item: target.name(), - }); - } - _ => { - self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { - hint_span: *repr_span, - span, - }); - } - } - } + }; + } - return; + // catch `repr()` with no arguments, applied to an item (i.e. not `#![repr()]`) + if let Some(first_attr_span) = first_attr_span + && reprs.is_empty() + && item.is_some() + { + match target { + Target::Struct | Target::Union | Target::Enum => {} + Target::Fn | Target::Method(_) => { + self.dcx().emit_err(errors::ReprAlignShouldBeAlign { + span: first_attr_span, + item: target.name(), + }); } - }; + _ => { + self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { + hint_span: first_attr_span, + span, + }); + } + } + return; } // Just point at all repr hints if there are any incompatibilities. @@ -2324,43 +2323,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_unused_attribute(&self, hir_id: HirId, attr: &Attribute, style: Option<AttrStyle>) { - // FIXME(jdonszelmann): deduplicate these checks after more attrs are parsed. This is very - // ugly now but can 100% be removed later. - if let Attribute::Parsed(p) = attr { - match p { - AttributeKind::Repr(reprs) => { - for (r, span) in reprs { - if let ReprAttr::ReprEmpty = r { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - *span, - errors::Unused { - attr_span: *span, - note: errors::UnusedNote::EmptyList { name: sym::repr }, - }, - ); - } - } - return; - } - AttributeKind::TargetFeature(features, span) if features.len() == 0 => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - *span, - errors::Unused { - attr_span: *span, - note: errors::UnusedNote::EmptyList { name: sym::target_feature }, - }, - ); - return; - } - _ => {} - }; - } - // Warn on useless empty attributes. + // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute` let note = if attr.has_any_name(&[ sym::macro_use, sym::allow, @@ -2576,7 +2540,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { - if !find_attr!(attrs, AttributeKind::Repr(r) => r.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) + if !find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) .unwrap_or(false) { self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span }); @@ -2852,8 +2816,12 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { ATTRS_TO_CHECK.iter().find(|attr_to_check| attr.has_name(**attr_to_check)) { (attr.span(), *a) - } else if let Attribute::Parsed(AttributeKind::Repr(r)) = attr { - (r.first().unwrap().1, sym::repr) + } else if let Attribute::Parsed(AttributeKind::Repr { + reprs: _, + first_span: first_attr_span, + }) = attr + { + (*first_attr_span, sym::repr) } else { continue; }; |
