@@ -11,17 +11,80 @@ fn main() {
11
11
. stdout ;
12
12
let version = String :: from_utf8 ( output) . unwrap ( ) ;
13
13
14
+ enable_simd_optimizations ( & version) ;
15
+ }
16
+
17
+ fn enable_simd_optimizations ( version : & str ) {
14
18
// If we're using nightly Rust, then we can enable vector optimizations.
15
19
// Note that these aren't actually activated unless the `unstable` feature
16
20
// is enabled.
17
21
//
18
22
// We also don't activate these if we've explicitly disabled auto
19
23
// optimizations. Disabling auto optimizations is intended for use in
20
24
// tests, so that we can reliably test fallback implementations.
21
- if env:: var_os ( "CARGO_CFG_REGEX_DISABLE_AUTO_OPTIMIZATIONS" ) . is_none ( ) {
22
- if version. contains ( "nightly" ) {
23
- println ! ( "cargo:rustc-cfg=regex_runtime_teddy_ssse3" ) ;
24
- println ! ( "cargo:rustc-cfg=regex_runtime_teddy_avx2" ) ;
25
+ if env:: var_os ( "CARGO_CFG_REGEX_DISABLE_AUTO_OPTIMIZATIONS" ) . is_some ( ) {
26
+ return ;
27
+ }
28
+ let parsed = match Version :: parse ( & version) {
29
+ Ok ( parsed) => parsed,
30
+ Err ( err) => {
31
+ eprintln ! ( "failed to parse `rustc --version`: {}" , err) ;
32
+ return ;
33
+ }
34
+ } ;
35
+ let minimum = Version { major : 1 , minor : 27 , patch : 0 } ;
36
+ if version. contains ( "nightly" ) || parsed >= minimum {
37
+ println ! ( "cargo:rustc-cfg=regex_runtime_teddy_ssse3" ) ;
38
+ println ! ( "cargo:rustc-cfg=regex_runtime_teddy_avx2" ) ;
39
+ }
40
+ }
41
+
42
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
43
+ struct Version {
44
+ major : u32 ,
45
+ minor : u32 ,
46
+ patch : u32 ,
47
+ }
48
+
49
+ impl Version {
50
+ fn parse ( mut s : & str ) -> Result < Version , String > {
51
+ if !s. starts_with ( "rustc " ) {
52
+ return Err ( format ! ( "unrecognized version string: {}" , s) ) ;
25
53
}
54
+ s = & s[ "rustc " . len ( ) ..] ;
55
+
56
+ let parts: Vec < & str > = s. split ( "." ) . collect ( ) ;
57
+ if parts. len ( ) < 3 {
58
+ return Err ( format ! ( "not enough version parts: {:?}" , parts) ) ;
59
+ }
60
+
61
+ let mut num = String :: new ( ) ;
62
+ for c in parts[ 0 ] . chars ( ) {
63
+ if !c. is_digit ( 10 ) {
64
+ break ;
65
+ }
66
+ num. push ( c) ;
67
+ }
68
+ let major = num. parse :: < u32 > ( ) . map_err ( |e| e. to_string ( ) ) ?;
69
+
70
+ num. clear ( ) ;
71
+ for c in parts[ 1 ] . chars ( ) {
72
+ if !c. is_digit ( 10 ) {
73
+ break ;
74
+ }
75
+ num. push ( c) ;
76
+ }
77
+ let minor = num. parse :: < u32 > ( ) . map_err ( |e| e. to_string ( ) ) ?;
78
+
79
+ num. clear ( ) ;
80
+ for c in parts[ 2 ] . chars ( ) {
81
+ if !c. is_digit ( 10 ) {
82
+ break ;
83
+ }
84
+ num. push ( c) ;
85
+ }
86
+ let patch = num. parse :: < u32 > ( ) . map_err ( |e| e. to_string ( ) ) ?;
87
+
88
+ Ok ( Version { major, minor, patch } )
26
89
}
27
90
}
0 commit comments