diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-11-02 12:14:12 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-02 12:14:12 +0100 |
| commit | 6eeb28628935e9445093929e47cdd1872e7bd186 (patch) | |
| tree | d0a6e6bc989e16026d92ff1f3ffee09d19967b4b | |
| parent | 588a4203508ed7c76750c96b482641261630ed36 (diff) | |
| parent | 728315df79d19562b7be11011b54d20406abd1f4 (diff) | |
| download | rust-6eeb28628935e9445093929e47cdd1872e7bd186.tar.gz rust-6eeb28628935e9445093929e47cdd1872e7bd186.zip | |
Rollup merge of #132481 - lukas-code:doc-stab3, r=GuillaumeGomez
rustdoc: skip stability inheritance for some item kinds For some item kinds it's incorrect to inherit their parent's stability, because they might be accessible without referring to the parent directly -- This PR removes the stability inheritance for these items and reverts their displayed stability to that before https://github.com/rust-lang/rust/pull/130798. Impl items, both inherent and trait impls, have a stability, but it is ignored when checking for enabled features. However, impl items are automatically unstable if they're nested inside an unstable module -- this caused the children of impl to inherit the instability and lead to https://github.com/rust-lang/rust/issues/132440. Furthermore, for associated items only the stability of the associated item itself is checked and not that of its parent impl. This is true even for trait impls and we have [relied on this behavior in the standard library in the past](https://doc.rust-lang.org/1.37.0/std/slice/trait.SliceConcatExt.html#tymethod.concat), so these also shouldn't inherit the impl's stability. I've also removed the stability inheritance for primitives and keywords so that viewing e.g. [the `i32` docs on `core`](https://doc.rust-lang.org/nightly/core/primitive.i32.html) will no longer show "since 1.6.0". Note that we currently don't annotate stability for the keyword docs, but if we start doing so in the future then this is probably more correct. fixes (after backport) https://github.com/rust-lang/rust/issues/132440
| -rw-r--r-- | src/librustdoc/passes/propagate_stability.rs | 74 | ||||
| -rw-r--r-- | tests/rustdoc/stability.rs | 114 |
2 files changed, 157 insertions, 31 deletions
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index f55479687f8..a28487cc79e 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -9,7 +9,7 @@ use rustc_attr::{Stability, StabilityLevel}; use rustc_hir::def_id::CRATE_DEF_ID; -use crate::clean::{Crate, Item, ItemId}; +use crate::clean::{Crate, Item, ItemId, ItemKind}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::Pass; @@ -38,22 +38,45 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> { ItemId::DefId(def_id) => { let own_stability = self.cx.tcx.lookup_stability(def_id); - // If any of the item's parents was stabilized later or is still unstable, - // then use the parent's stability instead. - if let Some(own_stab) = own_stability - && let StabilityLevel::Stable { - since: own_since, - allowed_through_unstable_modules: false, - } = own_stab.level - && let Some(parent_stab) = parent_stability - && (parent_stab.is_unstable() - || parent_stab - .stable_since() - .is_some_and(|parent_since| parent_since > own_since)) - { - parent_stability - } else { - own_stability + let (ItemKind::StrippedItem(box kind) | kind) = &item.kind; + match kind { + ItemKind::ExternCrateItem { .. } + | ItemKind::ImportItem(..) + | ItemKind::StructItem(..) + | ItemKind::UnionItem(..) + | ItemKind::EnumItem(..) + | ItemKind::FunctionItem(..) + | ItemKind::ModuleItem(..) + | ItemKind::TypeAliasItem(..) + | ItemKind::StaticItem(..) + | ItemKind::TraitItem(..) + | ItemKind::TraitAliasItem(..) + | ItemKind::StructFieldItem(..) + | ItemKind::VariantItem(..) + | ItemKind::ForeignFunctionItem(..) + | ItemKind::ForeignStaticItem(..) + | ItemKind::ForeignTypeItem + | ItemKind::MacroItem(..) + | ItemKind::ProcMacroItem(..) + | ItemKind::ConstantItem(..) => { + // If any of the item's parents was stabilized later or is still unstable, + // then use the parent's stability instead. + merge_stability(own_stability, parent_stability) + } + + // Don't inherit the parent's stability for these items, because they + // are potentially accessible even if the parent is more unstable. + ItemKind::ImplItem(..) + | ItemKind::TyMethodItem(..) + | ItemKind::MethodItem(..) + | ItemKind::TyAssocConstItem(..) + | ItemKind::AssocConstItem(..) + | ItemKind::TyAssocTypeItem(..) + | ItemKind::AssocTypeItem(..) + | ItemKind::PrimitiveItem(..) + | ItemKind::KeywordItem => own_stability, + + ItemKind::StrippedItem(..) => unreachable!(), } } ItemId::Auto { .. } | ItemId::Blanket { .. } => { @@ -70,3 +93,20 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> { Some(item) } } + +fn merge_stability( + own_stability: Option<Stability>, + parent_stability: Option<Stability>, +) -> Option<Stability> { + if let Some(own_stab) = own_stability + && let StabilityLevel::Stable { since: own_since, allowed_through_unstable_modules: false } = + own_stab.level + && let Some(parent_stab) = parent_stability + && (parent_stab.is_unstable() + || parent_stab.stable_since().is_some_and(|parent_since| parent_since > own_since)) + { + parent_stability + } else { + own_stability + } +} diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs index fc72154cad8..550eb0bc137 100644 --- a/tests/rustdoc/stability.rs +++ b/tests/rustdoc/stability.rs @@ -1,6 +1,8 @@ #![feature(staged_api)] +#![feature(rustc_attrs)] +#![feature(rustdoc_internals)] -#![stable(feature = "rust1", since = "1.0.0")] +#![stable(feature = "core", since = "1.6.0")] //@ has stability/index.html //@ has - '//ul[@class="item-table"]/li[1]//a' AaStable @@ -26,7 +28,7 @@ pub struct ZzStable; #[unstable(feature = "unstable", issue = "none")] pub mod unstable { //@ !hasraw stability/unstable/struct.StableInUnstable.html \ - // '//span[@class="since"]' + // '//div[@class="main-heading"]//span[@class="since"]' //@ has - '//div[@class="stab unstable"]' 'experimental' #[stable(feature = "rust1", since = "1.0.0")] pub struct StableInUnstable; @@ -34,52 +36,136 @@ pub mod unstable { #[stable(feature = "rust1", since = "1.0.0")] pub mod stable_in_unstable { //@ !hasraw stability/unstable/stable_in_unstable/struct.Inner.html \ - // '//span[@class="since"]' + // '//div[@class="main-heading"]//span[@class="since"]' //@ has - '//div[@class="stab unstable"]' 'experimental' #[stable(feature = "rust1", since = "1.0.0")] pub struct Inner; } + + //@ has stability/struct.AaStable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '2.2.2' + impl super::AaStable { + #[stable(feature = "rust2", since = "2.2.2")] + pub fn foo() {} + } + + //@ has stability/unstable/struct.StableInUnstable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' + impl StableInUnstable { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn foo() {} + } +} + +#[unstable(feature = "unstable", issue = "none")] +#[doc(hidden)] +pub mod unstable_stripped { + //@ has stability/struct.AaStable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '2.2.2' + impl super::AaStable { + #[stable(feature = "rust2", since = "2.2.2")] + pub fn foo() {} + } } #[stable(feature = "rust2", since = "2.2.2")] pub mod stable_later { //@ has stability/stable_later/struct.StableInLater.html \ - // '//span[@class="since"]' '2.2.2' + // '//div[@class="main-heading"]//span[@class="since"]' '2.2.2' #[stable(feature = "rust1", since = "1.0.0")] pub struct StableInLater; #[stable(feature = "rust1", since = "1.0.0")] pub mod stable_in_later { //@ has stability/stable_later/stable_in_later/struct.Inner.html \ - // '//span[@class="since"]' '2.2.2' + // '//div[@class="main-heading"]//span[@class="since"]' '2.2.2' #[stable(feature = "rust1", since = "1.0.0")] pub struct Inner; } } #[stable(feature = "rust1", since = "1.0.0")] -pub mod stable_earlier { - //@ has stability/stable_earlier/struct.StableInUnstable.html \ - // '//span[@class="since"]' '1.0.0' +#[rustc_allowed_through_unstable_modules] +pub mod stable_earlier1 { + //@ has stability/stable_earlier1/struct.StableInUnstable.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::unstable::StableInUnstable; + + //@ has stability/stable_earlier1/stable_in_unstable/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::unstable::stable_in_unstable; + + //@ has stability/stable_earlier1/struct.StableInLater.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::stable_later::StableInLater; + + //@ has stability/stable_earlier1/stable_in_later/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::stable_later::stable_in_later; +} + +/// These will inherit the crate stability. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod stable_earlier2 { + //@ has stability/stable_earlier2/struct.StableInUnstable.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' + //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::unstable::StableInUnstable; - //@ has stability/stable_earlier/stable_in_unstable/struct.Inner.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/stable_in_unstable/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::unstable::stable_in_unstable; - //@ has stability/stable_earlier/struct.StableInLater.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/struct.StableInLater.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::stable_later::StableInLater; - //@ has stability/stable_earlier/stable_in_later/struct.Inner.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/stable_in_later/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::stable_later::stable_in_later; } + +//@ !hasraw stability/trait.UnstableTraitWithStableMethod.html \ +// '//div[@class="main-heading"]//span[@class="since"]' +//@ has - '//*[@id="tymethod.foo"]//span[@class="since"]' '1.0.0' +//@ has - '//*[@id="method.bar"]//span[@class="since"]' '1.0.0' +#[unstable(feature = "unstable", issue = "none")] +pub trait UnstableTraitWithStableMethod { + #[stable(feature = "rust1", since = "1.0.0")] + fn foo(); + #[stable(feature = "rust1", since = "1.0.0")] + fn bar() {} +} + +//@ has stability/primitive.i32.html \ +// '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' +#[rustc_doc_primitive = "i32"] +// +/// `i32` is always stable in 1.0, even if you look at it from core. +#[stable(feature = "rust1", since = "1.0.0")] +mod prim_i32 {} + +//@ has stability/keyword.if.html \ +// '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' +#[doc(keyword = "if")] +// +/// We currently don't document stability for keywords, but let's test it anyway. +#[stable(feature = "rust1", since = "1.0.0")] +mod if_keyword {} |
