diff options
| author | Nathan Stocks <cleancut@github.com> | 2022-10-02 14:34:10 -0600 |
|---|---|---|
| committer | Nathan Stocks <cleancut@github.com> | 2022-10-07 13:19:27 -0600 |
| commit | 3fe8e004e99b4b2dd616210d5c7e4d211ab25043 (patch) | |
| tree | 6f246f93656f88379e1f2f03c3a24d2bcfe686a1 | |
| parent | a7aa1850b2de87e31ffa07df6f4d47e0a5f7b01e (diff) | |
| download | rust-3fe8e004e99b4b2dd616210d5c7e4d211ab25043.tar.gz rust-3fe8e004e99b4b2dd616210d5c7e4d211ab25043.zip | |
migrate the rest of check_attr.rs to translateable diagnostics
| -rw-r--r-- | compiler/rustc_error_messages/locales/en-US/passes.ftl | 36 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 95 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 41 |
3 files changed, 110 insertions, 62 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 2308c7b2453..217a05b4364 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -564,3 +564,39 @@ passes_useless_assignment = [true] field *[false] variable } of type `{$ty}` to itself + +passes_only_has_effect_on = + `#[{$attr_name}]` only has an effect on {$target_name -> + [function] functions + [module] modules + [implementation_block] implementation blocks + *[unspecified] (unspecified--this is a compiler bug) + } + +passes_object_lifetime_err = + {$repr} + +passes_unrecognized_repr_hint = + unrecognized representation hint + .help = valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +passes_attribute_should_be_applied_to = + attribute should be applied to {$what -> + [enum] an enum + [struct] a struct + [struct-union] a struct or union + [struct-enum-union] a struct, enum, or union + [struct-enum-function-union] a struct, enum, function, or union + *[unspecified] (unspecified--this is a compiler bug) + } + .label = not {$what -> + [enum] an enum + [struct] a struct + [struct-union] a struct or union + [struct-enum-union] a struct, enum, or union + [struct-enum-function-union] a struct, enum, function, or union + *[unspecified] (unspecified--this is a compiler bug) + } + +passes_transparent_incompatible = + transparent {$target} cannot have other repr hints diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 18e1233fa84..33eb57fe769 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -4,10 +4,13 @@ //! conflicts between multiple such attributes attached to the same //! item. -use crate::errors::{self, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel}; +use crate::errors::{ + self, AttributeShouldBeAppliedTo, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel, + ObjectLifetimeErr, OnlyHasEffectOn, TransparentIncompatible, UnrecognizedReprHint, +}; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{fluent, struct_span_err, Applicability, MultiSpan}; +use rustc_errors::{fluent, Applicability, MultiSpan}; use rustc_expand::base::resolve_path; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; @@ -164,17 +167,17 @@ impl CheckAttrVisitor<'_> { sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target), sym::deprecated => self.check_deprecated(hir_id, attr, span, target), sym::macro_use | sym::macro_escape => self.check_macro_use(hir_id, attr, target), - sym::path => self.check_generic_attr(hir_id, attr, target, &[Target::Mod]), + sym::path => self.check_generic_attr(hir_id, attr, target, Target::Mod), sym::plugin_registrar => self.check_plugin_registrar(hir_id, attr, target), sym::macro_export => self.check_macro_export(hir_id, attr, target), sym::ignore | sym::should_panic | sym::proc_macro_derive => { - self.check_generic_attr(hir_id, attr, target, &[Target::Fn]) + self.check_generic_attr(hir_id, attr, target, Target::Fn) } sym::automatically_derived => { - self.check_generic_attr(hir_id, attr, target, &[Target::Impl]) + self.check_generic_attr(hir_id, attr, target, Target::Impl) } sym::no_implicit_prelude => { - self.check_generic_attr(hir_id, attr, target, &[Target::Mod]) + self.check_generic_attr(hir_id, attr, target, Target::Mod) } sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id), _ => {} @@ -351,31 +354,17 @@ impl CheckAttrVisitor<'_> { hir_id: HirId, attr: &Attribute, target: Target, - allowed_targets: &[Target], + allowed_target: Target, ) { - if !allowed_targets.iter().any(|t| t == &target) { - let name = attr.name_or_empty(); - let mut i = allowed_targets.iter(); - // Pluralize - let b = i.next().map_or_else(String::new, |t| t.to_string() + "s"); - let supported_names = i.enumerate().fold(b, |mut b, (i, allowed_target)| { - if allowed_targets.len() > 2 && i == allowed_targets.len() - 2 { - b.push_str(", and "); - } else if allowed_targets.len() == 2 && i == allowed_targets.len() - 2 { - b.push_str(" and "); - } else { - b.push_str(", "); - } - // Pluralize - b.push_str(&(allowed_target.to_string() + "s")); - b - }); - self.tcx.struct_span_lint_hir( + if target != allowed_target { + self.tcx.emit_spanned_lint( UNUSED_ATTRIBUTES, hir_id, attr.span, - &format!("`#[{name}]` only has an effect on {}", supported_names), - |lint| lint, + OnlyHasEffectOn { + attr_name: attr.name_or_empty(), + target_name: allowed_target.name().replace(" ", "_"), + }, ); } } @@ -432,7 +421,7 @@ impl CheckAttrVisitor<'_> { ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(), ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(), }; - tcx.sess.span_err(p.span, &repr); + tcx.sess.emit_err(ObjectLifetimeErr { span: p.span, repr }); } } } @@ -1605,12 +1594,12 @@ impl CheckAttrVisitor<'_> { continue; } - let (article, allowed_targets) = match hint.name_or_empty() { + let what = match hint.name_or_empty() { sym::C => { is_c = true; match target { Target::Struct | Target::Union | Target::Enum => continue, - _ => ("a", "struct, enum, or union"), + _ => "struct-enum-union", } } sym::align => { @@ -1626,12 +1615,12 @@ impl CheckAttrVisitor<'_> { match target { Target::Struct | Target::Union | Target::Enum | Target::Fn => continue, - _ => ("a", "struct, enum, function, or union"), + _ => "struct-enum-function-union", } } sym::packed => { if target != Target::Struct && target != Target::Union { - ("a", "struct or union") + "struct-union" } else { continue; } @@ -1639,7 +1628,7 @@ impl CheckAttrVisitor<'_> { sym::simd => { is_simd = true; if target != Target::Struct { - ("a", "struct") + "struct" } else { continue; } @@ -1648,7 +1637,7 @@ impl CheckAttrVisitor<'_> { is_transparent = true; match target { Target::Struct | Target::Union | Target::Enum => continue, - _ => ("a", "struct, enum, or union"), + _ => "struct-enum-union", } } sym::i8 @@ -1665,35 +1654,22 @@ impl CheckAttrVisitor<'_> { | sym::usize => { int_reprs += 1; if target != Target::Enum { - ("an", "enum") + "enum" } else { continue; } } _ => { - struct_span_err!( - self.tcx.sess, - hint.span(), - E0552, - "unrecognized representation hint" - ) - .help("valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, \ - `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`") - .emit(); - + self.tcx.sess.emit_err(UnrecognizedReprHint { span: hint.span() }); continue; } }; - struct_span_err!( - self.tcx.sess, - hint.span(), - E0517, - "{}", - &format!("attribute should be applied to {article} {allowed_targets}") - ) - .span_label(span, &format!("not {article} {allowed_targets}")) - .emit(); + self.tcx.sess.emit_err(AttributeShouldBeAppliedTo { + hint_span: hint.span(), + span, + what, + }); } // Just point at all repr hints if there are any incompatibilities. @@ -1703,14 +1679,9 @@ impl CheckAttrVisitor<'_> { // Error on repr(transparent, <anything else>). if is_transparent && hints.len() > 1 { let hint_spans: Vec<_> = hint_spans.clone().collect(); - struct_span_err!( - self.tcx.sess, - hint_spans, - E0692, - "transparent {} cannot have other repr hints", - target - ) - .emit(); + self.tcx + .sess + .emit_err(TransparentIncompatible { hint_spans, target: target.to_string() }); } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1) diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index ba1d4472e34..4f8c3ed6002 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1272,3 +1272,44 @@ pub struct UselessAssignment<'a> { pub is_field_assign: bool, pub ty: Ty<'a>, } + +#[derive(LintDiagnostic)] +#[diag(passes::only_has_effect_on)] +pub struct OnlyHasEffectOn { + pub attr_name: Symbol, + pub target_name: String, +} + +#[derive(Diagnostic)] +#[diag(passes::object_lifetime_err)] +pub struct ObjectLifetimeErr { + #[primary_span] + pub span: Span, + pub repr: String, +} + +#[derive(Diagnostic)] +#[diag(passes::unrecognized_repr_hint, code = "E0552")] +#[help] +pub struct UnrecognizedReprHint { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::attribute_should_be_applied_to, code = "E0517")] +pub struct AttributeShouldBeAppliedTo<'a> { + #[primary_span] + pub hint_span: Span, + #[label] + pub span: Span, + pub what: &'a str, +} + +#[derive(Diagnostic)] +#[diag(passes::transparent_incompatible, code = "E0692")] +pub struct TransparentIncompatible { + #[primary_span] + pub hint_spans: Vec<Span>, + pub target: String, +} |
