@@ -670,14 +670,51 @@ fn construct_const<'a, 'tcx>(
670670 builder. finish ( )
671671}
672672
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.
673677fn 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 ) ;
678698 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+ }
679712 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
681718}
682719
683720impl < ' a , ' tcx > Builder < ' a , ' tcx > {
0 commit comments