Skip to content

Commit 3fe8e00

Browse files
committed
migrate the rest of check_attr.rs to translateable diagnostics
1 parent a7aa185 commit 3fe8e00

File tree

3 files changed

+110
-62
lines changed

3 files changed

+110
-62
lines changed

compiler/rustc_error_messages/locales/en-US/passes.ftl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,39 @@ passes_useless_assignment =
564564
[true] field
565565
*[false] variable
566566
} of type `{$ty}` to itself
567+
568+
passes_only_has_effect_on =
569+
`#[{$attr_name}]` only has an effect on {$target_name ->
570+
[function] functions
571+
[module] modules
572+
[implementation_block] implementation blocks
573+
*[unspecified] (unspecified--this is a compiler bug)
574+
}
575+
576+
passes_object_lifetime_err =
577+
{$repr}
578+
579+
passes_unrecognized_repr_hint =
580+
unrecognized representation hint
581+
.help = valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
582+
583+
passes_attribute_should_be_applied_to =
584+
attribute should be applied to {$what ->
585+
[enum] an enum
586+
[struct] a struct
587+
[struct-union] a struct or union
588+
[struct-enum-union] a struct, enum, or union
589+
[struct-enum-function-union] a struct, enum, function, or union
590+
*[unspecified] (unspecified--this is a compiler bug)
591+
}
592+
.label = not {$what ->
593+
[enum] an enum
594+
[struct] a struct
595+
[struct-union] a struct or union
596+
[struct-enum-union] a struct, enum, or union
597+
[struct-enum-function-union] a struct, enum, function, or union
598+
*[unspecified] (unspecified--this is a compiler bug)
599+
}
600+
601+
passes_transparent_incompatible =
602+
transparent {$target} cannot have other repr hints

compiler/rustc_passes/src/check_attr.rs

Lines changed: 33 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
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+
};
811
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
912
use rustc_data_structures::fx::FxHashMap;
10-
use rustc_errors::{fluent, struct_span_err, Applicability, MultiSpan};
13+
use rustc_errors::{fluent, Applicability, MultiSpan};
1114
use rustc_expand::base::resolve_path;
1215
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
1316
use 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)

compiler/rustc_passes/src/errors.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,3 +1272,44 @@ pub struct UselessAssignment<'a> {
12721272
pub is_field_assign: bool,
12731273
pub ty: Ty<'a>,
12741274
}
1275+
1276+
#[derive(LintDiagnostic)]
1277+
#[diag(passes::only_has_effect_on)]
1278+
pub struct OnlyHasEffectOn {
1279+
pub attr_name: Symbol,
1280+
pub target_name: String,
1281+
}
1282+
1283+
#[derive(Diagnostic)]
1284+
#[diag(passes::object_lifetime_err)]
1285+
pub struct ObjectLifetimeErr {
1286+
#[primary_span]
1287+
pub span: Span,
1288+
pub repr: String,
1289+
}
1290+
1291+
#[derive(Diagnostic)]
1292+
#[diag(passes::unrecognized_repr_hint, code = "E0552")]
1293+
#[help]
1294+
pub struct UnrecognizedReprHint {
1295+
#[primary_span]
1296+
pub span: Span,
1297+
}
1298+
1299+
#[derive(Diagnostic)]
1300+
#[diag(passes::attribute_should_be_applied_to, code = "E0517")]
1301+
pub struct AttributeShouldBeAppliedTo<'a> {
1302+
#[primary_span]
1303+
pub hint_span: Span,
1304+
#[label]
1305+
pub span: Span,
1306+
pub what: &'a str,
1307+
}
1308+
1309+
#[derive(Diagnostic)]
1310+
#[diag(passes::transparent_incompatible, code = "E0692")]
1311+
pub struct TransparentIncompatible {
1312+
#[primary_span]
1313+
pub hint_spans: Vec<Span>,
1314+
pub target: String,
1315+
}

0 commit comments

Comments
 (0)