migrate stability.rs to translateable diagnostics
This commit is contained in:
parent
3fe8e004e9
commit
be4059dd3e
3 changed files with 209 additions and 84 deletions
|
@ -600,3 +600,53 @@ passes_attribute_should_be_applied_to =
|
||||||
|
|
||||||
passes_transparent_incompatible =
|
passes_transparent_incompatible =
|
||||||
transparent {$target} cannot have other repr hints
|
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 hint_spans: Vec<Span>,
|
||||||
pub target: String,
|
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,
|
//! A pass that annotates every item and method with its stability level,
|
||||||
//! propagating default levels lexically from parent to children ast nodes.
|
//! 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::{
|
use rustc_attr::{
|
||||||
self as attr, rust_version_symbol, ConstStability, Stability, StabilityLevel, Unstable,
|
self as attr, rust_version_symbol, ConstStability, Stability, StabilityLevel, Unstable,
|
||||||
UnstableReason, VERSION_PLACEHOLDER,
|
UnstableReason, VERSION_PLACEHOLDER,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
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 as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
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_middle::ty::{query::Providers, TyCtxt};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
|
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
|
||||||
use rustc_session::Session;
|
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
@ -179,7 +183,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
if !self.in_trait_impl
|
if !self.in_trait_impl
|
||||||
|| (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id()))
|
|| (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 let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
|
||||||
if stab.is_none() {
|
if stab.is_none() {
|
||||||
struct_span_err!(
|
self.tcx.sess.emit_err(DeprecatedAttribute { span: *span });
|
||||||
self.tcx.sess,
|
|
||||||
*span,
|
|
||||||
E0549,
|
|
||||||
"deprecated attribute must be paired with \
|
|
||||||
either stable or unstable attribute"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,10 +219,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
if kind == AnnotationKind::Prohibited
|
if kind == AnnotationKind::Prohibited
|
||||||
|| (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated)
|
|| (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated)
|
||||||
{
|
{
|
||||||
self.tcx.sess.struct_span_err(span,"this stability annotation is useless")
|
self.tcx.sess.emit_err(UselessStability { span, item_sp });
|
||||||
.span_label(span, "useless stability annotation")
|
|
||||||
.span_label(item_sp, "the stability attribute annotates this item")
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("annotate: found {:?}", stab);
|
debug!("annotate: found {:?}", stab);
|
||||||
|
@ -239,19 +235,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
match stab_v.parse::<u64>() {
|
match stab_v.parse::<u64>() {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.tcx.sess.struct_span_err(span, "invalid stability version found")
|
self.tcx.sess.emit_err(InvalidStability { span, item_sp });
|
||||||
.span_label(span, "invalid stability version")
|
|
||||||
.span_label(item_sp, "the stability attribute annotates this item")
|
|
||||||
.emit();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(stab_vp) => match dep_v.parse::<u64>() {
|
Ok(stab_vp) => match dep_v.parse::<u64>() {
|
||||||
Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
|
Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
self.tcx.sess.struct_span_err(span, "an API can't be stabilized after it is deprecated")
|
self.tcx
|
||||||
.span_label(span, "invalid version")
|
.sess
|
||||||
.span_label(item_sp, "the stability attribute annotates this item")
|
.emit_err(CannotStabilizeDeprecated { span, item_sp });
|
||||||
.emit();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ordering::Equal => continue,
|
Ordering::Equal => continue,
|
||||||
|
@ -259,10 +251,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
if dep_v != "TBD" {
|
if dep_v != "TBD" {
|
||||||
self.tcx.sess.struct_span_err(span, "invalid deprecation version found")
|
self.tcx
|
||||||
.span_label(span, "invalid deprecation version")
|
.sess
|
||||||
.span_label(item_sp, "the stability attribute annotates this item")
|
.emit_err(InvalidDeprecationVersion { span, item_sp });
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
break;
|
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);
|
self.index.implications.insert(implied_by, feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +524,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
|
||||||
let stab = self.tcx.stability().local_stability(def_id);
|
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) {
|
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());
|
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 {
|
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());
|
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
|
&& *constness == hir::Constness::Const
|
||||||
&& const_stab.map_or(false, |(stab, _)| stab.is_const_stable())
|
&& const_stab.map_or(false, |(stab, _)| stab.is_const_stable())
|
||||||
{
|
{
|
||||||
self.tcx
|
self.tcx.sess.emit_err(TraitImplConstStable { span: item.span });
|
||||||
.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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,7 +918,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
|
||||||
}
|
}
|
||||||
if !lang_features.insert(feature) {
|
if !lang_features.insert(feature) {
|
||||||
// Warn if the user enables a lang feature multiple times.
|
// 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();
|
let mut remaining_lib_features = FxIndexMap::default();
|
||||||
for (feature, span) in declared_lib_features {
|
for (feature, span) in declared_lib_features {
|
||||||
if !tcx.sess.opts.unstable_features.is_nightly_build() {
|
if !tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||||
struct_span_err!(
|
tcx.sess.emit_err(FeatureOnlyOnNightly {
|
||||||
tcx.sess,
|
span: *span,
|
||||||
*span,
|
release_channel: env!("CFG_RELEASE_CHANNEL"),
|
||||||
E0554,
|
});
|
||||||
"`#![feature]` may not be used on the {} release channel",
|
|
||||||
env!("CFG_RELEASE_CHANNEL")
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
if remaining_lib_features.contains_key(&feature) {
|
if remaining_lib_features.contains_key(&feature) {
|
||||||
// Warn if the user enables a lib feature multiple times.
|
// 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);
|
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 {
|
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 {
|
for (implied_by, feature) in remaining_implications {
|
||||||
let local_defined_features = tcx.lib_features(());
|
let local_defined_features = tcx.lib_features(());
|
||||||
let span = local_defined_features
|
let span = *local_defined_features
|
||||||
.stable
|
.stable
|
||||||
.get(&feature)
|
.get(&feature)
|
||||||
.map(|(_, span)| span)
|
.map(|(_, span)| span)
|
||||||
.or_else(|| local_defined_features.unstable.get(&feature))
|
.or_else(|| local_defined_features.unstable.get(&feature))
|
||||||
.expect("feature that implied another does not exist");
|
.expect("feature that implied another does not exist");
|
||||||
tcx.sess
|
tcx.sess.emit_err(ImpliedFeatureNotExist { span, feature, implied_by });
|
||||||
.struct_span_err(
|
|
||||||
*span,
|
|
||||||
format!("feature `{implied_by}` implying `{feature}` does not exist"),
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#44232): the `used_features` table no longer exists, so we
|
// 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}`"
|
by the feature `{implies}`"
|
||||||
),
|
),
|
||||||
|lint| {
|
|lint| {
|
||||||
lint
|
lint.span_suggestion(
|
||||||
.span_suggestion(
|
span,
|
||||||
span,
|
&format!(
|
||||||
&format!(
|
|
||||||
"if you are using features which are still unstable, change to using `{implies}`"
|
"if you are using features which are still unstable, change to using `{implies}`"
|
||||||
),
|
),
|
||||||
implies,
|
implies,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
)
|
)
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
tcx.sess.source_map().span_extend_to_line(span),
|
tcx.sess.source_map().span_extend_to_line(span),
|
||||||
"if you are using features which are now stable, remove this line",
|
"if you are using features which are now stable, remove this line",
|
||||||
"",
|
"",
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1120,20 +1099,3 @@ fn unnecessary_stable_feature_lint(
|
||||||
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…
Add table
Add a link
Reference in a new issue