Skip to content

Commit 378b5b4

Browse files
committed
Generate more accurate MIR in construct_error
1 parent 9664122 commit 378b5b4

File tree

1 file changed

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

1 file changed

+42
-5
lines changed

src/librustc_mir_build/build/mod.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
673677
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);
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

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

0 commit comments

Comments
 (0)