Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 21c947b

Browse files
committed
rustdoc: report all unstable features needed for items
1 parent 1ed93d6 commit 21c947b

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

‎src/librustdoc/passes/propagate_stability.rs‎

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,17 @@ pub(crate) const PROPAGATE_STABILITY: Pass = Pass {
2121
};
2222

2323
pub(crate) fn propagate_stability(cr: Crate, cx: &mut DocContext<'_>) -> Crate {
24-
let crate_stability = cx.tcx.lookup_stability(CRATE_DEF_ID);
24+
let crate_stability = cx.tcx.lookup_stability(CRATE_DEF_ID).cloned();
2525
StabilityPropagator { parent_stability: crate_stability, cx }.fold_crate(cr)
2626
}
2727

2828
struct StabilityPropagator<'a, 'tcx> {
29-
parent_stability: Option<&'tcxStability>,
29+
parent_stability: Option<Stability>,
3030
cx: &'a mut DocContext<'tcx>,
3131
}
3232

3333
impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
3434
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
35-
let parent_stability = self.parent_stability;
36-
3735
let stability = match item.item_id {
3836
ItemId::DefId(def_id) => {
3937
let own_stability = self.cx.tcx.lookup_stability(def_id);
@@ -59,9 +57,7 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
5957
| ItemKind::MacroItem(..)
6058
| ItemKind::ProcMacroItem(..)
6159
| ItemKind::ConstantItem(..) => {
62-
// If any of the item's parents was stabilized later or is still unstable,
63-
// then use the parent's stability instead.
64-
merge_stability(own_stability, parent_stability)
60+
merge_stability(own_stability, self.parent_stability.as_ref())
6561
}
6662

6763
// Don't inherit the parent's stability for these items, because they
@@ -74,7 +70,7 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
7470
| ItemKind::TyAssocTypeItem(..)
7571
| ItemKind::AssocTypeItem(..)
7672
| ItemKind::PrimitiveItem(..)
77-
| ItemKind::KeywordItem => own_stability,
73+
| ItemKind::KeywordItem => own_stability.cloned(),
7874

7975
ItemKind::StrippedItem(..) => unreachable!(),
8076
}
@@ -85,28 +81,53 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
8581
}
8682
};
8783

88-
item.inner.stability = stability.cloned();
89-
self.parent_stability = stability;
84+
item.inner.stability = stability.clone();
85+
letparent_stability = std::mem::replace(&mutself.parent_stability,stability);
9086
let item = self.fold_item_recur(item);
9187
self.parent_stability = parent_stability;
9288

9389
Some(item)
9490
}
9591
}
9692

97-
fn merge_stability<'tcx>(
98-
own_stability: Option<&'tcxStability>,
99-
parent_stability: Option<&'tcxStability>,
100-
) -> Option<&'tcxStability> {
93+
fn merge_stability(
94+
own_stability: Option<&Stability>,
95+
parent_stability: Option<&Stability>,
96+
) -> Option<Stability> {
10197
if let Some(own_stab) = own_stability
102-
&& let &StabilityLevel::Stable { since: own_since, allowed_through_unstable_modules: false } =
103-
&own_stab.level
10498
&& let Some(parent_stab) = parent_stability
105-
&& (parent_stab.is_unstable()
106-
|| parent_stab.stable_since().is_some_and(|parent_since| parent_since > own_since))
10799
{
108-
parent_stability
100+
match own_stab.level {
101+
// If any of a stable item's parents were stabilized later or are still unstable,
102+
// then use the parent's stability instead.
103+
StabilityLevel::Stable {
104+
since: own_since,
105+
allowed_through_unstable_modules: false,
106+
..
107+
} if parent_stab.is_unstable()
108+
|| parent_stab
109+
.stable_since()
110+
.is_some_and(|parent_since| parent_since > own_since) =>
111+
{
112+
parent_stability.cloned()
113+
}
114+
115+
// If any of an unstable item's parents depend on other unstable features,
116+
// then use those as well.
117+
StabilityLevel::Unstable { unstables: ref own_gates, reason, is_soft }
118+
if let StabilityLevel::Unstable { unstables: parent_gates, .. } =
119+
&parent_stab.level =>
120+
{
121+
let missing_unstables = parent_gates
122+
.iter()
123+
.filter(|p| !own_gates.iter().any(|u| u.feature == p.feature));
124+
let unstables = own_gates.iter().chain(missing_unstables).cloned().collect();
125+
Some(Stability { level: StabilityLevel::Unstable { unstables, reason, is_soft } })
126+
}
127+
128+
_ => own_stability.cloned(),
129+
}
109130
} else {
110-
own_stability
131+
own_stability.cloned()
111132
}
112133
}

‎tests/rustdoc/stability.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ pub mod unstable {
5555
#[stable(feature = "rust1", since = "1.0.0")]
5656
pub fn foo() {}
5757
}
58+
59+
//@ has stability/unstable/fn.nested_unstable.html \
60+
// '//span[@class="item-info"]//div[@class="stab unstable"]' \
61+
// 'This is a nightly-only experimental API. (test, unstable)'
62+
#[unstable(feature = "test", issue = "none")]
63+
pub fn nested_unstable() {}
5864
}
5965

6066
#[unstable(feature = "unstable", issue = "none")]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /