4
4
//! conflicts between multiple such attributes attached to the same
5
5
//! item.
6
6
7
- use crate :: errors:: { self , DebugVisualizerUnreadable , InvalidAttrAtCrateLevel } ;
7
+ use crate :: errors:: {
8
+ self , AttributeShouldBeAppliedTo , DebugVisualizerUnreadable , InvalidAttrAtCrateLevel ,
9
+ ObjectLifetimeErr , OnlyHasEffectOn , TransparentIncompatible , UnrecognizedReprHint ,
10
+ } ;
8
11
use rustc_ast:: { ast, AttrStyle , Attribute , Lit , LitKind , MetaItemKind , NestedMetaItem } ;
9
12
use rustc_data_structures:: fx:: FxHashMap ;
10
- use rustc_errors:: { fluent, struct_span_err , Applicability , MultiSpan } ;
13
+ use rustc_errors:: { fluent, Applicability , MultiSpan } ;
11
14
use rustc_expand:: base:: resolve_path;
12
15
use rustc_feature:: { AttributeDuplicates , AttributeType , BuiltinAttribute , BUILTIN_ATTRIBUTE_MAP } ;
13
16
use rustc_hir as hir;
@@ -164,17 +167,17 @@ impl CheckAttrVisitor<'_> {
164
167
sym:: no_mangle => self . check_no_mangle ( hir_id, attr, span, target) ,
165
168
sym:: deprecated => self . check_deprecated ( hir_id, attr, span, target) ,
166
169
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 ) ,
168
171
sym:: plugin_registrar => self . check_plugin_registrar ( hir_id, attr, target) ,
169
172
sym:: macro_export => self . check_macro_export ( hir_id, attr, target) ,
170
173
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 )
172
175
}
173
176
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 )
175
178
}
176
179
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 )
178
181
}
179
182
sym:: rustc_object_lifetime_default => self . check_object_lifetime_default ( hir_id) ,
180
183
_ => { }
@@ -351,31 +354,17 @@ impl CheckAttrVisitor<'_> {
351
354
hir_id : HirId ,
352
355
attr : & Attribute ,
353
356
target : Target ,
354
- allowed_targets : & [ Target ] ,
357
+ allowed_target : Target ,
355
358
) {
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 (
374
361
UNUSED_ATTRIBUTES ,
375
362
hir_id,
376
363
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
+ } ,
379
368
) ;
380
369
}
381
370
}
@@ -432,7 +421,7 @@ impl CheckAttrVisitor<'_> {
432
421
ObjectLifetimeDefault :: Param ( def_id) => tcx. item_name ( def_id) . to_string ( ) ,
433
422
ObjectLifetimeDefault :: Ambiguous => "Ambiguous" . to_owned ( ) ,
434
423
} ;
435
- tcx. sess . span_err ( p. span , & repr) ;
424
+ tcx. sess . emit_err ( ObjectLifetimeErr { span : p. span , repr } ) ;
436
425
}
437
426
}
438
427
}
@@ -1605,12 +1594,12 @@ impl CheckAttrVisitor<'_> {
1605
1594
continue ;
1606
1595
}
1607
1596
1608
- let ( article , allowed_targets ) = match hint. name_or_empty ( ) {
1597
+ let what = match hint. name_or_empty ( ) {
1609
1598
sym:: C => {
1610
1599
is_c = true ;
1611
1600
match target {
1612
1601
Target :: Struct | Target :: Union | Target :: Enum => continue ,
1613
- _ => ( "a" , " struct, enum, or union") ,
1602
+ _ => " struct- enum- union",
1614
1603
}
1615
1604
}
1616
1605
sym:: align => {
@@ -1626,20 +1615,20 @@ impl CheckAttrVisitor<'_> {
1626
1615
1627
1616
match target {
1628
1617
Target :: Struct | Target :: Union | Target :: Enum | Target :: Fn => continue ,
1629
- _ => ( "a" , " struct, enum, function, or union") ,
1618
+ _ => " struct- enum- function- union",
1630
1619
}
1631
1620
}
1632
1621
sym:: packed => {
1633
1622
if target != Target :: Struct && target != Target :: Union {
1634
- ( "a" , " struct or union")
1623
+ " struct- union"
1635
1624
} else {
1636
1625
continue ;
1637
1626
}
1638
1627
}
1639
1628
sym:: simd => {
1640
1629
is_simd = true ;
1641
1630
if target != Target :: Struct {
1642
- ( "a" , " struct")
1631
+ " struct"
1643
1632
} else {
1644
1633
continue ;
1645
1634
}
@@ -1648,7 +1637,7 @@ impl CheckAttrVisitor<'_> {
1648
1637
is_transparent = true ;
1649
1638
match target {
1650
1639
Target :: Struct | Target :: Union | Target :: Enum => continue ,
1651
- _ => ( "a" , " struct, enum, or union") ,
1640
+ _ => " struct- enum- union",
1652
1641
}
1653
1642
}
1654
1643
sym:: i8
@@ -1665,35 +1654,22 @@ impl CheckAttrVisitor<'_> {
1665
1654
| sym:: usize => {
1666
1655
int_reprs += 1 ;
1667
1656
if target != Target :: Enum {
1668
- ( "an" , " enum")
1657
+ " enum"
1669
1658
} else {
1670
1659
continue ;
1671
1660
}
1672
1661
}
1673
1662
_ => {
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 ( ) } ) ;
1684
1664
continue ;
1685
1665
}
1686
1666
} ;
1687
1667
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
+ } ) ;
1697
1673
}
1698
1674
1699
1675
// Just point at all repr hints if there are any incompatibilities.
@@ -1703,14 +1679,9 @@ impl CheckAttrVisitor<'_> {
1703
1679
// Error on repr(transparent, <anything else>).
1704
1680
if is_transparent && hints. len ( ) > 1 {
1705
1681
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 ( ) } ) ;
1714
1685
}
1715
1686
// Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8)
1716
1687
if ( int_reprs > 1 )
0 commit comments