@@ -620,29 +620,63 @@ fn construct_const<'a, 'tcx>(
620
620
///
621
621
/// This is required because we may still want to run MIR passes on an item
622
622
/// 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) )
639
670
}
640
- hir:: BodyOwnerKind :: Const { .. } => 0 ,
641
- hir:: BodyOwnerKind :: Static ( _) => 0 ,
671
+ dk => bug ! ( "{:?} is not a body: {:?}" , def_id, dk) ,
642
672
} ;
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
+ ) ;
643
678
let mut cfg = CFG { basic_blocks : IndexVec :: new ( ) } ;
644
679
let mut source_scopes = IndexVec :: new ( ) ;
645
- let mut local_decls = IndexVec :: from_elem_n ( LocalDecl :: new ( ty, span) , 1 ) ;
646
680
647
681
cfg. start_new_block ( ) ;
648
682
source_scopes. push ( SourceScopeData {
@@ -655,28 +689,24 @@ fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Bo
655
689
safety : Safety :: Safe ,
656
690
} ) ,
657
691
} ) ;
658
- let source_info = SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ;
659
692
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
- }
665
693
cfg. terminate ( START_BLOCK , source_info, TerminatorKind :: Unreachable ) ;
666
694
667
695
let mut body = Body :: new (
668
- MirSource :: item ( def . to_def_id ( ) ) ,
696
+ MirSource :: item ( def_id . to_def_id ( ) ) ,
669
697
cfg. basic_blocks ,
670
698
source_scopes,
671
699
local_decls,
672
700
IndexVec :: new ( ) ,
673
- num_params ,
701
+ inputs . len ( ) ,
674
702
vec ! [ ] ,
675
703
span,
676
704
coroutine_kind,
677
- Some ( err ) ,
705
+ Some ( guar ) ,
678
706
) ;
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
+
680
710
body
681
711
}
682
712
0 commit comments