Closed
Description
It looks like default methods in traits will always use invoke
whereas defined methods will hit the optimization to not use invoke
:
// bar.rs
#![crate_type = "rlib"]
pub fn bar() {}
// foo.rs
#![crate_type = "rlib"]
extern crate bar;
pub trait A: Sized {
fn foo1(self) {
bar::bar();
}
fn foo2(self);
}
impl A for i32 {
fn foo2(self) {
bar::bar();
}
}
fn main() {
0i32.foo1();
0i32.foo2();
}
$ rustc bar.rs
$ rustc foo.rs -L . --emit llvm-ir
$ cat foo.ll
will yield this IR, notably:
; foo::A::foo1
; Function Attrs: uwtable
define internal void @_ZN3foo1A4foo117hcfa03453b669bd94E(i32) unnamed_addr #0 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
start:
%personalityslot = alloca { i8*, i32 }
; invoke bar::bar
invoke void @_ZN3bar3bar17h21868f3a4452d05bE()
to label %bb3 unwind label %cleanup
; ...
}
; <i32 as foo::A>::foo2
; Function Attrs: uwtable
define void @"_ZN30_$LT$i32$u20$as$u20$foo..A$GT$4foo217h68eec0bc305998eeE"(i32) unnamed_addr #0 {
start:
; call bar::bar
call void @_ZN3bar3bar17h21868f3a4452d05bE()
br label %bb1
bb1: ; preds = %start
ret void
}
Note that <i32 as A>::foo1
uses an invoke
instruction whereas <i32 as A>::foo2
does not.