diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 64a6f91f02206..10a9cfb626e63 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -138,7 +138,7 @@ pub enum StabilityLevel { /// `#[unstable]` Unstable { /// Reason for the current stability level. - reason: Option, + reason: UnstableReason, /// Relevant `rust-lang/rust` issue. issue: Option, is_soft: bool, @@ -182,6 +182,32 @@ impl StabilityLevel { } } +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(HashStable_Generic)] +pub enum UnstableReason { + None, + Default, + Some(Symbol), +} + +impl UnstableReason { + fn from_opt_reason(reason: Option) -> Self { + // UnstableReason::Default constructed manually + match reason { + Some(r) => Self::Some(r), + None => Self::None, + } + } + + pub fn to_opt_reason(&self) -> Option { + match self { + Self::None => None, + Self::Default => Some(sym::unstable_location_reason_default), + Self::Some(r) => Some(*r), + } + } +} + /// Collects stability info from all stability attributes in `attrs`. /// Returns `None` if no stability attributes are found. pub fn find_stability( @@ -371,7 +397,12 @@ where ); continue; } - let level = Unstable { reason, issue: issue_num, is_soft, implied_by }; + let level = Unstable { + reason: UnstableReason::from_opt_reason(reason), + issue: issue_num, + is_soft, + implied_by, + }; if sym::unstable == meta_name { stab = Some((Stability { level, feature }, attr.span)); } else { diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 0fbad3f0f0f06..414912dd0f7d8 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -475,7 +475,13 @@ impl<'tcx> TyCtxt<'tcx> { } let suggestion = suggestion_for_allocator_api(self, def_id, span, feature); - EvalResult::Deny { feature, reason, issue, suggestion, is_soft } + EvalResult::Deny { + feature, + reason: reason.to_opt_reason(), + issue, + suggestion, + is_soft, + } } Some(_) => { // Stable APIs are always ok to call and deprecated APIs are diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 81b04c414ed9b..ca6a2ac3db34c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -2,7 +2,7 @@ //! propagating default levels lexically from parent to children ast nodes. use attr::StabilityLevel; -use rustc_attr::{self as attr, ConstStability, Stability, Unstable}; +use rustc_attr::{self as attr, ConstStability, Stability, Unstable, UnstableReason}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; @@ -634,12 +634,9 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { // while maintaining the invariant that all sysroot crates are unstable // by default and are unable to be used. if tcx.sess.opts.unstable_opts.force_unstable_if_unmarked { - let reason = "this crate is being loaded from the sysroot, an \ - unstable location; did you mean to load this crate \ - from crates.io via `Cargo.toml` instead?"; let stability = Stability { level: attr::StabilityLevel::Unstable { - reason: Some(Symbol::intern(reason)), + reason: UnstableReason::Default, issue: NonZeroU32::new(27812), is_soft: false, implied_by: None, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 2b5eb12a8a890..070fb9c721b40 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -812,7 +812,7 @@ impl<'a> Resolver<'a> { stability::report_unstable( self.session, feature, - reason, + reason.to_opt_reason(), issue, None, is_soft, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 2ac1ecfe87eb5..68fb166405880 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1527,6 +1527,9 @@ symbols! { unsized_locals, unsized_tuple_coercion, unstable, + unstable_location_reason_default: "this crate is being loaded from the sysroot, an \ + unstable location; did you mean to load this crate \ + from crates.io via `Cargo.toml` instead?", untagged_unions, unused_imports, unused_qualifications,