Skip to content

Commit

Permalink
Make feature key optional for rustc_stable, rustc_const_stable attrib…
Browse files Browse the repository at this point in the history
…utes

… so partial stabilizations no longer have to make up a feature name
that never existed as unstable for the stabilized subset of the API.
  • Loading branch information
jplatte committed Sep 2, 2021
1 parent b27ccbc commit bf8a53e
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 41 deletions.
44 changes: 22 additions & 22 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,13 @@ pub enum OptimizeAttr {
#[derive(HashStable_Generic)]
pub struct Stability {
pub level: StabilityLevel,
pub feature: Symbol,
}

/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct ConstStability {
pub level: StabilityLevel,
pub feature: Symbol,
/// whether the function has a `#[rustc_promotable]` attribute
pub promotable: bool,
}
Expand All @@ -113,8 +111,18 @@ pub struct ConstStability {
#[derive(HashStable_Generic)]
pub enum StabilityLevel {
// Reason for the current stability level and the relevant rust-lang issue
Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
Stable { since: Symbol },
Unstable {
reason: Option<Symbol>,
feature: Symbol,
issue: Option<NonZeroU32>,
is_soft: bool,
},
Stable {
since: Symbol,
// feature flag, should not be set when the feature name remains in use
// for unstable items (i.e. when partially stabilizing a feature)
feature: Option<Symbol>,
},
}

impl StabilityLevel {
Expand Down Expand Up @@ -309,14 +317,12 @@ where
);
continue;
}
let level = Unstable { reason, issue: issue_num, is_soft };
let level = Unstable { reason, feature, issue: issue_num, is_soft };
if sym::unstable == meta_name {
stab = Some((Stability { level, feature }, attr.span));
stab = Some((Stability { level }, attr.span));
} else {
const_stab = Some((
ConstStability { level, feature, promotable: false },
attr.span,
));
const_stab =
Some((ConstStability { level, promotable: false }, attr.span));
}
}
(None, _, _) => {
Expand Down Expand Up @@ -385,22 +391,16 @@ where
}
}

match (feature, since) {
(Some(feature), Some(since)) => {
let level = Stable { since };
match since {
Some(since) => {
let level = Stable { since, feature };
if sym::stable == meta_name {
stab = Some((Stability { level, feature }, attr.span));
stab = Some((Stability { level }, attr.span));
} else {
const_stab = Some((
ConstStability { level, feature, promotable: false },
attr.span,
));
const_stab =
Some((ConstStability { level, promotable: false }, attr.span));
}
}
(None, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
continue;
}
_ => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
continue;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl<'tcx> TyCtxt<'tcx> {

match stability {
Some(&Stability {
level: attr::Unstable { reason, issue, is_soft }, feature, ..
level: attr::Unstable { reason, feature, issue, is_soft }, ..
}) => {
if span.allows_unstable(feature) {
debug!("stability: skipping span={:?} since it is internal", span);
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_mir/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_attr::StabilityLevel;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::hir::map::blocks::FnLikeNode;
Expand Down Expand Up @@ -27,7 +28,11 @@ pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
if tcx.is_const_fn_raw(def_id) {
let const_stab = tcx.lookup_const_stability(def_id)?;
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
if let StabilityLevel::Unstable { feature, .. } = const_stab.level {
Some(feature)
} else {
None
}
} else {
None
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {

// Check if deprecated_since < stable_since. If it is,
// this is *almost surely* an accident.
if let (&Some(dep_since), &attr::Stable { since: stab_since }) =
if let (&Some(dep_since), &attr::Stable { since: stab_since, .. }) =
(&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
{
// Explicit version of iter::order::lt to handle parse errors properly
Expand Down Expand Up @@ -701,10 +701,10 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
let stability = tcx.intern_stability(Stability {
level: attr::StabilityLevel::Unstable {
reason: Some(Symbol::intern(reason)),
feature: sym::rustc_private,
issue: NonZeroU32::new(27812),
is_soft: false,
},
feature: sym::rustc_private,
});
annotator.parent_stab = Some(stability);
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,8 +1141,7 @@ impl<'a> Resolver<'a> {
) {
let span = path.span;
if let Some(stability) = &ext.stability {
if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level {
let feature = stability.feature;
if let StabilityLevel::Unstable { reason, feature, issue, is_soft } = stability.level {
if !self.active_features.contains(&feature) && !span.allows_unstable(feature) {
let lint_buffer = &mut self.lint_buffer;
let soft_handler =
Expand Down
5 changes: 3 additions & 2 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::iter::once;
use std::sync::Arc;

use rustc_ast as ast;
use rustc_attr::StabilityLevel;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
Expand Down Expand Up @@ -356,7 +357,7 @@ crate fn build_impl(
}

if let Some(stab) = tcx.lookup_stability(did) {
if stab.level.is_unstable() && stab.feature == sym::rustc_private {
if let StabilityLevel::Unstable { feature: sym::rustc_private, .. } = &stab.level {
return;
}
}
Expand Down Expand Up @@ -388,7 +389,7 @@ crate fn build_impl(
}

if let Some(stab) = tcx.lookup_stability(did) {
if stab.level.is_unstable() && stab.feature == sym::rustc_private {
if let StabilityLevel::Unstable { feature: sym::rustc_private, .. } = &stab.level {
return;
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,13 @@ fn short_item_info(

// Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
// Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item
if let Some(StabilityLevel::Unstable { reason, feature, issue, .. }) = item
.stability(cx.tcx())
.as_ref()
.filter(|stab| stab.feature != sym::rustc_private)
.map(|stab| (stab.level, stab.feature))
.filter(|stab| {
!matches!(stab.level, StabilityLevel::Unstable { feature: sym::rustc_private, .. })
})
.map(|stab| stab.level)
{
let mut message =
"<span class=\"emoji\">🔬</span> This is a nightly-only experimental API.".to_owned();
Expand Down Expand Up @@ -801,7 +803,7 @@ fn render_stability_since_raw(

match (ver, const_stability) {
// stable and const stable
(Some(v), Some(ConstStability { level: StabilityLevel::Stable { since }, .. }))
(Some(v), Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. }))
if Some(since.as_str()).as_deref() != containing_const_ver =>
{
write!(
Expand All @@ -813,7 +815,7 @@ fn render_stability_since_raw(
// stable and const unstable
(
Some(v),
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }),
Some(ConstStability { level: StabilityLevel::Unstable { issue, feature, .. }, .. }),
) => {
write!(
w,
Expand Down
10 changes: 5 additions & 5 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clean::AttributesExt;
use std::cmp::Ordering;
use std::fmt;

use rustc_attr::StabilityLevel;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def::CtorKind;
Expand Down Expand Up @@ -414,11 +415,10 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->

// The "rustc_private" crates are permanently unstable so it makes no sense
// to render "unstable" everywhere.
if item
.stability(tcx)
.as_ref()
.map(|s| s.level.is_unstable() && s.feature != sym::rustc_private)
== Some(true)
if item.stability(tcx).as_ref().map(|s| {
matches!(s.level, StabilityLevel::Unstable { feature, .. } if feature != sym::rustc_private)
})
== Some(true)
{
tags += &tag_html("unstable", "", "Experimental");
}
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(crate_visibility_modifier)]
#![feature(never_type)]
#![feature(once_cell)]
#![feature(option_result_contains)]
#![feature(type_ascription)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ fn check_terminator(
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<&RustcVersion>) -> bool {
rustc_mir::const_eval::is_const_fn(tcx, def_id)
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
if let rustc_attr::StabilityLevel::Stable { since } = const_stab.level {
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
// function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`.
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
Expand Down

0 comments on commit bf8a53e

Please sign in to comment.