]> git.lizzy.rs Git - rust.git/blobdiff - crates/proc-macro-srv/src/abis/mod.rs
Assert that sysroot ABI version matches exactly
[rust.git] / crates / proc-macro-srv / src / abis / mod.rs
index f1083a9284b3acbed05124e77c50917490fcdcd1..a59da0f6b10bbdd9ed0ff79260f2861d4312ad26 100644 (file)
@@ -29,6 +29,9 @@
 #[cfg(feature = "sysroot-abi")]
 mod abi_sysroot;
 
+// see `build.rs`
+include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
+
 // Used by `test/utils.rs`
 #[cfg(test)]
 pub(crate) use abi_1_64::TokenStream as TestTokenStream;
@@ -74,13 +77,37 @@ pub fn from_lib(
         lib: &Library,
         symbol_name: String,
         info: RustCInfo,
+        #[cfg_attr(not(feature = "sysroot-abi"), allow(unused_variables))] version_string: String,
     ) -> Result<Abi, LoadProcMacroDylibError> {
-        // Gated behind an env var for now to avoid a change in behavior for
-        // rustup-installed rust-analyzer
+        // the sysroot ABI relies on `extern proc_macro` with unstable features,
+        // instead of a snapshot of the proc macro bridge's source code. it's only
+        // enabled if we have an exact version match.
         #[cfg(feature = "sysroot-abi")]
-        if std::env::var("PROC_MACRO_SRV_SYSROOT_ABI").is_ok() {
-            let inner = unsafe { Abi_Sysroot::from_lib(lib, symbol_name) }?;
-            return Ok(Abi::AbiSysroot(inner));
+        {
+            if version_string == RUSTC_VERSION_STRING {
+                let inner = unsafe { Abi_Sysroot::from_lib(lib, symbol_name) }?;
+                return Ok(Abi::AbiSysroot(inner));
+            }
+
+            // if we reached this point, versions didn't match. in testing, we
+            // want that to panic - this could mean that the format of `rustc
+            // --version` no longer matches the format of the version string
+            // stored in the `.rustc` section, and we want to catch that in-tree
+            // with `x.py test`
+            #[cfg(test)]
+            {
+                let allow_mismatch = std::env::var("PROC_MACRO_SRV_ALLOW_SYSROOT_MISMATCH");
+                if let Ok("1") = allow_mismatch.as_deref() {
+                    // only used by rust-analyzer developers, when working on the
+                    // sysroot ABI from the rust-analyzer repository - which should
+                    // only happen pre-subtree. this can be removed later.
+                } else {
+                    panic!(
+                        "sysroot ABI mismatch: dylib rustc version (read from .rustc section): {:?} != proc-macro-srv version (read from 'rustc --version'): {:?}",
+                        version_string, RUSTC_VERSION_STRING
+                    );
+                }
+            }
         }
 
         // FIXME: this should use exclusive ranges when they're stable