Skip to content

Commit bc43cdc

Browse files
committed
add check for uninhabited types along side never
1 parent 29e035e commit bc43cdc

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

compiler/rustc_mir_build/src/builder/mod.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
839839
self.infcx.typing_env(self.param_env),
840840
);
841841

842-
if !ty_is_inhabited {
842+
// check if the function's return type is inhabited
843+
let output_is_inhabited =
844+
if matches!(self.tcx.def_kind(self.def_id), DefKind::Fn | DefKind::AssocFn) {
845+
self.tcx
846+
.fn_sig(self.def_id)
847+
.instantiate_identity()
848+
.skip_binder()
849+
.output()
850+
.is_inhabited_from(
851+
self.tcx,
852+
self.parent_module,
853+
self.infcx.typing_env(self.param_env),
854+
)
855+
} else {
856+
true
857+
};
858+
859+
if !ty_is_inhabited && output_is_inhabited {
843860
// Unreachable code warnings are already emitted during type checking.
844861
// However, during type checking, full type information is being
845862
// calculated but not yet available, so the check for diverging
@@ -852,7 +869,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
852869
if !ty.is_never() {
853870
lints.push((target_bb, ty, term.source_info.span));
854871
}
855-
856872
// The presence or absence of a return edge affects control-flow sensitive
857873
// MIR checks and ultimately whether code is accepted or not. We can only
858874
// omit the return edge if a return type is visibly uninhabited to a module
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![deny(unreachable_code)]
2+
//@ run-pass
3+
4+
use std::convert::Infallible;
5+
6+
pub fn foo(f: impl FnOnce() -> Infallible) -> Infallible {
7+
f()
8+
}
9+
10+
fn main() {}

0 commit comments

Comments
 (0)