Skip to content

Commit

Permalink
Auto merge of rust-lang#132733 - cuviper:beta-next, r=cuviper
Browse files Browse the repository at this point in the history
[beta] backports

- rustdoc: skip stability inheritance for some item kinds rust-lang#132481
- Avoid use imports in thread_local_inner! in static rust-lang#132101
- Also treat `impl` definition parent as transparent regarding modules rust-lang#132453
- Revert "Avoid nested replacement ranges" from rust-lang#129346. rust-lang#132587

r? cuviper
  • Loading branch information
bors committed Nov 8, 2024
2 parents 67512de + 25ab47d commit eb6e3fa
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 45 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,15 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
// };
// };
// ```
//
// It isn't possible to mix a impl in a module with const-anon, but an item can
// be put inside a module and referenced by a impl so we also have to treat the
// item parent as transparent to module and for consistency we have to do the same
// for impl, otherwise the item-def and impl-def won't have the same parent.
let outermost_impl_parent = peel_parent_while(cx.tcx, parent, |tcx, did| {
tcx.def_kind(did) == DefKind::Const
&& tcx.opt_item_name(did) == Some(kw::Underscore)
tcx.def_kind(did) == DefKind::Mod
|| (tcx.def_kind(did) == DefKind::Const
&& tcx.opt_item_name(did) == Some(kw::Underscore))
});

// 2. We check if any of the paths reference a the `impl`-parent.
Expand Down
28 changes: 21 additions & 7 deletions compiler/rustc_parse/src/parser/attr_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,30 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
node_replacements.array_windows()
{
assert!(
node_range.0.end <= next_node_range.0.start,
"Node ranges should be disjoint: ({:?}, {:?}) ({:?}, {:?})",
node_range.0.end <= next_node_range.0.start
|| node_range.0.end >= next_node_range.0.end,
"Node ranges should be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})",
node_range,
tokens,
next_node_range,
next_tokens,
);
}

// Process the replace ranges.
for (node_range, target) in node_replacements.into_iter() {
// Process the replace ranges, starting from the highest start
// position and working our way back. If have tokens like:
//
// `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
//
// Then we will generate replace ranges for both
// the `#[cfg(FALSE)] field: bool` and the entire
// `#[cfg(FALSE)] struct Foo { #[cfg(FALSE)] field: bool }`
//
// By starting processing from the replace range with the greatest
// start position, we ensure that any (outer) replace range which
// encloses another (inner) replace range will fully overwrite the
// inner range's replacement.
for (node_range, target) in node_replacements.into_iter().rev() {
assert!(
!node_range.0.is_empty(),
"Cannot replace an empty node range: {:?}",
Expand Down Expand Up @@ -383,9 +396,10 @@ impl<'a> Parser<'a> {
// from `ParserRange` form to `NodeRange` form. We will perform the actual
// replacement only when we convert the `LazyAttrTokenStream` to an
// `AttrTokenStream`.
self.capture_state
.parser_replacements
.drain(parser_replacements_start..parser_replacements_end)
self.capture_state.parser_replacements
[parser_replacements_start..parser_replacements_end]
.iter()
.cloned()
.chain(inner_attr_parser_replacements)
.map(|(parser_range, data)| {
(NodeRange::new(parser_range, collect_pos.start_pos), data)
Expand Down
9 changes: 4 additions & 5 deletions library/std/src/sys/thread_local/statik.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{
const __INIT: $t = $init;

// NOTE: Please update the shadowing test in `tests/thread.rs` if these types are renamed.
unsafe {
use $crate::thread::LocalKey;
use $crate::thread::local_impl::EagerStorage;

LocalKey::new(|_| {
static VAL: EagerStorage<$t> = EagerStorage { value: __INIT };
$crate::thread::LocalKey::new(|_| {
static VAL: $crate::thread::local_impl::EagerStorage<$t> =
$crate::thread::local_impl::EagerStorage { value: __INIT };
&VAL.value
})
}
Expand Down
74 changes: 57 additions & 17 deletions src/librustdoc/passes/propagate_stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 { .. } => {
Expand All @@ -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
}
}
114 changes: 100 additions & 14 deletions tests/rustdoc/stability.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -26,60 +28,144 @@ 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;

#[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 {}
Loading

0 comments on commit eb6e3fa

Please sign in to comment.