1
1
use rustc:: hir;
2
2
use rustc:: hir:: def_id:: DefId ;
3
- use rustc:: infer;
4
3
use rustc:: mir:: * ;
5
4
use rustc:: ty:: { self , Ty , TyCtxt } ;
6
5
use rustc:: ty:: layout:: VariantIdx ;
@@ -21,6 +20,7 @@ use crate::transform::{
21
20
} ;
22
21
use crate :: util:: elaborate_drops:: { self , DropElaborator , DropStyle , DropFlagMode } ;
23
22
use crate :: util:: patch:: MirPatch ;
23
+ use crate :: util:: expand_aggregate;
24
24
25
25
pub fn provide ( providers : & mut Providers < ' _ > ) {
26
26
providers. mir_shims = make_shim;
@@ -842,29 +842,26 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
842
842
mir
843
843
}
844
844
845
- pub fn build_adt_ctor < ' a , ' gcx , ' tcx > ( infcx : & infer:: InferCtxt < ' a , ' gcx , ' tcx > ,
846
- ctor_id : hir:: HirId ,
847
- fields : & [ hir:: StructField ] ,
848
- span : Span )
849
- -> Body < ' tcx >
850
- {
851
- let tcx = infcx. tcx ;
852
- let gcx = tcx. global_tcx ( ) ;
853
- let def_id = tcx. hir ( ) . local_def_id_from_hir_id ( ctor_id) ;
854
- let param_env = gcx. param_env ( def_id) ;
845
+ pub fn build_adt_ctor < ' gcx > ( tcx : TyCtxt < ' _ , ' gcx , ' gcx > , ctor_id : DefId ) -> & ' gcx Body < ' gcx > {
846
+ debug_assert ! ( tcx. is_constructor( ctor_id) ) ;
847
+
848
+ let span = tcx. hir ( ) . span_if_local ( ctor_id)
849
+ . unwrap_or_else ( || bug ! ( "no span for ctor {:?}" , ctor_id) ) ;
850
+
851
+ let param_env = tcx. param_env ( ctor_id) ;
855
852
856
853
// Normalize the sig.
857
- let sig = gcx . fn_sig ( def_id )
854
+ let sig = tcx . fn_sig ( ctor_id )
858
855
. no_bound_vars ( )
859
856
. expect ( "LBR in ADT constructor signature" ) ;
860
- let sig = gcx . normalize_erasing_regions ( param_env, sig) ;
857
+ let sig = tcx . normalize_erasing_regions ( param_env, sig) ;
861
858
862
859
let ( adt_def, substs) = match sig. output ( ) . sty {
863
860
ty:: Adt ( adt_def, substs) => ( adt_def, substs) ,
864
861
_ => bug ! ( "unexpected type for ADT ctor {:?}" , sig. output( ) )
865
862
} ;
866
863
867
- debug ! ( "build_ctor: def_id ={:?} sig={:?} fields={:?} " , def_id , sig, fields ) ;
864
+ debug ! ( "build_ctor: ctor_id ={:?} sig={:?}" , ctor_id , sig) ;
868
865
869
866
let local_decls = local_decls_for_sig ( & sig, span) ;
870
867
@@ -873,34 +870,45 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
873
870
scope : OUTERMOST_SOURCE_SCOPE
874
871
} ;
875
872
876
- let variant_no = if adt_def. is_enum ( ) {
877
- adt_def. variant_index_with_ctor_id ( def_id )
873
+ let variant_index = if adt_def. is_enum ( ) {
874
+ adt_def. variant_index_with_ctor_id ( ctor_id )
878
875
} else {
879
876
VariantIdx :: new ( 0 )
880
877
} ;
881
878
882
- // return = ADT(arg0, arg1, ...); return
879
+ // Generate the following MIR:
880
+ //
881
+ // (return as Variant).field0 = arg0;
882
+ // (return as Variant).field1 = arg1;
883
+ //
884
+ // return;
885
+ debug ! ( "build_ctor: variant_index={:?}" , variant_index) ;
886
+
887
+ let statements = expand_aggregate (
888
+ Place :: RETURN_PLACE ,
889
+ adt_def
890
+ . variants [ variant_index]
891
+ . fields
892
+ . iter ( )
893
+ . enumerate ( )
894
+ . map ( |( idx, field_def) | (
895
+ Operand :: Move ( Place :: Base ( PlaceBase :: Local ( Local :: new ( idx + 1 ) ) ) ) ,
896
+ field_def. ty ( tcx, substs) ,
897
+ ) ) ,
898
+ AggregateKind :: Adt ( adt_def, variant_index, substs, None , None ) ,
899
+ source_info,
900
+ ) . collect ( ) ;
901
+
883
902
let start_block = BasicBlockData {
884
- statements : vec ! [ Statement {
885
- source_info,
886
- kind: StatementKind :: Assign (
887
- Place :: RETURN_PLACE ,
888
- box Rvalue :: Aggregate (
889
- box AggregateKind :: Adt ( adt_def, variant_no, substs, None , None ) ,
890
- ( 1 ..sig. inputs( ) . len( ) +1 ) . map( |i| {
891
- Operand :: Move ( Place :: Base ( PlaceBase :: Local ( Local :: new( i) ) ) )
892
- } ) . collect( )
893
- )
894
- )
895
- } ] ,
903
+ statements,
896
904
terminator : Some ( Terminator {
897
905
source_info,
898
906
kind : TerminatorKind :: Return ,
899
907
} ) ,
900
908
is_cleanup : false
901
909
} ;
902
910
903
- Body :: new (
911
+ let body = Body :: new (
904
912
IndexVec :: from_elem_n ( start_block, 1 ) ,
905
913
IndexVec :: from_elem_n (
906
914
SourceScopeData { span : span, parent_scope : None } , 1
@@ -914,5 +922,17 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
914
922
vec ! [ ] ,
915
923
span,
916
924
vec ! [ ] ,
917
- )
925
+ ) ;
926
+
927
+ crate :: util:: dump_mir (
928
+ tcx,
929
+ None ,
930
+ "mir_map" ,
931
+ & 0 ,
932
+ crate :: transform:: MirSource :: item ( ctor_id) ,
933
+ & body,
934
+ |_, _| Ok ( ( ) ) ,
935
+ ) ;
936
+
937
+ tcx. arena . alloc ( body)
918
938
}
0 commit comments