11
11
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
12
12
13
13
#![ feature( rustc_private) ]
14
+ #![ feature( assert_matches) ]
14
15
15
16
extern crate rustc_hir;
16
17
#[ macro_use]
@@ -23,8 +24,8 @@ use rustc_smir::rustc_internal;
23
24
use stable_mir:: mir:: mono:: { Instance , InstanceKind } ;
24
25
use stable_mir:: mir:: visit:: { Location , MirVisitor } ;
25
26
use stable_mir:: mir:: { LocalDecl , Terminator , TerminatorKind } ;
26
- use stable_mir:: ty:: { RigidTy , TyKind } ;
27
- use std:: collections :: HashSet ;
27
+ use stable_mir:: ty:: { FnDef , GenericArgs , RigidTy , TyKind } ;
28
+ use std:: assert_matches :: assert_matches ;
28
29
use std:: convert:: TryFrom ;
29
30
use std:: io:: Write ;
30
31
use std:: ops:: ControlFlow ;
@@ -39,9 +40,10 @@ fn test_intrinsics() -> ControlFlow<()> {
39
40
visitor. visit_body ( & main_body) ;
40
41
41
42
let calls = visitor. calls ;
42
- assert_eq ! ( calls. len( ) , 2 , "Expected 2 calls, but found: {calls:?}" ) ;
43
- for intrinsic in & calls {
44
- check_intrinsic ( intrinsic)
43
+ assert_eq ! ( calls. len( ) , 3 , "Expected 3 calls, but found: {calls:?}" ) ;
44
+ for ( fn_def, args) in calls. into_iter ( ) {
45
+ check_instance ( & Instance :: resolve ( fn_def, & args) . unwrap ( ) ) ;
46
+ check_def ( fn_def) ;
45
47
}
46
48
47
49
ControlFlow :: Continue ( ( ) )
@@ -53,22 +55,39 @@ fn test_intrinsics() -> ControlFlow<()> {
53
55
///
54
56
/// If by any chance this test breaks because you changed how an intrinsic is implemented, please
55
57
/// update the test to invoke a different intrinsic.
56
- fn check_intrinsic ( intrinsic : & Instance ) {
57
- assert_eq ! ( intrinsic . kind, InstanceKind :: Intrinsic ) ;
58
- let name = intrinsic . intrinsic_name ( ) . unwrap ( ) ;
59
- if intrinsic . has_body ( ) {
60
- let Some ( body) = intrinsic . body ( ) else { unreachable ! ( "Expected a body" ) } ;
58
+ fn check_instance ( instance : & Instance ) {
59
+ assert_eq ! ( instance . kind, InstanceKind :: Intrinsic ) ;
60
+ let name = instance . intrinsic_name ( ) . unwrap ( ) ;
61
+ if instance . has_body ( ) {
62
+ let Some ( body) = instance . body ( ) else { unreachable ! ( "Expected a body" ) } ;
61
63
assert ! ( !body. blocks. is_empty( ) ) ;
62
- assert_eq ! ( & name, "likely" ) ;
64
+ assert_matches ! ( name. as_str ( ) , "likely" | "vtable_size ") ;
63
65
} else {
64
- assert ! ( intrinsic . body( ) . is_none( ) ) ;
66
+ assert ! ( instance . body( ) . is_none( ) ) ;
65
67
assert_eq ! ( & name, "size_of_val" ) ;
66
68
}
67
69
}
68
70
71
+ fn check_def ( fn_def : FnDef ) {
72
+ assert ! ( fn_def. is_intrinsic( ) ) ;
73
+ let intrinsic = fn_def. as_intrinsic ( ) . unwrap ( ) ;
74
+ assert_eq ! ( fn_def, intrinsic. into( ) ) ;
75
+
76
+ let name = intrinsic. fn_name ( ) ;
77
+ match name. as_str ( ) {
78
+ "likely" | "size_of_val" => {
79
+ assert ! ( !intrinsic. must_be_overridden( ) ) ;
80
+ }
81
+ "vtable_size" => {
82
+ assert ! ( intrinsic. must_be_overridden( ) ) ;
83
+ }
84
+ _ => unreachable ! ( "Unexpected intrinsic: {}" , name) ,
85
+ }
86
+ }
87
+
69
88
struct CallsVisitor < ' a > {
70
89
locals : & ' a [ LocalDecl ] ,
71
- calls : HashSet < Instance > ,
90
+ calls : Vec < ( FnDef , GenericArgs ) > ,
72
91
}
73
92
74
93
impl < ' a > MirVisitor for CallsVisitor < ' a > {
@@ -77,10 +96,10 @@ impl<'a> MirVisitor for CallsVisitor<'a> {
77
96
TerminatorKind :: Call { func, .. } => {
78
97
let TyKind :: RigidTy ( RigidTy :: FnDef ( def, args) ) =
79
98
func. ty ( self . locals ) . unwrap ( ) . kind ( )
80
- else {
81
- return ;
82
- } ;
83
- self . calls . insert ( Instance :: resolve ( def, & args) . unwrap ( ) ) ;
99
+ else {
100
+ return ;
101
+ } ;
102
+ self . calls . push ( ( def, args. clone ( ) ) ) ;
84
103
}
85
104
_ => { }
86
105
}
@@ -106,6 +125,7 @@ fn generate_input(path: &str) -> std::io::Result<()> {
106
125
#![feature(core_intrinsics)]
107
126
use std::intrinsics::*;
108
127
pub fn use_intrinsics(init: bool) -> bool {{
128
+ let vtable_sz = unsafe {{ vtable_size(0 as *const ()) }};
109
129
let sz = unsafe {{ size_of_val("hi") }};
110
130
likely(init && sz == 2)
111
131
}}
0 commit comments