@@ -22,7 +22,7 @@ extern crate serde;
22
22
extern crate serde_json;
23
23
use rustc_middle as middle;
24
24
use rustc_middle:: ty:: {
25
- EarlyBinder , FnSig , GenericArgs , List , Ty , TyCtxt , TypeFoldable , TypingEnv ,
25
+ EarlyBinder , FnSig , GenericArgs , GenericArgsRef , List , Ty , TyCtxt , TypeFoldable , TypingEnv ,
26
26
} ;
27
27
use rustc_session:: config:: { OutFileName , OutputType } ;
28
28
use rustc_smir:: rustc_internal:: { self , internal} ;
@@ -34,7 +34,7 @@ use serde::{Serialize, Serializer};
34
34
use stable_mir:: {
35
35
mir:: mono:: { Instance , InstanceKind , MonoItem } ,
36
36
mir:: { alloc:: AllocId , visit:: MirVisitor , Body , LocalDecl , Rvalue , Terminator , TerminatorKind } ,
37
- ty:: { AdtDef , Allocation , ConstDef , ForeignItemKind , IndexedVal , RigidTy , TyKind , VariantIdx } ,
37
+ ty:: { AdtDef , Allocation , ConstDef , ForeignItemKind , IndexedVal , RigidTy , TyKind } ,
38
38
visitor:: { Visitable , Visitor } ,
39
39
CrateDef , CrateItem , ItemKind ,
40
40
} ;
@@ -554,6 +554,32 @@ impl Visitor for TyCollector<'_> {
554
554
inputs_outputs. push ( sig_stable. ret . ty ) ;
555
555
inputs_outputs. super_visit ( self )
556
556
}
557
+ // The visitor won't collect field types for ADTs, therefore doing it explicitly
558
+ TyKind :: RigidTy ( RigidTy :: Adt ( adt_def, args) ) => {
559
+ let tcx = self . tcx ;
560
+ let adt = rustc_internal:: internal ( tcx, adt_def) ;
561
+
562
+ let args: GenericArgsRef = rustc_internal:: internal ( tcx, args) ;
563
+ let fields: Vec < stable_mir:: ty:: Ty > = adt
564
+ . all_fields ( )
565
+ . map ( move |field| field. ty ( tcx, args) )
566
+ . map ( rustc_internal:: stable)
567
+ . collect ( ) ;
568
+
569
+ let mut control = ty. super_visit ( self ) ;
570
+ if matches ! ( control, ControlFlow :: Continue ( _) ) {
571
+ let maybe_layout_shape = ty. layout ( ) . ok ( ) . map ( |layout| layout. shape ( ) ) ;
572
+ self . types . insert ( * ty, ( ty. kind ( ) , maybe_layout_shape) ) ;
573
+ }
574
+
575
+ for f_ty in fields {
576
+ control = self . visit_ty ( & f_ty) ;
577
+ if matches ! ( control, ControlFlow :: Break ( ( ) ) ) {
578
+ break ;
579
+ }
580
+ }
581
+ control
582
+ }
557
583
_ => {
558
584
let control = ty. super_visit ( self ) ;
559
585
match control {
@@ -606,23 +632,21 @@ fn update_link_map<'tcx>(
606
632
) ;
607
633
}
608
634
curr_val. 0 . 0 |= new_val. 0 . 0 ;
609
- if debug_enabled ( ) {
610
- println ! (
611
- "Regenerated link map entry: {:?}:{:?} -> {:?}" ,
612
- & key,
613
- key. 0 . kind( ) . fn_def( ) ,
614
- new_val
615
- ) ;
616
- }
635
+ #[ cfg( feature = "debug_log" ) ]
636
+ println ! (
637
+ "Regenerated link map entry: {:?}:{:?} -> {:?}" ,
638
+ & key,
639
+ key. 0 . kind( ) . fn_def( ) ,
640
+ new_val
641
+ ) ;
617
642
} else {
618
- if debug_enabled ( ) {
619
- println ! (
620
- "Generated link map entry from call: {:?}:{:?} -> {:?}" ,
621
- & key,
622
- key. 0 . kind( ) . fn_def( ) ,
623
- new_val
624
- ) ;
625
- }
643
+ #[ cfg( feature = "debug_log" ) ]
644
+ println ! (
645
+ "Generated link map entry from call: {:?}:{:?} -> {:?}" ,
646
+ & key,
647
+ key. 0 . kind( ) . fn_def( ) ,
648
+ new_val
649
+ ) ;
626
650
link_map. insert ( key. clone ( ) , new_val) ;
627
651
}
628
652
}
@@ -657,12 +681,11 @@ fn collect_alloc(
657
681
match global_alloc {
658
682
GlobalAlloc :: Memory ( ref alloc) => {
659
683
let pointed_kind = get_prov_type ( kind) ;
660
- if debug_enabled ( ) {
661
- println ! (
662
- "DEBUG: called collect_alloc: {:?}:{:?}:{:?}" ,
663
- val, pointed_kind, global_alloc
664
- ) ;
665
- }
684
+ #[ cfg( feature = "debug_log" ) ]
685
+ println ! (
686
+ "DEBUG: called collect_alloc: {:?}:{:?}:{:?}" ,
687
+ val, pointed_kind, global_alloc
688
+ ) ;
666
689
entry. or_insert ( AllocInfo :: Memory ( alloc. clone ( ) ) ) ; // TODO: include pointed_kind.clone().unwrap() ?
667
690
alloc. provenance . ptrs . iter ( ) . for_each ( |( _, prov) | {
668
691
collect_alloc ( val_collector, pointed_kind. clone ( ) , prov. 0 ) ;
@@ -763,13 +786,12 @@ impl MirVisitor for InternedValueCollector<'_, '_> {
763
786
use stable_mir:: ty:: { ConstantKind , TyConstKind } ; // TyConst
764
787
match constant. kind ( ) {
765
788
ConstantKind :: Allocated ( alloc) => {
766
- if debug_enabled ( ) {
767
- println ! (
768
- "visited_mir_const::Allocated({:?}) as {:?}" ,
769
- alloc,
770
- constant. ty( ) . kind( )
771
- ) ;
772
- }
789
+ #[ cfg( feature = "debug_log" ) ]
790
+ println ! (
791
+ "visited_mir_const::Allocated({:?}) as {:?}" ,
792
+ alloc,
793
+ constant. ty( ) . kind( )
794
+ ) ;
773
795
alloc. provenance . ptrs . iter ( ) . for_each ( |( _offset, prov) | {
774
796
collect_alloc ( self , Some ( constant. ty ( ) . kind ( ) ) , prov. 0 )
775
797
} ) ;
@@ -889,9 +911,8 @@ impl MirVisitor for UnevaluatedConstCollector<'_, '_> {
889
911
|| self . pending_items . contains_key ( & item_name)
890
912
|| self . current_item == hash ( & item_name) )
891
913
{
892
- if debug_enabled ( ) {
893
- println ! ( "Adding unevaluated const body for: {}" , item_name) ;
894
- }
914
+ #[ cfg( feature = "debug_log" ) ]
915
+ println ! ( "Adding unevaluated const body for: {}" , item_name) ;
895
916
self . unevaluated_consts
896
917
. insert ( uconst. def , item_name. clone ( ) ) ;
897
918
self . pending_items . insert (
@@ -982,7 +1003,8 @@ pub enum TypeMetadata {
982
1003
EnumType {
983
1004
name : String ,
984
1005
adt_def : AdtDef ,
985
- discriminants : Vec < ( VariantIdx , u128 ) > ,
1006
+ discriminants : Vec < u128 > ,
1007
+ fields : Vec < Vec < stable_mir:: ty:: Ty > > ,
986
1008
} ,
987
1009
StructType {
988
1010
name : String ,
@@ -1000,6 +1022,7 @@ pub enum TypeMetadata {
1000
1022
types : Vec < stable_mir:: ty:: Ty > ,
1001
1023
} ,
1002
1024
FunType ( String ) ,
1025
+ VoidType ,
1003
1026
}
1004
1027
1005
1028
fn mk_type_metadata (
@@ -1014,28 +1037,40 @@ fn mk_type_metadata(
1014
1037
T ( prim_type) if t. is_primitive ( ) => Some ( ( k, PrimitiveType ( prim_type) ) ) ,
1015
1038
// for enums, we need a mapping of variantIdx to discriminant
1016
1039
// this requires access to the internals and is not provided as an interface function at the moment
1017
- T ( Adt ( adt_def, _ ) ) if t. is_enum ( ) => {
1040
+ T ( Adt ( adt_def, args ) ) if t. is_enum ( ) => {
1018
1041
let adt_internal = rustc_internal:: internal ( tcx, adt_def) ;
1019
1042
let discriminants = adt_internal
1020
1043
. discriminants ( tcx)
1021
- . map ( |( v_idx , discr) | ( rustc_internal :: stable ( v_idx ) , discr. val ) )
1044
+ . map ( |( _ , discr) | discr. val )
1022
1045
. collect :: < Vec < _ > > ( ) ;
1046
+ let fields = adt_internal
1047
+ . variants ( )
1048
+ . into_iter ( )
1049
+ . map ( |def| {
1050
+ def. fields
1051
+ . iter ( )
1052
+ . map ( |f| f. ty ( tcx, rustc_internal:: internal ( tcx, & args) ) )
1053
+ . map ( rustc_internal:: stable)
1054
+ . collect :: < Vec < stable_mir:: ty:: Ty > > ( )
1055
+ } )
1056
+ . collect ( ) ;
1023
1057
let name = adt_def. name ( ) ;
1024
1058
Some ( (
1025
1059
k,
1026
1060
EnumType {
1027
1061
name,
1028
1062
adt_def,
1029
1063
discriminants,
1064
+ fields,
1030
1065
} ,
1031
1066
) )
1032
1067
}
1033
1068
// for structs, we record the name for information purposes and the field types
1034
- T ( Adt ( adt_def, _ ) ) if t. is_struct ( ) => {
1069
+ T ( Adt ( adt_def, args ) ) if t. is_struct ( ) => {
1035
1070
let name = adt_def. name ( ) ;
1036
1071
let fields = rustc_internal:: internal ( tcx, adt_def)
1037
1072
. all_fields ( ) // is_struct, so only one variant
1038
- . map ( move |field| tcx . type_of ( field . did ) . instantiate_identity ( ) )
1073
+ . map ( move |f| f . ty ( tcx , rustc_internal :: internal ( tcx , & args ) ) )
1039
1074
. map ( rustc_internal:: stable)
1040
1075
. collect ( ) ;
1041
1076
Some ( (
@@ -1069,9 +1104,27 @@ fn mk_type_metadata(
1069
1104
| T ( Pat ( _, _) )
1070
1105
| T ( Coroutine ( _, _, _) )
1071
1106
| T ( Dynamic ( _, _, _) )
1072
- | T ( CoroutineWitness ( _, _) ) => None ,
1073
- TyKind :: Alias ( _, _) | TyKind :: Param ( _) | TyKind :: Bound ( _, _) => None ,
1074
- _ => None , // redundant because of first 4 cases, but rustc does not understand that
1107
+ | T ( CoroutineWitness ( _, _) ) => {
1108
+ #[ cfg( feature = "debug_log" ) ]
1109
+ println ! (
1110
+ "\n DEBUG: Skipping unsupported ty {}: {:?}" ,
1111
+ k. to_index( ) ,
1112
+ k. kind( )
1113
+ ) ;
1114
+ None
1115
+ }
1116
+ T ( Never ) => Some ( ( k, VoidType ) ) ,
1117
+ TyKind :: Alias ( _, _) | TyKind :: Param ( _) | TyKind :: Bound ( _, _) => {
1118
+ #[ cfg( feature = "debug_log" ) ]
1119
+ println ! ( "\n Skipping undesired ty {}: {:?}" , k. to_index( ) , k. kind( ) ) ;
1120
+ None
1121
+ }
1122
+ _ => {
1123
+ // redundant because of first 4 cases, but rustc does not understand that
1124
+ #[ cfg( feature = "debug_log" ) ]
1125
+ println ! ( "\n DEBUG: Funny other Ty {}: {:?}" , k. to_index( ) , k. kind( ) ) ;
1126
+ None
1127
+ }
1075
1128
}
1076
1129
}
1077
1130
0 commit comments