]> git.proxmox.com Git - rustc.git/blob - tests/codegen/virtual-function-elimination.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / tests / codegen / virtual-function-elimination.rs
1 // compile-flags: -Zvirtual-function-elimination -Clto -O -Csymbol-mangling-version=v0
2 // ignore-32bit
3 // ignore-debug
4
5 // CHECK: @vtable.0 = {{.*}}, !type ![[TYPE0:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]]
6 // CHECK: @vtable.1 = {{.*}}, !type ![[TYPE1:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]]
7 // CHECK: @vtable.2 = {{.*}}, !type ![[TYPE2:[0-9]+]], !vcall_visibility ![[VCALL_VIS2:[0-9]+]]
8
9 #![crate_type = "lib"]
10 #![allow(incomplete_features)]
11 #![feature(unsized_locals)]
12
13 use std::rc::Rc;
14
15 trait T {
16 // CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::used
17 fn used(&self) -> i32 {
18 1
19 }
20 // CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::used_through_sub_trait
21 fn used_through_sub_trait(&self) -> i32 {
22 3
23 }
24 // CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::by_rc
25 fn by_rc(self: Rc<Self>) -> i32 {
26 self.used() + self.used()
27 }
28 // CHECK-LABEL-NOT: {{.*}}::unused
29 fn unused(&self) -> i32 {
30 2
31 }
32 // CHECK-LABEL-NOT: {{.*}}::by_rc_unused
33 fn by_rc_unused(self: Rc<Self>) -> i32 {
34 self.by_rc()
35 }
36 }
37
38 trait U: T {
39 // CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::U>::subtrait_used
40 fn subtrait_used(&self) -> i32 {
41 4
42 }
43 // CHECK-LABEL-NOT: {{.*}}::subtrait_unused
44 fn subtrait_unused(&self) -> i32 {
45 5
46 }
47 }
48
49 pub trait V {
50 // CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::V>::public_function
51 fn public_function(&self) -> i32;
52 }
53
54 #[derive(Copy, Clone)]
55 struct S;
56
57 impl T for S {}
58
59 impl U for S {}
60
61 impl V for S {
62 fn public_function(&self) -> i32 {
63 6
64 }
65 }
66
67 fn taking_t(t: &dyn T) -> i32 {
68 // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"[[MANGLED_TYPE0:[0-9a-zA-Z_]+]]")
69 t.used()
70 }
71
72 fn taking_rc_t(t: Rc<dyn T>) -> i32 {
73 // CHECK: @llvm.type.checked.load({{.*}}, i32 40, metadata !"[[MANGLED_TYPE0:[0-9a-zA-Z_]+]]")
74 t.by_rc()
75 }
76
77 fn taking_u(u: &dyn U) -> i32 {
78 // CHECK: @llvm.type.checked.load({{.*}}, i32 64, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
79 // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
80 // CHECK: @llvm.type.checked.load({{.*}}, i32 32, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
81 u.subtrait_used() + u.used() + u.used_through_sub_trait()
82 }
83
84 pub fn taking_v(v: &dyn V) -> i32 {
85 // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtCs64ITQYi9761_28virtual_function_elimination1V")
86 v.public_function()
87 }
88
89 pub fn main() {
90 let s = S;
91 taking_t(&s);
92 taking_rc_t(Rc::new(s));
93 taking_u(&s);
94 taking_v(&s);
95 }
96
97 // CHECK: ![[TYPE0]] = !{i64 0, !"[[MANGLED_TYPE0]]"}
98 // CHECK: ![[VCALL_VIS0]] = !{i64 2}
99 // CHECK: ![[TYPE1]] = !{i64 0, !"[[MANGLED_TYPE1]]"}
100 // CHECK: ![[TYPE2]] = !{i64 0, !"NtCs64ITQYi9761_28virtual_function_elimination1V"}
101 // CHECK: ![[VCALL_VIS2]] = !{i64 1}