44//! conflicts between multiple such attributes attached to the same
55//! item.
66
7- use crate :: errors:: { self , DebugVisualizerUnreadable , InvalidAttrAtCrateLevel } ;
7+ use crate :: errors:: {
8+ self , AttributeShouldBeAppliedTo , DebugVisualizerUnreadable , InvalidAttrAtCrateLevel ,
9+ ObjectLifetimeErr , OnlyHasEffectOn , TransparentIncompatible , UnrecognizedReprHint ,
10+ } ;
811use rustc_ast:: { ast, AttrStyle , Attribute , Lit , LitKind , MetaItemKind , NestedMetaItem } ;
912use rustc_data_structures:: fx:: FxHashMap ;
10- use rustc_errors:: { fluent, struct_span_err , Applicability , MultiSpan } ;
13+ use rustc_errors:: { fluent, Applicability , MultiSpan } ;
1114use rustc_expand:: base:: resolve_path;
1215use rustc_feature:: { AttributeDuplicates , AttributeType , BuiltinAttribute , BUILTIN_ATTRIBUTE_MAP } ;
1316use rustc_hir as hir;
@@ -164,17 +167,17 @@ impl CheckAttrVisitor<'_> {
164167 sym:: no_mangle => self . check_no_mangle ( hir_id, attr, span, target) ,
165168 sym:: deprecated => self . check_deprecated ( hir_id, attr, span, target) ,
166169 sym:: macro_use | sym:: macro_escape => self . check_macro_use ( hir_id, attr, target) ,
167- sym:: path => self . check_generic_attr ( hir_id, attr, target, & [ Target :: Mod ] ) ,
170+ sym:: path => self . check_generic_attr ( hir_id, attr, target, Target :: Mod ) ,
168171 sym:: plugin_registrar => self . check_plugin_registrar ( hir_id, attr, target) ,
169172 sym:: macro_export => self . check_macro_export ( hir_id, attr, target) ,
170173 sym:: ignore | sym:: should_panic | sym:: proc_macro_derive => {
171- self . check_generic_attr ( hir_id, attr, target, & [ Target :: Fn ] )
174+ self . check_generic_attr ( hir_id, attr, target, Target :: Fn )
172175 }
173176 sym:: automatically_derived => {
174- self . check_generic_attr ( hir_id, attr, target, & [ Target :: Impl ] )
177+ self . check_generic_attr ( hir_id, attr, target, Target :: Impl )
175178 }
176179 sym:: no_implicit_prelude => {
177- self . check_generic_attr ( hir_id, attr, target, & [ Target :: Mod ] )
180+ self . check_generic_attr ( hir_id, attr, target, Target :: Mod )
178181 }
179182 sym:: rustc_object_lifetime_default => self . check_object_lifetime_default ( hir_id) ,
180183 _ => { }
@@ -351,31 +354,17 @@ impl CheckAttrVisitor<'_> {
351354 hir_id : HirId ,
352355 attr : & Attribute ,
353356 target : Target ,
354- allowed_targets : & [ Target ] ,
357+ allowed_target : Target ,
355358 ) {
356- if !allowed_targets. iter ( ) . any ( |t| t == & target) {
357- let name = attr. name_or_empty ( ) ;
358- let mut i = allowed_targets. iter ( ) ;
359- // Pluralize
360- let b = i. next ( ) . map_or_else ( String :: new, |t| t. to_string ( ) + "s" ) ;
361- let supported_names = i. enumerate ( ) . fold ( b, |mut b, ( i, allowed_target) | {
362- if allowed_targets. len ( ) > 2 && i == allowed_targets. len ( ) - 2 {
363- b. push_str ( ", and " ) ;
364- } else if allowed_targets. len ( ) == 2 && i == allowed_targets. len ( ) - 2 {
365- b. push_str ( " and " ) ;
366- } else {
367- b. push_str ( ", " ) ;
368- }
369- // Pluralize
370- b. push_str ( & ( allowed_target. to_string ( ) + "s" ) ) ;
371- b
372- } ) ;
373- self . tcx . struct_span_lint_hir (
359+ if target != allowed_target {
360+ self . tcx . emit_spanned_lint (
374361 UNUSED_ATTRIBUTES ,
375362 hir_id,
376363 attr. span ,
377- & format ! ( "`#[{name}]` only has an effect on {}" , supported_names) ,
378- |lint| lint,
364+ OnlyHasEffectOn {
365+ attr_name : attr. name_or_empty ( ) ,
366+ target_name : allowed_target. name ( ) . replace ( " " , "_" ) ,
367+ } ,
379368 ) ;
380369 }
381370 }
@@ -432,7 +421,7 @@ impl CheckAttrVisitor<'_> {
432421 ObjectLifetimeDefault :: Param ( def_id) => tcx. item_name ( def_id) . to_string ( ) ,
433422 ObjectLifetimeDefault :: Ambiguous => "Ambiguous" . to_owned ( ) ,
434423 } ;
435- tcx. sess . span_err ( p. span , & repr) ;
424+ tcx. sess . emit_err ( ObjectLifetimeErr { span : p. span , repr } ) ;
436425 }
437426 }
438427 }
@@ -1605,12 +1594,12 @@ impl CheckAttrVisitor<'_> {
16051594 continue ;
16061595 }
16071596
1608- let ( article , allowed_targets ) = match hint. name_or_empty ( ) {
1597+ let what = match hint. name_or_empty ( ) {
16091598 sym:: C => {
16101599 is_c = true ;
16111600 match target {
16121601 Target :: Struct | Target :: Union | Target :: Enum => continue ,
1613- _ => ( "a" , " struct, enum, or union") ,
1602+ _ => " struct- enum- union",
16141603 }
16151604 }
16161605 sym:: align => {
@@ -1626,20 +1615,20 @@ impl CheckAttrVisitor<'_> {
16261615
16271616 match target {
16281617 Target :: Struct | Target :: Union | Target :: Enum | Target :: Fn => continue ,
1629- _ => ( "a" , " struct, enum, function, or union") ,
1618+ _ => " struct- enum- function- union",
16301619 }
16311620 }
16321621 sym:: packed => {
16331622 if target != Target :: Struct && target != Target :: Union {
1634- ( "a" , " struct or union")
1623+ " struct- union"
16351624 } else {
16361625 continue ;
16371626 }
16381627 }
16391628 sym:: simd => {
16401629 is_simd = true ;
16411630 if target != Target :: Struct {
1642- ( "a" , " struct")
1631+ " struct"
16431632 } else {
16441633 continue ;
16451634 }
@@ -1648,7 +1637,7 @@ impl CheckAttrVisitor<'_> {
16481637 is_transparent = true ;
16491638 match target {
16501639 Target :: Struct | Target :: Union | Target :: Enum => continue ,
1651- _ => ( "a" , " struct, enum, or union") ,
1640+ _ => " struct- enum- union",
16521641 }
16531642 }
16541643 sym:: i8
@@ -1665,35 +1654,22 @@ impl CheckAttrVisitor<'_> {
16651654 | sym:: usize => {
16661655 int_reprs += 1 ;
16671656 if target != Target :: Enum {
1668- ( "an" , " enum")
1657+ " enum"
16691658 } else {
16701659 continue ;
16711660 }
16721661 }
16731662 _ => {
1674- struct_span_err ! (
1675- self . tcx. sess,
1676- hint. span( ) ,
1677- E0552 ,
1678- "unrecognized representation hint"
1679- )
1680- . help ( "valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, \
1681- `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`")
1682- . emit ( ) ;
1683-
1663+ self . tcx . sess . emit_err ( UnrecognizedReprHint { span : hint. span ( ) } ) ;
16841664 continue ;
16851665 }
16861666 } ;
16871667
1688- struct_span_err ! (
1689- self . tcx. sess,
1690- hint. span( ) ,
1691- E0517 ,
1692- "{}" ,
1693- & format!( "attribute should be applied to {article} {allowed_targets}" )
1694- )
1695- . span_label ( span, & format ! ( "not {article} {allowed_targets}" ) )
1696- . emit ( ) ;
1668+ self . tcx . sess . emit_err ( AttributeShouldBeAppliedTo {
1669+ hint_span : hint. span ( ) ,
1670+ span,
1671+ what,
1672+ } ) ;
16971673 }
16981674
16991675 // Just point at all repr hints if there are any incompatibilities.
@@ -1703,14 +1679,9 @@ impl CheckAttrVisitor<'_> {
17031679 // Error on repr(transparent, <anything else>).
17041680 if is_transparent && hints. len ( ) > 1 {
17051681 let hint_spans: Vec < _ > = hint_spans. clone ( ) . collect ( ) ;
1706- struct_span_err ! (
1707- self . tcx. sess,
1708- hint_spans,
1709- E0692 ,
1710- "transparent {} cannot have other repr hints" ,
1711- target
1712- )
1713- . emit ( ) ;
1682+ self . tcx
1683+ . sess
1684+ . emit_err ( TransparentIncompatible { hint_spans, target : target. to_string ( ) } ) ;
17141685 }
17151686 // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8)
17161687 if ( int_reprs > 1 )
0 commit comments