11use rustc:: hir;
22use rustc:: hir:: def_id:: DefId ;
3- use rustc:: infer;
43use rustc:: mir:: * ;
54use rustc:: ty:: { self , Ty , TyCtxt } ;
65use rustc:: ty:: layout:: VariantIdx ;
@@ -21,6 +20,7 @@ use crate::transform::{
2120} ;
2221use crate :: util:: elaborate_drops:: { self , DropElaborator , DropStyle , DropFlagMode } ;
2322use crate :: util:: patch:: MirPatch ;
23+ use crate :: util:: expand_aggregate;
2424
2525pub fn provide ( providers : & mut Providers < ' _ > ) {
2626 providers. mir_shims = make_shim;
@@ -842,29 +842,26 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
842842 mir
843843}
844844
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) ;
855852
856853 // Normalize the sig.
857- let sig = gcx . fn_sig ( def_id )
854+ let sig = tcx . fn_sig ( ctor_id )
858855 . no_bound_vars ( )
859856 . 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) ;
861858
862859 let ( adt_def, substs) = match sig. output ( ) . sty {
863860 ty:: Adt ( adt_def, substs) => ( adt_def, substs) ,
864861 _ => bug ! ( "unexpected type for ADT ctor {:?}" , sig. output( ) )
865862 } ;
866863
867- debug ! ( "build_ctor: def_id ={:?} sig={:?} fields={:?} " , def_id , sig, fields ) ;
864+ debug ! ( "build_ctor: ctor_id ={:?} sig={:?}" , ctor_id , sig) ;
868865
869866 let local_decls = local_decls_for_sig ( & sig, span) ;
870867
@@ -873,34 +870,45 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
873870 scope : OUTERMOST_SOURCE_SCOPE
874871 } ;
875872
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 )
878875 } else {
879876 VariantIdx :: new ( 0 )
880877 } ;
881878
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+
883902 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,
896904 terminator : Some ( Terminator {
897905 source_info,
898906 kind : TerminatorKind :: Return ,
899907 } ) ,
900908 is_cleanup : false
901909 } ;
902910
903- Body :: new (
911+ let body = Body :: new (
904912 IndexVec :: from_elem_n ( start_block, 1 ) ,
905913 IndexVec :: from_elem_n (
906914 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>,
914922 vec ! [ ] ,
915923 span,
916924 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)
918938}
0 commit comments