Skip to content

Make feature key optional for rustc_stable, rustc_const_stable attributes #88588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -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,
}
@@ -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 {
@@ -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, _, _) => {
@@ -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;
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
@@ -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);
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;
@@ -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
}
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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);
}
3 changes: 1 addition & 2 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
@@ -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 =
5 changes: 3 additions & 2 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -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};
@@ -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;
}
}
@@ -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;
}
}
12 changes: 7 additions & 5 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -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();
@@ -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!(
@@ -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,
10 changes: 5 additions & 5 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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");
}
1 change: 1 addition & 0 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
#![feature(crate_visibility_modifier)]
#![feature(never_type)]
#![feature(once_cell)]
#![feature(option_result_contains)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed I left this in but removed the use of Option::contains. Will remove with the next push.

#![feature(type_ascription)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]
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
@@ -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.