@@ -620,29 +620,63 @@ fn construct_const<'a, 'tcx>(
620620///
621621/// This is required because we may still want to run MIR passes on an item
622622/// with type errors, but normal MIR construction can't handle that in general.
623- fn construct_error ( tcx : TyCtxt < ' _ > , def : LocalDefId , err : ErrorGuaranteed ) -> Body < ' _ > {
624- let span = tcx. def_span ( def) ;
625- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def) ;
626- let coroutine_kind = tcx. coroutine_kind ( def) ;
627- let body_owner_kind = tcx. hir ( ) . body_owner_kind ( def) ;
628-
629- let ty = Ty :: new_error ( tcx, err) ;
630- let num_params = match body_owner_kind {
631- hir:: BodyOwnerKind :: Fn => tcx. fn_sig ( def) . skip_binder ( ) . inputs ( ) . skip_binder ( ) . len ( ) ,
632- hir:: BodyOwnerKind :: Closure => {
633- let ty = tcx. type_of ( def) . instantiate_identity ( ) ;
634- match ty. kind ( ) {
635- ty:: Closure ( _, args) => 1 + args. as_closure ( ) . sig ( ) . inputs ( ) . skip_binder ( ) . len ( ) ,
636- ty:: Coroutine ( ..) => 2 ,
637- _ => bug ! ( "expected closure or coroutine, found {ty:?}" ) ,
638- }
623+ fn construct_error ( tcx : TyCtxt < ' _ > , def_id : LocalDefId , guar : ErrorGuaranteed ) -> Body < ' _ > {
624+ let span = tcx. def_span ( def_id) ;
625+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
626+ let coroutine_kind = tcx. coroutine_kind ( def_id) ;
627+
628+ let ( inputs, output, yield_ty) = match tcx. def_kind ( def_id) {
629+ DefKind :: Const
630+ | DefKind :: AssocConst
631+ | DefKind :: AnonConst
632+ | DefKind :: InlineConst
633+ | DefKind :: Static ( _) => ( vec ! [ ] , tcx. type_of ( def_id) . instantiate_identity ( ) , None ) ,
634+ DefKind :: Ctor ( ..) | DefKind :: Fn | DefKind :: AssocFn => {
635+ let sig = tcx. liberate_late_bound_regions (
636+ def_id. to_def_id ( ) ,
637+ tcx. fn_sig ( def_id) . instantiate_identity ( ) ,
638+ ) ;
639+ ( sig. inputs ( ) . to_vec ( ) , sig. output ( ) , None )
640+ }
641+ DefKind :: Closure => {
642+ let closure_ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
643+ let ty:: Closure ( _, args) = closure_ty. kind ( ) else { bug ! ( ) } ;
644+ let args = args. as_closure ( ) ;
645+ let sig = tcx. liberate_late_bound_regions ( def_id. to_def_id ( ) , args. sig ( ) ) ;
646+ let self_ty = match args. kind ( ) {
647+ ty:: ClosureKind :: Fn => Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_erased , closure_ty) ,
648+ ty:: ClosureKind :: FnMut => Ty :: new_mut_ref ( tcx, tcx. lifetimes . re_erased , closure_ty) ,
649+ ty:: ClosureKind :: FnOnce => closure_ty,
650+ } ;
651+ ( [ self_ty] . into_iter ( ) . chain ( sig. inputs ( ) . to_vec ( ) ) . collect ( ) , sig. output ( ) , None )
652+ }
653+ DefKind :: Coroutine => {
654+ let coroutine_ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
655+ let ty:: Coroutine ( _, args, _) = coroutine_ty. kind ( ) else { bug ! ( ) } ;
656+ let args = args. as_coroutine ( ) ;
657+ let yield_ty = args. yield_ty ( ) ;
658+ let return_ty = args. return_ty ( ) ;
659+ let self_ty = Ty :: new_adt (
660+ tcx,
661+ tcx. adt_def ( tcx. lang_items ( ) . pin_type ( ) . unwrap ( ) ) ,
662+ tcx. mk_args ( & [ Ty :: new_mut_ref ( tcx, tcx. lifetimes . re_erased , coroutine_ty) . into ( ) ] ) ,
663+ ) ;
664+ let coroutine_state = Ty :: new_adt (
665+ tcx,
666+ tcx. adt_def ( tcx. lang_items ( ) . coroutine_state ( ) . unwrap ( ) ) ,
667+ tcx. mk_args ( & [ yield_ty. into ( ) , return_ty. into ( ) ] ) ,
668+ ) ;
669+ ( vec ! [ self_ty, args. resume_ty( ) ] , coroutine_state, Some ( yield_ty) )
639670 }
640- hir:: BodyOwnerKind :: Const { .. } => 0 ,
641- hir:: BodyOwnerKind :: Static ( _) => 0 ,
671+ dk => bug ! ( "{:?} is not a body: {:?}" , def_id, dk) ,
642672 } ;
673+
674+ let source_info = SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ;
675+ let local_decls = IndexVec :: from_iter (
676+ [ output] . iter ( ) . chain ( & inputs) . map ( |ty| LocalDecl :: with_source_info ( * ty, source_info) ) ,
677+ ) ;
643678 let mut cfg = CFG { basic_blocks : IndexVec :: new ( ) } ;
644679 let mut source_scopes = IndexVec :: new ( ) ;
645- let mut local_decls = IndexVec :: from_elem_n ( LocalDecl :: new ( ty, span) , 1 ) ;
646680
647681 cfg. start_new_block ( ) ;
648682 source_scopes. push ( SourceScopeData {
@@ -655,28 +689,24 @@ fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Bo
655689 safety : Safety :: Safe ,
656690 } ) ,
657691 } ) ;
658- let source_info = SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ;
659692
660- // Some MIR passes will expect the number of parameters to match the
661- // function declaration.
662- for _ in 0 ..num_params {
663- local_decls. push ( LocalDecl :: with_source_info ( ty, source_info) ) ;
664- }
665693 cfg. terminate ( START_BLOCK , source_info, TerminatorKind :: Unreachable ) ;
666694
667695 let mut body = Body :: new (
668- MirSource :: item ( def . to_def_id ( ) ) ,
696+ MirSource :: item ( def_id . to_def_id ( ) ) ,
669697 cfg. basic_blocks ,
670698 source_scopes,
671699 local_decls,
672700 IndexVec :: new ( ) ,
673- num_params ,
701+ inputs . len ( ) ,
674702 vec ! [ ] ,
675703 span,
676704 coroutine_kind,
677- Some ( err ) ,
705+ Some ( guar ) ,
678706 ) ;
679- body. coroutine . as_mut ( ) . map ( |gen| gen. yield_ty = Some ( ty) ) ;
707+
708+ body. coroutine . as_mut ( ) . map ( |gen| gen. yield_ty = yield_ty) ;
709+
680710 body
681711}
682712
0 commit comments