1111//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
1212
1313#![ feature( rustc_private) ]
14+ #![ feature( assert_matches) ]
1415
1516extern crate rustc_hir;
1617#[ macro_use]
@@ -23,8 +24,8 @@ use rustc_smir::rustc_internal;
2324use stable_mir:: mir:: mono:: { Instance , InstanceKind } ;
2425use stable_mir:: mir:: visit:: { Location , MirVisitor } ;
2526use 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 ;
2829use std:: convert:: TryFrom ;
2930use std:: io:: Write ;
3031use std:: ops:: ControlFlow ;
@@ -39,9 +40,10 @@ fn test_intrinsics() -> ControlFlow<()> {
3940 visitor. visit_body ( & main_body) ;
4041
4142 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) ;
4547 }
4648
4749 ControlFlow :: Continue ( ( ) )
@@ -53,22 +55,39 @@ fn test_intrinsics() -> ControlFlow<()> {
5355///
5456/// If by any chance this test breaks because you changed how an intrinsic is implemented, please
5557/// 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" ) } ;
6163 assert ! ( !body. blocks. is_empty( ) ) ;
62- assert_eq ! ( & name, "likely" ) ;
64+ assert_matches ! ( name. as_str ( ) , "likely" | "vtable_size ") ;
6365 } else {
64- assert ! ( intrinsic . body( ) . is_none( ) ) ;
66+ assert ! ( instance . body( ) . is_none( ) ) ;
6567 assert_eq ! ( & name, "size_of_val" ) ;
6668 }
6769}
6870
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+
6988struct CallsVisitor < ' a > {
7089 locals : & ' a [ LocalDecl ] ,
71- calls : HashSet < Instance > ,
90+ calls : Vec < ( FnDef , GenericArgs ) > ,
7291}
7392
7493impl < ' a > MirVisitor for CallsVisitor < ' a > {
@@ -77,10 +96,10 @@ impl<'a> MirVisitor for CallsVisitor<'a> {
7796 TerminatorKind :: Call { func, .. } => {
7897 let TyKind :: RigidTy ( RigidTy :: FnDef ( def, args) ) =
7998 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 ( ) ) ) ;
84103 }
85104 _ => { }
86105 }
@@ -106,6 +125,7 @@ fn generate_input(path: &str) -> std::io::Result<()> {
106125 #![feature(core_intrinsics)]
107126 use std::intrinsics::*;
108127 pub fn use_intrinsics(init: bool) -> bool {{
128+ let vtable_sz = unsafe {{ vtable_size(0 as *const ()) }};
109129 let sz = unsafe {{ size_of_val("hi") }};
110130 likely(init && sz == 2)
111131 }}
0 commit comments