@@ -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,46 @@ 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
+ let has_stripped_variants = adt_def. variants ( ) . len ( ) != variants. len ( ) ;
975
+ TypeAliasInnerType :: Enum {
976
+ variants,
977
+ has_stripped_variants,
978
+ is_non_exhaustive : adt_def. is_variant_list_non_exhaustive ( ) ,
979
+ }
980
+ } else {
981
+ let variant = adt_def
982
+ . variants ( )
983
+ . iter ( )
984
+ . next ( )
985
+ . unwrap_or_else ( || bug ! ( "a struct or union should always have one variant def" ) ) ;
986
+
987
+ let fields: Vec < _ > =
988
+ clean_variant_def_with_args ( variant, args, cx) . kind . inner_items ( ) . cloned ( ) . collect ( ) ;
989
+
990
+ let has_stripped_fields = variant. fields . len ( ) != fields. len ( ) ;
991
+ if adt_def. is_struct ( ) {
992
+ TypeAliasInnerType :: Struct { ctor_kind : variant. ctor_kind ( ) , fields, has_stripped_fields }
993
+ } else {
994
+ TypeAliasInnerType :: Union { fields, has_stripped_fields }
995
+ }
996
+ } )
997
+ }
998
+
958
999
fn clean_proc_macro < ' tcx > (
959
1000
item : & hir:: Item < ' tcx > ,
960
1001
name : & mut Symbol ,
@@ -1222,6 +1263,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
1222
1263
Box :: new ( TypeAlias {
1223
1264
type_ : clean_ty ( default, cx) ,
1224
1265
generics,
1266
+ inner_type : None ,
1225
1267
item_type : Some ( item_type) ,
1226
1268
} ) ,
1227
1269
bounds,
@@ -1264,7 +1306,12 @@ pub(crate) fn clean_impl_item<'tcx>(
1264
1306
None ,
1265
1307
) ;
1266
1308
AssocTypeItem (
1267
- Box :: new ( TypeAlias { type_, generics, item_type : Some ( item_type) } ) ,
1309
+ Box :: new ( TypeAlias {
1310
+ type_,
1311
+ generics,
1312
+ inner_type : None ,
1313
+ item_type : Some ( item_type) ,
1314
+ } ) ,
1268
1315
Vec :: new ( ) ,
1269
1316
)
1270
1317
}
@@ -1471,6 +1518,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1471
1518
None ,
1472
1519
) ,
1473
1520
generics,
1521
+ inner_type : None ,
1474
1522
item_type : None ,
1475
1523
} ) ,
1476
1524
bounds,
@@ -1490,6 +1538,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1490
1538
None ,
1491
1539
) ,
1492
1540
generics,
1541
+ inner_type : None ,
1493
1542
item_type : None ,
1494
1543
} ) ,
1495
1544
// Associated types inside trait or inherent impls are not allowed to have
@@ -2350,6 +2399,60 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont
2350
2399
)
2351
2400
}
2352
2401
2402
+ pub ( crate ) fn clean_variant_def_with_args < ' tcx > (
2403
+ variant : & ty:: VariantDef ,
2404
+ args : & GenericArgsRef < ' tcx > ,
2405
+ cx : & mut DocContext < ' tcx > ,
2406
+ ) -> Item {
2407
+ let discriminant = match variant. discr {
2408
+ ty:: VariantDiscr :: Explicit ( def_id) => Some ( Discriminant { expr : None , value : def_id } ) ,
2409
+ ty:: VariantDiscr :: Relative ( _) => None ,
2410
+ } ;
2411
+
2412
+ let kind = match variant. ctor_kind ( ) {
2413
+ Some ( CtorKind :: Const ) => VariantKind :: CLike ,
2414
+ Some ( CtorKind :: Fn ) => VariantKind :: Tuple (
2415
+ variant
2416
+ . fields
2417
+ . iter ( )
2418
+ . filter ( |field| field. vis . is_public ( ) )
2419
+ . map ( |field| {
2420
+ let ty = cx. tcx . type_of ( field. did ) . instantiate ( cx. tcx , args) ;
2421
+ clean_field_with_def_id (
2422
+ field. did ,
2423
+ field. name ,
2424
+ clean_middle_ty ( ty:: Binder :: dummy ( ty) , cx, Some ( field. did ) , None ) ,
2425
+ cx,
2426
+ )
2427
+ } )
2428
+ . collect ( ) ,
2429
+ ) ,
2430
+ None => VariantKind :: Struct ( VariantStruct {
2431
+ fields : variant
2432
+ . fields
2433
+ . iter ( )
2434
+ . filter ( |field| field. vis . is_public ( ) )
2435
+ . map ( |field| {
2436
+ let ty = cx. tcx . type_of ( field. did ) . instantiate ( cx. tcx , args) ;
2437
+ clean_field_with_def_id (
2438
+ field. did ,
2439
+ field. name ,
2440
+ clean_middle_ty ( ty:: Binder :: dummy ( ty) , cx, Some ( field. did ) , None ) ,
2441
+ cx,
2442
+ )
2443
+ } )
2444
+ . collect ( ) ,
2445
+ } ) ,
2446
+ } ;
2447
+
2448
+ Item :: from_def_id_and_parts (
2449
+ variant. def_id ,
2450
+ Some ( variant. name ) ,
2451
+ VariantItem ( Variant { kind, discriminant } ) ,
2452
+ cx,
2453
+ )
2454
+ }
2455
+
2353
2456
fn clean_variant_data < ' tcx > (
2354
2457
variant : & hir:: VariantData < ' tcx > ,
2355
2458
disr_expr : & Option < hir:: AnonConst > ,
@@ -2604,7 +2707,7 @@ fn clean_maybe_renamed_item<'tcx>(
2604
2707
ItemKind :: TyAlias ( hir_ty, generics) => {
2605
2708
* cx. current_type_aliases . entry ( def_id) . or_insert ( 0 ) += 1 ;
2606
2709
let rustdoc_ty = clean_ty ( hir_ty, cx) ;
2607
- let ty = clean_middle_ty (
2710
+ let type_ = clean_middle_ty (
2608
2711
ty:: Binder :: dummy ( hir_ty_to_ty ( cx. tcx , hir_ty) ) ,
2609
2712
cx,
2610
2713
None ,
@@ -2617,10 +2720,15 @@ fn clean_maybe_renamed_item<'tcx>(
2617
2720
cx. current_type_aliases . remove ( & def_id) ;
2618
2721
}
2619
2722
}
2723
+
2724
+ let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( ) ;
2725
+ let inner_type = clean_ty_alias_inner_type ( ty, cx) ;
2726
+
2620
2727
TypeAliasItem ( Box :: new ( TypeAlias {
2621
- type_ : rustdoc_ty,
2622
2728
generics,
2623
- item_type : Some ( ty) ,
2729
+ inner_type,
2730
+ type_ : rustdoc_ty,
2731
+ item_type : Some ( type_) ,
2624
2732
} ) )
2625
2733
}
2626
2734
ItemKind :: Enum ( ref def, generics) => EnumItem ( Enum {
0 commit comments