mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
migrate stability.rs to translateable diagnostics
This commit is contained in:
parent
3fe8e004e9
commit
be4059dd3e
@ -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 <https://github.com/rust-lang/rust/issues/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
|
||||
|
@ -1313,3 +1313,116 @@ pub struct TransparentIncompatible {
|
||||
pub hint_spans: Vec<Span>,
|
||||
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,
|
||||
}
|
||||
|
@ -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::<u64>() {
|
||||
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::<u64>() {
|
||||
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 <https://github.com/rust-lang/rust/issues/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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user