1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::process::Command;
fn main() {
let (_major, minor, _patch) = detect_rustc_version();
// Register all cfg flags with Cargo for expected warnings suppression.
emit_check_cfg("rustc_spanned_at_root");
emit_check_cfg("rapx_rustc_ge_193");
emit_check_cfg("rapx_rustc_ge_196");
emit_check_cfg("rapx_rustc_ge_198");
// ─── Version-gated compatibility flags ───────────────────────────────
//
// Add new entries here when compiler APIs change. Each entry records
// the minimum rustc minor version that requires the new code path.
//
// Flag name | since | Description
// ------------------------------|-------|-------------------------------
// rustc_spanned_at_root | 1.96 | Spanned: source_map::Spanned
// | | became private; only
// | | rustc_span::Spanned is public
// rapx_rustc_ge_193 | 1.93 | Analysis trait: &mut self→&self
// | | NullaryOp: 1→2 fields
// | | Option<EarlyBinder<T>> blanket
// | | methods (skip_binder, etc.)
// | | impl_trait_id, impl_opt_trait_ref
// | | added to TyCtxt
// | | is_doc_comment: bool→Option<bool>
// rapx_rustc_ge_196 | 1.96 | Rvalue::NullaryOp removed
// | | Rvalue::ShallowInitBox removed
// | | Spanned: re-export→re-export of
// | | private type
// | | Operand::RuntimeChecks added
// | | Fn::eii_impls added
// | | DefKind::Const/AssocConst
// | | unit→struct variants
// | | Query key ref changes
// rapx_rustc_ge_198 | 1.98 | Ty/TraitRef/Clause/FnSig
// | | wrapped in Unnormalized
// | | StatementKind::Retag removed
// | | TerminatorKind::Drop
// | | async_fut field removed
// | | ItemKind::Trait struct variant
// | | FieldDef::mut_restriction added
// | | Various tuple variant field
// | | count changes
emit_cfg("rustc_spanned_at_root", minor >= 96);
emit_cfg("rapx_rustc_ge_193", minor >= 93);
emit_cfg("rapx_rustc_ge_196", minor >= 96);
emit_cfg("rapx_rustc_ge_198", minor >= 98);
}
fn emit_check_cfg(name: &str) {
println!("cargo::rustc-check-cfg=cfg({name})");
}
fn emit_cfg(name: &str, condition: bool) {
if condition {
println!("cargo::rustc-cfg={name}");
}
}
fn detect_rustc_version() -> (u32, u32, u32) {
let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string());
let output = Command::new(&rustc)
.arg("--version")
.output()
.unwrap_or_else(|_| panic!("failed to run `{} --version`", rustc));
let version = String::from_utf8_lossy(&output.stdout);
let parts: Vec<&str> = version
.split(|c: char| !c.is_ascii_digit())
.filter(|s| !s.is_empty())
.collect();
let major = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
let minor = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
let patch = parts.get(2).and_then(|s| s.parse().ok()).unwrap_or(0);
(major, minor, patch)
}