From be4059dd3e64a9b83db35dd7e14512e10b6eac82 Mon Sep 17 00:00:00 2001 From: Nathan Stocks Date: Sun, 2 Oct 2022 21:22:46 -0600 Subject: [PATCH] migrate stability.rs to translateable diagnostics --- .../locales/en-US/passes.ftl | 50 +++++++ compiler/rustc_passes/src/errors.rs | 113 +++++++++++++++ compiler/rustc_passes/src/stability.rs | 130 +++++++----------- 3 files changed, 209 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 217a05b4364..a10ed0f83ea 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -600,3 +600,53 @@ passes_attribute_should_be_applied_to = passes_transparent_incompatible = transparent {$target} cannot have other repr hints + +passes_deprecated_attribute = + deprecated attribute must be paired with either stable or unstable attribute + +passes_useless_stability = + this stability annotation is useless + .label = useless stability annotation + .item = the stability attribute annotates this item + +passes_invalid_stability = + invalid stability version found + .label = invalid stability version + .item = the stability attribute annotates this item + +passes_cannot_stabilize_deprecated = + an API can't be stabilized after it is deprecated + .label = invalid version + .item = the stability attribute annotates this item + +passes_invalid_deprecation_version = + invalid deprecation version found + .label = invalid deprecation version + .item = the stability attribute annotates this item + +passes_missing_stability_attr = + {$descr} has missing stability attribute + +passes_missing_const_stab_attr = + {$descr} has missing const stability attribute + +passes_trait_impl_const_stable = + trait implementations cannot be const stable yet + .note = see issue #67792 for more information + +passes_feature_only_on_nightly = + `#![feature]` may not be used on the {$release_channel} release channel + +passes_unknown_feature = + unknown feature `{$feature}` + +passes_implied_feature_not_exist = + feature `{$implied_by}` implying `{$feature}` does not exist + +passes_duplicate_feature_err = + the feature `{$feature}` has already been declared + +passes_missing_const_err = + attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` + .help = make the function or method const + .label = attribute specified here diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4f8c3ed6002..e1261d29f57 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1313,3 +1313,116 @@ pub struct TransparentIncompatible { pub hint_spans: Vec, pub target: String, } + +#[derive(Diagnostic)] +#[diag(passes::deprecated_attribute, code = "E0549")] +pub struct DeprecatedAttribute { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::useless_stability)] +pub struct UselessStability { + #[primary_span] + #[label] + pub span: Span, + #[label(passes::item)] + pub item_sp: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::invalid_stability)] +pub struct InvalidStability { + #[primary_span] + #[label] + pub span: Span, + #[label(passes::item)] + pub item_sp: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::cannot_stabilize_deprecated)] +pub struct CannotStabilizeDeprecated { + #[primary_span] + #[label] + pub span: Span, + #[label(passes::item)] + pub item_sp: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::invalid_deprecation_version)] +pub struct InvalidDeprecationVersion { + #[primary_span] + #[label] + pub span: Span, + #[label(passes::item)] + pub item_sp: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::missing_stability_attr)] +pub struct MissingStabilityAttr<'a> { + #[primary_span] + pub span: Span, + pub descr: &'a str, +} + +#[derive(Diagnostic)] +#[diag(passes::missing_const_stab_attr)] +pub struct MissingConstStabAttr<'a> { + #[primary_span] + pub span: Span, + pub descr: &'a str, +} + +#[derive(Diagnostic)] +#[diag(passes::trait_impl_const_stable)] +#[note] +pub struct TraitImplConstStable { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes::feature_only_on_nightly, code = "E0554")] +pub struct FeatureOnlyOnNightly { + #[primary_span] + pub span: Span, + pub release_channel: &'static str, +} + +#[derive(Diagnostic)] +#[diag(passes::unknown_feature, code = "E0635")] +pub struct UnknownFeature { + #[primary_span] + pub span: Span, + pub feature: Symbol, +} + +#[derive(Diagnostic)] +#[diag(passes::implied_feature_not_exist)] +pub struct ImpliedFeatureNotExist { + #[primary_span] + pub span: Span, + pub feature: Symbol, + pub implied_by: Symbol, +} + +#[derive(Diagnostic)] +#[diag(passes::duplicate_feature_err, code = "E0636")] +pub struct DuplicateFeatureErr { + #[primary_span] + pub span: Span, + pub feature: Symbol, +} +#[derive(Diagnostic)] +#[diag(passes::missing_const_err)] +pub struct MissingConstErr { + #[primary_span] + #[help] + pub fn_sig_span: Span, + #[label] + pub const_span: Span, +} diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 34fa80228df..cfd6acd8d7c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -1,13 +1,18 @@ //! A pass that annotates every item and method with its stability level, //! propagating default levels lexically from parent to children ast nodes. -use crate::errors; +use crate::errors::{ + self, CannotStabilizeDeprecated, DeprecatedAttribute, DuplicateFeatureErr, + FeatureOnlyOnNightly, ImpliedFeatureNotExist, InvalidDeprecationVersion, InvalidStability, + MissingConstErr, MissingConstStabAttr, MissingStabilityAttr, TraitImplConstStable, + UnknownFeature, UselessStability, +}; use rustc_attr::{ self as attr, rust_version_symbol, ConstStability, Stability, StabilityLevel, Unstable, UnstableReason, VERSION_PLACEHOLDER, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -20,7 +25,6 @@ use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index}; use rustc_middle::ty::{query::Providers, TyCtxt}; use rustc_session::lint; use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED}; -use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use rustc_target::spec::abi::Abi; @@ -179,7 +183,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if !self.in_trait_impl || (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id())) { - missing_const_err(&self.tcx.sess, fn_sig.span, const_span); + self.tcx + .sess + .emit_err(MissingConstErr { fn_sig_span: fn_sig.span, const_span }); } } } @@ -197,14 +203,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr { if stab.is_none() { - struct_span_err!( - self.tcx.sess, - *span, - E0549, - "deprecated attribute must be paired with \ - either stable or unstable attribute" - ) - .emit(); + self.tcx.sess.emit_err(DeprecatedAttribute { span: *span }); } } @@ -220,10 +219,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if kind == AnnotationKind::Prohibited || (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated) { - self.tcx.sess.struct_span_err(span,"this stability annotation is useless") - .span_label(span, "useless stability annotation") - .span_label(item_sp, "the stability attribute annotates this item") - .emit(); + self.tcx.sess.emit_err(UselessStability { span, item_sp }); } debug!("annotate: found {:?}", stab); @@ -239,19 +235,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { { match stab_v.parse::() { Err(_) => { - self.tcx.sess.struct_span_err(span, "invalid stability version found") - .span_label(span, "invalid stability version") - .span_label(item_sp, "the stability attribute annotates this item") - .emit(); + self.tcx.sess.emit_err(InvalidStability { span, item_sp }); break; } Ok(stab_vp) => match dep_v.parse::() { Ok(dep_vp) => match dep_vp.cmp(&stab_vp) { Ordering::Less => { - self.tcx.sess.struct_span_err(span, "an API can't be stabilized after it is deprecated") - .span_label(span, "invalid version") - .span_label(item_sp, "the stability attribute annotates this item") - .emit(); + self.tcx + .sess + .emit_err(CannotStabilizeDeprecated { span, item_sp }); break; } Ordering::Equal => continue, @@ -259,10 +251,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { }, Err(_) => { if dep_v != "TBD" { - self.tcx.sess.struct_span_err(span, "invalid deprecation version found") - .span_label(span, "invalid deprecation version") - .span_label(item_sp, "the stability attribute annotates this item") - .emit(); + self.tcx + .sess + .emit_err(InvalidDeprecationVersion { span, item_sp }); } break; } @@ -271,7 +262,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } - if let Stability { level: Unstable { implied_by: Some(implied_by), .. }, feature } = stab { + if let Stability { level: Unstable { implied_by: Some(implied_by), .. }, feature } = + stab + { self.index.implications.insert(implied_by, feature); } @@ -531,7 +524,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { let stab = self.tcx.stability().local_stability(def_id); if !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(def_id) { let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); - self.tcx.sess.span_err(span, &format!("{} has missing stability attribute", descr)); + self.tcx.sess.emit_err(MissingStabilityAttr { span, descr }); } } @@ -551,7 +544,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { if is_const && is_stable && missing_const_stability_attribute && is_reachable { let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); - self.tcx.sess.span_err(span, &format!("{descr} has missing const stability attribute")); + self.tcx.sess.emit_err(MissingConstStabAttr { span, descr }); } } } @@ -764,11 +757,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { && *constness == hir::Constness::Const && const_stab.map_or(false, |(stab, _)| stab.is_const_stable()) { - self.tcx - .sess - .struct_span_err(item.span, "trait implementations cannot be const stable yet") - .note("see issue #67792 for more information") - .emit(); + self.tcx.sess.emit_err(TraitImplConstStable { span: item.span }); } } @@ -929,7 +918,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { } if !lang_features.insert(feature) { // Warn if the user enables a lang feature multiple times. - duplicate_feature_err(tcx.sess, span, feature); + tcx.sess.emit_err(DuplicateFeatureErr { span, feature }); } } @@ -937,18 +926,14 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let mut remaining_lib_features = FxIndexMap::default(); for (feature, span) in declared_lib_features { if !tcx.sess.opts.unstable_features.is_nightly_build() { - struct_span_err!( - tcx.sess, - *span, - E0554, - "`#![feature]` may not be used on the {} release channel", - env!("CFG_RELEASE_CHANNEL") - ) - .emit(); + tcx.sess.emit_err(FeatureOnlyOnNightly { + span: *span, + release_channel: env!("CFG_RELEASE_CHANNEL"), + }); } if remaining_lib_features.contains_key(&feature) { // Warn if the user enables a lib feature multiple times. - duplicate_feature_err(tcx.sess, *span, *feature); + tcx.sess.emit_err(DuplicateFeatureErr { span: *span, feature: *feature }); } remaining_lib_features.insert(feature, *span); } @@ -1049,23 +1034,18 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { } for (feature, span) in remaining_lib_features { - struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit(); + tcx.sess.emit_err(UnknownFeature { span, feature: *feature }); } for (implied_by, feature) in remaining_implications { let local_defined_features = tcx.lib_features(()); - let span = local_defined_features + let span = *local_defined_features .stable .get(&feature) .map(|(_, span)| span) .or_else(|| local_defined_features.unstable.get(&feature)) .expect("feature that implied another does not exist"); - tcx.sess - .struct_span_err( - *span, - format!("feature `{implied_by}` implying `{feature}` does not exist"), - ) - .emit(); + tcx.sess.emit_err(ImpliedFeatureNotExist { span, feature, implied_by }); } // FIXME(#44232): the `used_features` table no longer exists, so we @@ -1088,21 +1068,20 @@ fn unnecessary_partially_stable_feature_lint( by the feature `{implies}`" ), |lint| { - lint - .span_suggestion( - span, - &format!( + lint.span_suggestion( + span, + &format!( "if you are using features which are still unstable, change to using `{implies}`" ), - implies, - Applicability::MaybeIncorrect, - ) - .span_suggestion( - tcx.sess.source_map().span_extend_to_line(span), - "if you are using features which are now stable, remove this line", - "", - Applicability::MaybeIncorrect, - ) + implies, + Applicability::MaybeIncorrect, + ) + .span_suggestion( + tcx.sess.source_map().span_extend_to_line(span), + "if you are using features which are now stable, remove this line", + "", + Applicability::MaybeIncorrect, + ) }, ); } @@ -1120,20 +1099,3 @@ fn unnecessary_stable_feature_lint( lint }); } - -fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) { - struct_span_err!(sess, span, E0636, "the feature `{}` has already been declared", feature) - .emit(); -} - -fn missing_const_err(session: &Session, fn_sig_span: Span, const_span: Span) { - const ERROR_MSG: &'static str = "attributes `#[rustc_const_unstable]` \ - and `#[rustc_const_stable]` require \ - the function or method to be `const`"; - - session - .struct_span_err(fn_sig_span, ERROR_MSG) - .span_help(fn_sig_span, "make the function or method const") - .span_label(const_span, "attribute specified here") - .emit(); -}