Never return uninhabited values at all by cuviper · Pull Request #59639 · rust-lang/rust (original) (raw)
The
unreachable
is never reached though (heh ;), so it has no effect. You are first callingtrap
, which is a well-defined function that never returns. Everything after it is dead code and hence does not matter.
Yes, but a call
is not a terminator, so you still need something. As I quoted from the reference, this is a normal use case to have unreachable
following a no-return function. If you end a function on a call void @llvm.trap
, as I just tried with one of the examples below, you get an error, and even adding tail
or musttail
is not enough. So unreachable
is sort of a no-op terminator in this case.
$ opt -lint -disable-output issue48227.ll
opt: issue48227.ll:2525:1: error: expected instruction opcode
}
^
Now, we could change this to just unreachable
, without the trap, if that helps #59793.
Which exact example did you use for this? I cannot reproduce.
From #48227:
#![crate_type = "lib"]
pub fn lines<'a>(left: &'a str) { iter(left.lines()); }
fn iter<I, T>(left: I) where I: Clone + Iterator<Item = T> + DoubleEndedIterator, T: PartialEq, { let _left_count = left.clone().count(); }
$ rustc +nightly-2019-04-05 --emit=llvm-ir issue48227.rs && grep -C3 trap issue48227.ll
; Function Attrs: noreturn nonlazybind uwtable
define void @"_ZN50_$LT$T$u20$as$u20$core..convert..From$LT$T$GT$$GT$4from17h8496458b8d57254eE"() unnamed_addr #3 {
start:
call void @llvm.trap()
unreachable
}
--
declare zeroext i1 @"_ZN42_$LT$$u21$$u20$as$u20$core..fmt..Debug$GT$3fmt17h48bee2ab31956489E"({ [0 x i8] }* noalias nonnull readonly align 1, %"core::fmt::Formatter"* align 8 dereferenceable(96)) unnamed_addr #1
; Function Attrs: cold noreturn nounwind
declare void @llvm.trap() #7
; Function Attrs: nounwind nonlazybind uwtable
declare i32 @memcmp(i8*, i8*, i64) unnamed_addr #5
Optimization removes it:
$ rustc +nightly-2019-04-05 --emit=llvm-ir issue48227.rs -O && grep -C3 trap issue48227.ll
From #48229:
fn main() { (1 .. 9).filter(|_| true).sum::(); }
$ rustc +nightly-2019-04-05 --emit=llvm-ir issue48229.rs && grep -C3 trap issue48229.ll
; Function Attrs: noreturn nonlazybind uwtable
define internal void @"_ZN50_$LT$T$u20$as$u20$core..convert..From$LT$T$GT$$GT$4from17h0f0e4c14c5a910afE"() unnamed_addr #3 {
start:
call void @llvm.trap()
unreachable
}
--
declare void @_ZN4core9panicking9panic_fmt17h48d5842cb1c97579E(%"core::fmt::Arguments"* noalias nocapture dereferenceable(48), { [0 x i64], { [0 x i8]*, i64 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias readonly align 8 dereferenceable(24)) unnamed_addr #2
; Function Attrs: cold noreturn nounwind
declare void @llvm.trap() #8
; Function Attrs: nonlazybind
define i32 @main(i32, i8**) unnamed_addr #9 {
Optimization removes it:
$ rustc +nightly-2019-04-05 --emit=llvm-ir issue48229.rs -O && grep -C3 trap issue48229.ll