@@ -45,15 +45,17 @@ use std::rc::Rc;
4545use std:: { fs, str} ;
4646
4747use rinja:: Template ;
48- use rustc_attr:: { ConstStability , DeprecatedSince , Deprecation , StabilityLevel , StableSince } ;
48+ use rustc_attr:: {
49+ ConstStability , ConstStabilityLevel , DeprecatedSince , Deprecation , StabilityLevel , StableSince ,
50+ } ;
4951use rustc_data_structures:: captures:: Captures ;
5052use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
5153use rustc_hir:: Mutability ;
5254use rustc_hir:: def_id:: { DefId , DefIdSet } ;
5355use rustc_middle:: ty:: print:: PrintTraitRefExt ;
5456use rustc_middle:: ty:: { self , TyCtxt } ;
5557use rustc_session:: RustcVersion ;
56- use rustc_span:: symbol:: { Symbol , sym } ;
58+ use rustc_span:: symbol:: Symbol ;
5759use rustc_span:: { BytePos , DUMMY_SP , FileName , RealFileName } ;
5860use serde:: ser:: SerializeMap ;
5961use serde:: { Serialize , Serializer } ;
@@ -674,17 +676,23 @@ enum ShortItemInfo {
674676 Deprecation {
675677 message : String ,
676678 } ,
677- /// The feature corresponding to an unstable item, and optionally
678- /// a tracking issue URL and number.
679+ /// The features corresponding to an unstable item, and optionally
680+ /// a tracking issue URL and number for each .
679681 Unstable {
680- feature : String ,
681- tracking : Option < ( String , u32 ) > ,
682+ features : Vec < UnstableFeature > ,
682683 } ,
683684 Portability {
684685 message : String ,
685686 } ,
686687}
687688
689+ #[ derive( Template ) ]
690+ #[ template( path = "unstable_feature.html" ) ]
691+ struct UnstableFeature {
692+ feature : String ,
693+ tracking : Option < ( String , u32 ) > ,
694+ }
695+
688696/// Render the stability, deprecation and portability information that is displayed at the top of
689697/// the item's documentation.
690698fn short_item_info (
@@ -723,19 +731,24 @@ fn short_item_info(
723731
724732 // Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
725733 // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
726- if let Some ( ( StabilityLevel :: Unstable { reason : _ , issue , .. } , feature ) ) = item
734+ if let Some ( StabilityLevel :: Unstable { unstables , .. } ) = item
727735 . stability ( cx. tcx ( ) )
728736 . as_ref ( )
729- . filter ( |stab| stab. feature != sym :: rustc_private )
730- . map ( |stab| ( stab. level , stab . feature ) )
737+ . filter ( |stab| ! stab. is_rustc_private ( ) )
738+ . map ( |stab| & stab. level )
731739 {
732- let tracking = if let ( Some ( url) , Some ( issue) ) = ( & cx. shared . issue_tracker_base_url , issue)
733- {
734- Some ( ( url. clone ( ) , issue. get ( ) ) )
735- } else {
736- None
740+ let track = |issue : Option < std:: num:: NonZero < u32 > > | {
741+ if let ( Some ( url) , Some ( issue) ) = ( & cx. shared . issue_tracker_base_url , issue) {
742+ Some ( ( url. clone ( ) , issue. get ( ) ) )
743+ } else {
744+ None
745+ }
737746 } ;
738- extra_info. push ( ShortItemInfo :: Unstable { feature : feature. to_string ( ) , tracking } ) ;
747+ let features = unstables
748+ . iter ( )
749+ . map ( |u| UnstableFeature { feature : u. feature . to_string ( ) , tracking : track ( u. issue ) } )
750+ . collect ( ) ;
751+ extra_info. push ( ShortItemInfo :: Unstable { features } ) ;
739752 }
740753
741754 if let Some ( message) = portability ( item, parent) {
@@ -989,7 +1002,7 @@ fn assoc_method(
9891002fn render_stability_since_raw_with_extra (
9901003 w : & mut Buffer ,
9911004 stable_version : Option < StableSince > ,
992- const_stability : Option < ConstStability > ,
1005+ const_stability : Option < & ConstStability > ,
9931006 extra_class : & str ,
9941007) -> bool {
9951008 let mut title = String :: new ( ) ;
@@ -1001,18 +1014,20 @@ fn render_stability_since_raw_with_extra(
10011014 }
10021015
10031016 let const_title_and_stability = match const_stability {
1004- Some ( ConstStability { level : StabilityLevel :: Stable { since, .. } , .. } ) => {
1017+ Some ( ConstStability { level : ConstStabilityLevel :: Stable { since, .. } , .. } ) => {
10051018 since_to_string ( & since)
10061019 . map ( |since| ( format ! ( "const since {since}" ) , format ! ( "const: {since}" ) ) )
10071020 }
1008- Some ( ConstStability { level : StabilityLevel :: Unstable { issue , .. } , feature , .. } ) => {
1021+ Some ( ConstStability { level : ConstStabilityLevel :: Unstable { unstables , .. } , .. } ) => {
10091022 if stable_version. is_none ( ) {
10101023 // don't display const unstable if entirely unstable
10111024 None
10121025 } else {
1013- let unstable = if let Some ( n) = issue
1014- && let Some ( feature) = feature
1015- {
1026+ // if constness depends on multiple unstable features, only link to the first
1027+ // tracking issue found, to save space. the issue description should link to issues
1028+ // for any features it can intersect with
1029+ let feature_issue = unstables. iter ( ) . find_map ( |u| u. issue . map ( |n| ( u. feature , n) ) ) ;
1030+ let unstable = if let Some ( ( feature, n) ) = feature_issue {
10161031 format ! (
10171032 "<a \
10181033 href=\" https://github.com/rust-lang/rust/issues/{n}\" \
@@ -1026,6 +1041,14 @@ fn render_stability_since_raw_with_extra(
10261041 Some ( ( String :: from ( "const unstable" ) , format ! ( "const: {unstable}" ) ) )
10271042 }
10281043 }
1044+ Some ( ConstStability { level : ConstStabilityLevel :: ImplicitUnstable , .. } ) => {
1045+ // No explicit const-stability annotation was provided. Treat it as const-unstable.
1046+ if stable_version. is_none ( ) {
1047+ None
1048+ } else {
1049+ Some ( ( String :: from ( "const unstable" ) , format ! ( "const: unstable" ) ) )
1050+ }
1051+ }
10291052 _ => None ,
10301053 } ;
10311054
@@ -1062,7 +1085,7 @@ fn since_to_string(since: &StableSince) -> Option<String> {
10621085fn render_stability_since_raw (
10631086 w : & mut Buffer ,
10641087 ver : Option < StableSince > ,
1065- const_stability : Option < ConstStability > ,
1088+ const_stability : Option < & ConstStability > ,
10661089) -> bool {
10671090 render_stability_since_raw_with_extra ( w, ver, const_stability, "" )
10681091}
0 commit comments