@@ -670,14 +670,51 @@ fn construct_const<'a, 'tcx>(
670
670
builder. finish ( )
671
671
}
672
672
673
+ /// Construct MIR for a item that has had errors in type checking.
674
+ ///
675
+ /// This is required because we may still want to run MIR passes on an item
676
+ /// with type errors, but normal MIR construction can't handle that in general.
673
677
fn construct_error < ' a , ' tcx > ( hir : Cx < ' a , ' tcx > , body_id : hir:: BodyId ) -> Body < ' tcx > {
674
- let owner_id = hir. tcx ( ) . hir ( ) . body_owner ( body_id) ;
675
- let span = hir. tcx ( ) . hir ( ) . span ( owner_id) ;
676
- let ty = hir. tcx ( ) . types . err ;
677
- let mut builder = Builder :: new ( hir, span, 0 , Safety :: Safe , ty, span, None ) ;
678
+ let tcx = hir. tcx ( ) ;
679
+ let owner_id = tcx. hir ( ) . body_owner ( body_id) ;
680
+ let span = tcx. hir ( ) . span ( owner_id) ;
681
+ let ty = tcx. types . err ;
682
+ let num_params = match hir. body_owner_kind {
683
+ hir:: BodyOwnerKind :: Fn => tcx. hir ( ) . fn_decl_by_hir_id ( owner_id) . unwrap ( ) . inputs . len ( ) ,
684
+ hir:: BodyOwnerKind :: Closure => {
685
+ if tcx. hir ( ) . body ( body_id) . generator_kind ( ) . is_some ( ) {
686
+ // Generators have an implicit `self` parameter *and* a possibly
687
+ // implicit resume parameter.
688
+ 2
689
+ } else {
690
+ // The implicit self parameter adds another local in MIR.
691
+ 1 + tcx. hir ( ) . fn_decl_by_hir_id ( owner_id) . unwrap ( ) . inputs . len ( )
692
+ }
693
+ }
694
+ hir:: BodyOwnerKind :: Const => 0 ,
695
+ hir:: BodyOwnerKind :: Static ( _) => 0 ,
696
+ } ;
697
+ let mut builder = Builder :: new ( hir, span, num_params, Safety :: Safe , ty, span, None ) ;
678
698
let source_info = builder. source_info ( span) ;
699
+ // Some MIR passes will expect the number of parameters to match the
700
+ // function declaration.
701
+ for _ in 0 ..num_params {
702
+ builder. local_decls . push ( LocalDecl {
703
+ mutability : Mutability :: Mut ,
704
+ ty,
705
+ user_ty : UserTypeProjections :: none ( ) ,
706
+ source_info,
707
+ internal : false ,
708
+ local_info : LocalInfo :: Other ,
709
+ is_block_tail : None ,
710
+ } ) ;
711
+ }
679
712
builder. cfg . terminate ( START_BLOCK , source_info, TerminatorKind :: Unreachable ) ;
680
- builder. finish ( )
713
+ let mut body = builder. finish ( ) ;
714
+ if tcx. hir ( ) . body ( body_id) . generator_kind . is_some ( ) {
715
+ body. yield_ty = Some ( ty) ;
716
+ }
717
+ body
681
718
}
682
719
683
720
impl < ' a , ' tcx > Builder < ' a , ' tcx > {
0 commit comments