1
Fork 0

Check if call return type is visibly uninhabited when building MIR

This commit is contained in:
Tomasz Miąsko 2022-01-25 00:00:00 +00:00
parent 4b133a7e27
commit 6f8a1ee45e
19 changed files with 167 additions and 98 deletions

View file

@ -255,10 +255,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
func: fun,
args,
cleanup: None,
// FIXME(varkor): replace this with an uninhabitedness-based check.
// This requires getting access to the current module to call
// `tcx.is_ty_uninhabited_from`, which is currently tricky to do.
destination: if expr.ty.is_never() {
// The presence or absence of a return edge affects control-flow sensitive
// MIR checks and ultimately whether code is accepted or not. We can only
// omit the return edge if a return type is visibly uninhabited to a module
// that makes the call.
destination: if this.tcx.is_ty_uninhabited_from(
this.parent_module,
expr.ty,
this.param_env,
) {
None
} else {
Some((destination, success))

View file

@ -350,6 +350,7 @@ struct Builder<'a, 'tcx> {
def_id: DefId,
hir_id: hir::HirId,
parent_module: DefId,
check_overflow: bool,
fn_span: Span,
arg_count: usize,
@ -807,15 +808,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
let lint_level = LintLevel::Explicit(hir_id);
let param_env = tcx.param_env(def.did);
let mut builder = Builder {
thir,
tcx,
infcx,
typeck_results: tcx.typeck_opt_const_arg(def),
region_scope_tree: tcx.region_scope_tree(def.did),
param_env: tcx.param_env(def.did),
param_env,
def_id: def.did.to_def_id(),
hir_id,
parent_module: tcx.parent_module(hir_id).to_def_id(),
check_overflow,
cfg: CFG { basic_blocks: IndexVec::new() },
fn_span: span,