@@ -21,19 +21,17 @@ pub(crate) const PROPAGATE_STABILITY: Pass = Pass {
2121} ;
2222
2323pub ( 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
2828struct StabilityPropagator < ' a , ' tcx > {
29- parent_stability : Option < & ' tcx Stability > ,
29+ parent_stability : Option < Stability > ,
3030 cx : & ' a mut DocContext < ' tcx > ,
3131}
3232
3333impl < ' 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+ let parent_stability = std :: mem :: replace ( & mut self . 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 < & ' tcx Stability > ,
99- parent_stability : Option < & ' tcx Stability > ,
100- ) -> Option < & ' tcx Stability > {
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}
0 commit comments