Skip to content

Commit c1786da

Browse files
committed
Generate more accurate MIR in construct_error
1 parent 5efb650 commit c1786da

File tree

1 file changed

+36
-5
lines changed
  • src/librustc_mir_build/build

1 file changed

+36
-5
lines changed

src/librustc_mir_build/build/mod.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -660,14 +660,45 @@ fn construct_const<'a, 'tcx>(
660660
builder.finish()
661661
}
662662

663+
/// Construct MIR for a item that has had errors in type checking.
664+
///
665+
/// This is required because we may still want to run MIR passes on an item
666+
/// with type errors, but normal MIR construction can't handle that in general.
663667
fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'tcx> {
664-
let owner_id = hir.tcx().hir().body_owner(body_id);
665-
let span = hir.tcx().hir().span(owner_id);
666-
let ty = hir.tcx().types.err;
667-
let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, None);
668+
let tcx = hir.tcx();
669+
let owner_id = tcx.hir().body_owner(body_id);
670+
let span = tcx.hir().span(owner_id);
671+
let ty = tcx.types.err;
672+
let num_params = match hir.body_owner_kind {
673+
hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len(),
674+
hir::BodyOwnerKind::Closure => {
675+
// The implicit self parameter adds another local in MIR.
676+
1 + tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len()
677+
}
678+
hir::BodyOwnerKind::Const => 0,
679+
hir::BodyOwnerKind::Static(_) => 0,
680+
};
681+
let mut builder = Builder::new(hir, span, num_params, Safety::Safe, ty, span, None);
668682
let source_info = builder.source_info(span);
683+
// Some MIR passes will expect the number of parameters to match the
684+
// function declaration.
685+
for _ in 0..num_params {
686+
builder.local_decls.push(LocalDecl {
687+
mutability: Mutability::Mut,
688+
ty,
689+
user_ty: UserTypeProjections::none(),
690+
source_info,
691+
internal: false,
692+
local_info: LocalInfo::Other,
693+
is_block_tail: None,
694+
});
695+
}
669696
builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
670-
builder.finish()
697+
let mut body = builder.finish();
698+
if tcx.hir().body(body_id).generator_kind.is_some() {
699+
body.yield_ty = Some(ty);
700+
}
701+
body
671702
}
672703

673704
impl<'a, 'tcx> Builder<'a, 'tcx> {

0 commit comments

Comments
 (0)