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