@@ -24,6 +24,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
24
24
use rustc_middle:: metadata:: Reexport ;
25
25
use rustc_middle:: middle:: resolve_bound_vars as rbv;
26
26
use rustc_middle:: ty:: fold:: TypeFolder ;
27
+ use rustc_middle:: ty:: GenericArgsRef ;
27
28
use rustc_middle:: ty:: TypeVisitableExt ;
28
29
use rustc_middle:: ty:: { self , AdtKind , EarlyBinder , Ty , TyCtxt } ;
29
30
use rustc_middle:: { bug, span_bug} ;
@@ -955,6 +956,43 @@ fn clean_ty_generics<'tcx>(
955
956
}
956
957
}
957
958
959
+ fn clean_ty_alias_inner_type < ' tcx > (
960
+ ty : Ty < ' tcx > ,
961
+ cx : & mut DocContext < ' tcx > ,
962
+ ) -> Option < TypeAliasInnerType > {
963
+ let ty:: Adt ( adt_def, args) = ty. kind ( ) else {
964
+ return None ;
965
+ } ;
966
+
967
+ Some ( if adt_def. is_enum ( ) {
968
+ let variants: rustc_index:: IndexVec < _ , _ > = adt_def
969
+ . variants ( )
970
+ . iter ( )
971
+ . map ( |variant| clean_variant_def_with_args ( variant, args, cx) )
972
+ . collect ( ) ;
973
+
974
+ TypeAliasInnerType :: Enum {
975
+ variants,
976
+ is_non_exhaustive : adt_def. is_variant_list_non_exhaustive ( ) ,
977
+ }
978
+ } else {
979
+ let variant = adt_def
980
+ . variants ( )
981
+ . iter ( )
982
+ . next ( )
983
+ . unwrap_or_else ( || bug ! ( "a struct or union should always have one variant def" ) ) ;
984
+
985
+ let fields: Vec < _ > =
986
+ clean_variant_def_with_args ( variant, args, cx) . kind . inner_items ( ) . cloned ( ) . collect ( ) ;
987
+
988
+ if adt_def. is_struct ( ) {
989
+ TypeAliasInnerType :: Struct { ctor_kind : variant. ctor_kind ( ) , fields }
990
+ } else {
991
+ TypeAliasInnerType :: Union { fields }
992
+ }
993
+ } )
994
+ }
995
+
958
996
fn clean_proc_macro < ' tcx > (
959
997
item : & hir:: Item < ' tcx > ,
960
998
name : & mut Symbol ,
@@ -1222,6 +1260,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
1222
1260
Box :: new ( TypeAlias {
1223
1261
type_ : clean_ty ( default, cx) ,
1224
1262
generics,
1263
+ inner_type : None ,
1225
1264
item_type : Some ( item_type) ,
1226
1265
} ) ,
1227
1266
bounds,
@@ -1264,7 +1303,12 @@ pub(crate) fn clean_impl_item<'tcx>(
1264
1303
None ,
1265
1304
) ;
1266
1305
AssocTypeItem (
1267
- Box :: new ( TypeAlias { type_, generics, item_type : Some ( item_type) } ) ,
1306
+ Box :: new ( TypeAlias {
1307
+ type_,
1308
+ generics,
1309
+ inner_type : None ,
1310
+ item_type : Some ( item_type) ,
1311
+ } ) ,
1268
1312
Vec :: new ( ) ,
1269
1313
)
1270
1314
}
@@ -1471,6 +1515,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1471
1515
None ,
1472
1516
) ,
1473
1517
generics,
1518
+ inner_type : None ,
1474
1519
item_type : None ,
1475
1520
} ) ,
1476
1521
bounds,
@@ -1490,6 +1535,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1490
1535
None ,
1491
1536
) ,
1492
1537
generics,
1538
+ inner_type : None ,
1493
1539
item_type : None ,
1494
1540
} ) ,
1495
1541
// Associated types inside trait or inherent impls are not allowed to have
@@ -2363,6 +2409,83 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont
2363
2409
)
2364
2410
}
2365
2411
2412
+ pub ( crate ) fn clean_variant_def_with_args < ' tcx > (
2413
+ variant : & ty:: VariantDef ,
2414
+ args : & GenericArgsRef < ' tcx > ,
2415
+ cx : & mut DocContext < ' tcx > ,
2416
+ ) -> Item {
2417
+ let discriminant = match variant. discr {
2418
+ ty:: VariantDiscr :: Explicit ( def_id) => Some ( Discriminant { expr : None , value : def_id } ) ,
2419
+ ty:: VariantDiscr :: Relative ( _) => None ,
2420
+ } ;
2421
+
2422
+ use rustc_middle:: traits:: ObligationCause ;
2423
+ use rustc_trait_selection:: infer:: TyCtxtInferExt ;
2424
+ use rustc_trait_selection:: traits:: query:: normalize:: QueryNormalizeExt ;
2425
+
2426
+ let infcx = cx. tcx . infer_ctxt ( ) . build ( ) ;
2427
+ let kind = match variant. ctor_kind ( ) {
2428
+ Some ( CtorKind :: Const ) => VariantKind :: CLike ,
2429
+ Some ( CtorKind :: Fn ) => VariantKind :: Tuple (
2430
+ variant
2431
+ . fields
2432
+ . iter ( )
2433
+ . map ( |field| {
2434
+ let ty = cx. tcx . type_of ( field. did ) . instantiate ( cx. tcx , args) ;
2435
+
2436
+ // normalize the type to only show concrete types
2437
+ // note: we do not use try_normalize_erasing_regions since we
2438
+ // do care about showing the regions
2439
+ let ty = infcx
2440
+ . at ( & ObligationCause :: dummy ( ) , cx. param_env )
2441
+ . query_normalize ( ty)
2442
+ . map ( |normalized| normalized. value )
2443
+ . unwrap_or ( ty) ;
2444
+
2445
+ clean_field_with_def_id (
2446
+ field. did ,
2447
+ field. name ,
2448
+ clean_middle_ty ( ty:: Binder :: dummy ( ty) , cx, Some ( field. did ) , None ) ,
2449
+ cx,
2450
+ )
2451
+ } )
2452
+ . collect ( ) ,
2453
+ ) ,
2454
+ None => VariantKind :: Struct ( VariantStruct {
2455
+ fields : variant
2456
+ . fields
2457
+ . iter ( )
2458
+ . map ( |field| {
2459
+ let ty = cx. tcx . type_of ( field. did ) . instantiate ( cx. tcx , args) ;
2460
+
2461
+ // normalize the type to only show concrete types
2462
+ // note: we do not use try_normalize_erasing_regions since we
2463
+ // do care about showing the regions
2464
+ let ty = infcx
2465
+ . at ( & ObligationCause :: dummy ( ) , cx. param_env )
2466
+ . query_normalize ( ty)
2467
+ . map ( |normalized| normalized. value )
2468
+ . unwrap_or ( ty) ;
2469
+
2470
+ clean_field_with_def_id (
2471
+ field. did ,
2472
+ field. name ,
2473
+ clean_middle_ty ( ty:: Binder :: dummy ( ty) , cx, Some ( field. did ) , None ) ,
2474
+ cx,
2475
+ )
2476
+ } )
2477
+ . collect ( ) ,
2478
+ } ) ,
2479
+ } ;
2480
+
2481
+ Item :: from_def_id_and_parts (
2482
+ variant. def_id ,
2483
+ Some ( variant. name ) ,
2484
+ VariantItem ( Variant { kind, discriminant } ) ,
2485
+ cx,
2486
+ )
2487
+ }
2488
+
2366
2489
fn clean_variant_data < ' tcx > (
2367
2490
variant : & hir:: VariantData < ' tcx > ,
2368
2491
disr_expr : & Option < hir:: AnonConst > ,
@@ -2617,7 +2740,7 @@ fn clean_maybe_renamed_item<'tcx>(
2617
2740
ItemKind :: TyAlias ( hir_ty, generics) => {
2618
2741
* cx. current_type_aliases . entry ( def_id) . or_insert ( 0 ) += 1 ;
2619
2742
let rustdoc_ty = clean_ty ( hir_ty, cx) ;
2620
- let ty = clean_middle_ty (
2743
+ let type_ = clean_middle_ty (
2621
2744
ty:: Binder :: dummy ( hir_ty_to_ty ( cx. tcx , hir_ty) ) ,
2622
2745
cx,
2623
2746
None ,
@@ -2630,10 +2753,15 @@ fn clean_maybe_renamed_item<'tcx>(
2630
2753
cx. current_type_aliases . remove ( & def_id) ;
2631
2754
}
2632
2755
}
2756
+
2757
+ let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
2758
+ let inner_type = clean_ty_alias_inner_type ( ty, cx) ;
2759
+
2633
2760
TypeAliasItem ( Box :: new ( TypeAlias {
2634
- type_ : rustdoc_ty,
2635
2761
generics,
2636
- item_type : Some ( ty) ,
2762
+ inner_type,
2763
+ type_ : rustdoc_ty,
2764
+ item_type : Some ( type_) ,
2637
2765
} ) )
2638
2766
}
2639
2767
ItemKind :: Enum ( ref def, generics) => EnumItem ( Enum {
0 commit comments