Skip to content

Commit

Permalink
rustdoc: inherit parent's stability where applicable
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas Markeffsky committed Sep 24, 2024
1 parent 67bb749 commit 2fdeb3b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 9 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub enum StabilityLevel {
}

/// Rust release in which a feature is stabilized.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable_Generic)]
pub enum StableSince {
Version(RustcVersion),
Expand Down
40 changes: 39 additions & 1 deletion src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,45 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool {

impl Item {
pub(crate) fn stability(&self, tcx: TyCtxt<'_>) -> Option<Stability> {
self.def_id().and_then(|did| tcx.lookup_stability(did))
let (mut def_id, mut stability) = if let Some(inlined) = self.inline_stmt_id {
let inlined_def_id = inlined.to_def_id();
if let Some(stability) = tcx.lookup_stability(inlined_def_id) {
(inlined_def_id, stability)
} else {
// For re-exports into crates without `staged_api`, reuse the original stability.
// This is necessary, because we always want to mark unstable items.
let def_id = self.def_id()?;
return tcx.lookup_stability(def_id);
}
} else {
let def_id = self.def_id()?;
let stability = tcx.lookup_stability(def_id)?;
(def_id, stability)
};

let StabilityLevel::Stable { mut since, allowed_through_unstable_modules: false } =
stability.level
else {
return Some(stability);
};

// If any of the item's ancestors was stabilized later or is still unstable,
// then report the ancestor's stability instead.
while let Some(parent_def_id) = tcx.opt_parent(def_id) {
if let Some(parent_stability) = tcx.lookup_stability(parent_def_id) {
match parent_stability.level {
StabilityLevel::Unstable { .. } => return Some(parent_stability),
StabilityLevel::Stable { since: parent_since, .. } => {
if parent_since > since {
stability = parent_stability;
since = parent_since;
}
}
}
}
def_id = parent_def_id;
}
Some(stability)
}

pub(crate) fn const_stability(&self, tcx: TyCtxt<'_>) -> Option<ConstStability> {
Expand Down
18 changes: 12 additions & 6 deletions tests/rustdoc/const-display.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#![crate_name = "foo"]

#![unstable(feature = "humans",
reason = "who ever let humans program computers, we're apparently really bad at it",
issue = "none")]
#![stable(feature = "rust1", since = "1.0.0")]

#![feature(foo, foo2)]
#![feature(staged_api)]
Expand Down Expand Up @@ -48,10 +46,18 @@ pub const unsafe fn foo2_gated() -> u32 { 42 }
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const unsafe fn bar2_gated() -> u32 { 42 }

//@ has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
//@ !hasraw - '//span[@class="since"]'
pub const unsafe fn bar_not_gated() -> u32 { 42 }
#[unstable(
feature = "humans",
reason = "who ever let humans program computers, we're apparently really bad at it",
issue = "none",
)]
pub mod unstable {
//@ has 'foo/unstable/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
//@ !hasraw - '//span[@class="since"]'
pub const unsafe fn bar_not_gated() -> u32 { 42 }
}

#[stable(feature = "rust1", since = "1.0.0")]
pub struct Foo;

impl Foo {
Expand Down
31 changes: 30 additions & 1 deletion tests/rustdoc/stability.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(staged_api)]

#![unstable(feature = "test", issue = "none")]
#![stable(feature = "rust1", since = "1.0.0")]

//@ has stability/index.html
//@ has - '//ul[@class="item-table"]/li[1]//a' AaStable
Expand All @@ -10,6 +10,7 @@
#[stable(feature = "rust2", since = "2.2.2")]
pub struct AaStable;

#[unstable(feature = "test", issue = "none")]
pub struct Unstable {
//@ has stability/struct.Unstable.html \
// '//span[@class="item-info"]//div[@class="stab unstable"]' \
Expand All @@ -21,3 +22,31 @@ pub struct Unstable {

#[stable(feature = "rust2", since = "2.2.2")]
pub struct ZzStable;

#[unstable(feature = "unstable", issue = "none")]
pub mod unstable {
//@ !hasraw stability/unstable/struct.Foo.html '//span[@class="since"]'
//@ has - '//div[@class="stab unstable"]' 'experimental'
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Foo;
}

#[stable(feature = "rust2", since = "2.2.2")]
pub mod stable_later {
//@ has stability/stable_later/struct.Bar.html '//span[@class="since"]' '2.2.2'
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Bar;
}

#[stable(feature = "rust1", since = "1.0.0")]
pub mod stable_earlier {
//@ has stability/stable_earlier/struct.Foo.html '//span[@class="since"]' '1.0.0'
#[doc(inline)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::unstable::Foo;

//@ has stability/stable_earlier/struct.Bar.html '//span[@class="since"]' '1.0.0'
#[doc(inline)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::stable_later::Bar;
}

0 comments on commit 2fdeb3b

Please sign in to comment.