77#[ macro_use]
88extern crate quote;
99
10- use proc_macro2:: { Ident , Literal , Span , TokenStream , TokenTree } ;
10+ use proc_macro2:: { Ident , Span , TokenStream , TokenTree } ;
1111use quote:: ToTokens ;
1212use std:: env;
1313
14- fn string ( s : & str ) -> TokenTree {
15- Literal :: string ( s) . into ( )
16- }
17-
1814#[ proc_macro_attribute]
1915pub fn simd_test (
2016 attr : proc_macro:: TokenStream ,
2117 item : proc_macro:: TokenStream ,
2218) -> proc_macro:: TokenStream {
2319 let tokens = TokenStream :: from ( attr) . into_iter ( ) . collect :: < Vec < _ > > ( ) ;
24- if tokens. len ( ) != 3 {
25- panic ! ( "expected #[simd_test(enable = \" feature\" )]" ) ;
26- }
27- match & tokens[ 0 ] {
28- TokenTree :: Ident ( tt) if * tt == "enable" => { }
29- _ => panic ! ( "expected #[simd_test(enable = \" feature\" )]" ) ,
30- }
31- match & tokens[ 1 ] {
32- TokenTree :: Punct ( tt) if tt. as_char ( ) == '=' => { }
33- _ => panic ! ( "expected #[simd_test(enable = \" feature\" )]" ) ,
34- }
35- let enable_feature = match & tokens[ 2 ] {
36- TokenTree :: Literal ( tt) => tt. to_string ( ) ,
37- _ => panic ! ( "expected #[simd_test(enable = \" feature\" )]" ) ,
20+ let ( target_features, target_feature_attr) = match & tokens[ ..] {
21+ [ ] => ( Vec :: new ( ) , TokenStream :: new ( ) ) ,
22+ [
23+ TokenTree :: Ident ( enable) ,
24+ TokenTree :: Punct ( equals) ,
25+ TokenTree :: Literal ( literal) ,
26+ ] if enable == "enable" && equals. as_char ( ) == '=' => {
27+ let enable_feature = literal. to_string ( ) ;
28+ let enable_feature = enable_feature. trim_start_matches ( '"' ) . trim_end_matches ( '"' ) ;
29+ let target_features: Vec < _ > = enable_feature
30+ . replace ( '+' , "" )
31+ . split ( ',' )
32+ . map ( String :: from)
33+ . collect ( ) ;
34+
35+ (
36+ target_features,
37+ quote ! {
38+ #[ target_feature( enable = #enable_feature) ]
39+ } ,
40+ )
41+ }
42+ _ => panic ! ( "expected #[simd_test(enable = \" feature\" )] or #[simd_test]" ) ,
3843 } ;
39- let enable_feature = enable_feature. trim_start_matches ( '"' ) . trim_end_matches ( '"' ) ;
40- let target_features: Vec < String > = enable_feature
41- . replace ( '+' , "" )
42- . split ( ',' )
43- . map ( String :: from)
44- . collect ( ) ;
4544
46- let enable_feature = string ( enable_feature) ;
4745 let mut item = syn:: parse_macro_input!( item as syn:: ItemFn ) ;
4846 let item_attrs = std:: mem:: take ( & mut item. attrs ) ;
4947 let name = & item. sig . ident ;
@@ -102,13 +100,28 @@ pub fn simd_test(
102100 TokenStream :: new ( )
103101 } ;
104102
103+ let ( const_test, const_stability) = if item. sig . constness . is_some ( ) {
104+ (
105+ quote ! {
106+ const _: ( ) = unsafe { #name( ) } ;
107+ } ,
108+ quote ! {
109+ #[ rustc_const_unstable( feature = "stdarch_const_intrinsics" , issue = "none" ) ]
110+ } ,
111+ )
112+ } else {
113+ ( TokenStream :: new ( ) , TokenStream :: new ( ) )
114+ } ;
115+
105116 let ret: TokenStream = quote_spanned ! {
106117 proc_macro2:: Span :: call_site( ) =>
107118 #[ allow( non_snake_case) ]
108119 #[ test]
109120 #maybe_ignore
110121 #( #item_attrs) *
111122 fn #name( ) {
123+ #const_test
124+
112125 let mut missing_features = :: std:: vec:: Vec :: new( ) ;
113126 #detect_missing_features
114127 if missing_features. is_empty( ) {
@@ -118,7 +131,8 @@ pub fn simd_test(
118131 :: stdarch_test:: assert_skip_test_ok( stringify!( #name) , & missing_features) ;
119132 }
120133
121- #[ target_feature( enable = #enable_feature) ]
134+ #target_feature_attr
135+ #const_stability
122136 #item
123137 }
124138 } ;
0 commit comments