]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | // rustc-cfg emitted by the build script: |
2 | // | |
3 | // "use_proc_macro" | |
4 | // Link to extern crate proc_macro. Available on any compiler and any target | |
5 | // except wasm32. Requires "proc-macro" Cargo cfg to be enabled (default is | |
6 | // enabled). On wasm32 we never link to proc_macro even if "proc-macro" cfg | |
7 | // is enabled. | |
8 | // | |
9 | // "wrap_proc_macro" | |
10 | // Wrap types from libproc_macro rather than polyfilling the whole API. | |
11 | // Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, | |
12 | // because we can't emulate the unstable API without emulating everything | |
13 | // else. Also enabled unconditionally on nightly, in which case the | |
14 | // procmacro2_semver_exempt surface area is implemented by using the | |
15 | // nightly-only proc_macro API. | |
16 | // | |
f035d41b XL |
17 | // "hygiene" |
18 | // Enable Span::mixed_site() and non-dummy behavior of Span::resolved_at | |
19 | // and Span::located_at. Enabled on Rust 1.45+. | |
20 | // | |
e74abb32 XL |
21 | // "proc_macro_span" |
22 | // Enable non-dummy behavior of Span::start and Span::end methods which | |
23 | // requires an unstable compiler feature. Enabled when building with | |
24 | // nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable | |
25 | // features. | |
26 | // | |
27 | // "super_unstable" | |
28 | // Implement the semver exempt API in terms of the nightly-only proc_macro | |
29 | // API. Enabled when using procmacro2_semver_exempt on a nightly compiler. | |
30 | // | |
31 | // "span_locations" | |
32 | // Provide methods Span::start and Span::end which give the line/column | |
33 | // location of a token. Enabled by procmacro2_semver_exempt or the | |
34 | // "span-locations" Cargo cfg. This is behind a cfg because tracking | |
35 | // location inside spans is a performance hit. | |
36 | ||
37 | use std::env; | |
38 | use std::process::{self, Command}; | |
39 | use std::str; | |
40 | ||
41 | fn main() { | |
42 | println!("cargo:rerun-if-changed=build.rs"); | |
43 | ||
44 | let version = match rustc_version() { | |
45 | Some(version) => version, | |
46 | None => return, | |
47 | }; | |
48 | ||
49 | if version.minor < 31 { | |
50 | eprintln!("Minimum supported rustc version is 1.31"); | |
51 | process::exit(1); | |
52 | } | |
53 | ||
54 | let semver_exempt = cfg!(procmacro2_semver_exempt); | |
55 | if semver_exempt { | |
56 | // https://github.com/alexcrichton/proc-macro2/issues/147 | |
57 | println!("cargo:rustc-cfg=procmacro2_semver_exempt"); | |
58 | } | |
59 | ||
60 | if semver_exempt || cfg!(feature = "span-locations") { | |
61 | println!("cargo:rustc-cfg=span_locations"); | |
62 | } | |
63 | ||
1b1a35ee XL |
64 | if version.minor < 32 { |
65 | println!("cargo:rustc-cfg=no_libprocmacro_unwind_safe"); | |
66 | } | |
67 | ||
f035d41b XL |
68 | if version.minor < 39 { |
69 | println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard"); | |
70 | } | |
71 | ||
72 | if version.minor >= 45 { | |
73 | println!("cargo:rustc-cfg=hygiene"); | |
74 | } | |
75 | ||
e74abb32 XL |
76 | let target = env::var("TARGET").unwrap(); |
77 | if !enable_use_proc_macro(&target) { | |
78 | return; | |
79 | } | |
80 | ||
81 | println!("cargo:rustc-cfg=use_proc_macro"); | |
82 | ||
83 | if version.nightly || !semver_exempt { | |
84 | println!("cargo:rustc-cfg=wrap_proc_macro"); | |
85 | } | |
86 | ||
87 | if version.nightly && feature_allowed("proc_macro_span") { | |
88 | println!("cargo:rustc-cfg=proc_macro_span"); | |
89 | } | |
90 | ||
91 | if semver_exempt && version.nightly { | |
92 | println!("cargo:rustc-cfg=super_unstable"); | |
93 | } | |
94 | } | |
95 | ||
96 | fn enable_use_proc_macro(target: &str) -> bool { | |
97 | // wasm targets don't have the `proc_macro` crate, disable this feature. | |
98 | if target.contains("wasm32") { | |
99 | return false; | |
100 | } | |
101 | ||
102 | // Otherwise, only enable it if our feature is actually enabled. | |
103 | cfg!(feature = "proc-macro") | |
104 | } | |
105 | ||
106 | struct RustcVersion { | |
107 | minor: u32, | |
108 | nightly: bool, | |
109 | } | |
110 | ||
111 | fn rustc_version() -> Option<RustcVersion> { | |
112 | let rustc = env::var_os("RUSTC")?; | |
113 | let output = Command::new(rustc).arg("--version").output().ok()?; | |
114 | let version = str::from_utf8(&output.stdout).ok()?; | |
115 | let nightly = version.contains("nightly") || version.contains("dev"); | |
116 | let mut pieces = version.split('.'); | |
117 | if pieces.next() != Some("rustc 1") { | |
118 | return None; | |
119 | } | |
120 | let minor = pieces.next()?.parse().ok()?; | |
121 | Some(RustcVersion { minor, nightly }) | |
122 | } | |
123 | ||
124 | fn feature_allowed(feature: &str) -> bool { | |
125 | // Recognized formats: | |
126 | // | |
127 | // -Z allow-features=feature1,feature2 | |
128 | // | |
129 | // -Zallow-features=feature1,feature2 | |
130 | ||
131 | if let Some(rustflags) = env::var_os("RUSTFLAGS") { | |
132 | for mut flag in rustflags.to_string_lossy().split(' ') { | |
133 | if flag.starts_with("-Z") { | |
134 | flag = &flag["-Z".len()..]; | |
135 | } | |
136 | if flag.starts_with("allow-features=") { | |
137 | flag = &flag["allow-features=".len()..]; | |
138 | return flag.split(',').any(|allowed| allowed == feature); | |
139 | } | |
140 | } | |
141 | } | |
142 | ||
143 | // No allow-features= flag, allowed by default. | |
144 | true | |
145 | } |