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 calling trap, 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