{"record":{"id":"21cf8377337721be","repo":"rust-lang/rust","slug":"cfg-release-env-var-err","errorCode":null,"errorMessage":"CFG_RELEASE env var: {err}","messagePattern":"CFG_RELEASE env var: (.+?)","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"compiler/rustc_macros/src/current_version.rs","lineNumber":12,"sourceCode":"use proc_macro::TokenStream;\nuse proc_macro2::Span;\nuse quote::quote;\n\npub(crate) fn current_version(_input: TokenStream) -> TokenStream {\n    let env_var = \"CFG_RELEASE\";\n    TokenStream::from(match RustcVersion::parse_cfg_release(env_var) {\n        Ok(RustcVersion { major, minor, patch }) => quote!(\n            // The produced literal has type `rustc_session::RustcVersion`.\n            Self { major: #major, minor: #minor, patch: #patch }\n        ),\n        Err(err) => syn::Error::new(Span::call_site(), format!(\"{env_var} env var: {err}\"))\n            .into_compile_error(),\n    })\n}\n\nstruct RustcVersion {\n    major: u16,\n    minor: u16,\n    patch: u16,\n}\n\nimpl RustcVersion {\n    fn parse_cfg_release(env_var: &str) -> Result<Self, Box<dyn std::error::Error>> {\n        let value = proc_macro::tracked::env_var(env_var)?;\n\n        Self::parse_str(&value)\n            .ok_or_else(|| format!(\"failed to parse rustc version: {:?}\", value).into())\n    }\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/compiler/rustc_macros/src/current_version.rs#L1-L30","documentation":"Emitted by the current_version proc macro in rustc_macros. The macro reads the CFG_RELEASE environment variable via proc_macro::tracked::env_var, then parses it as major.minor.patch (ignoring any -suffix like -dev or -nightly). If the env var is missing (tracked::env_var returns Err) or the value cannot be parsed into three numeric components (parse_str returns None), the macro emits a compile-time syn::Error at the call site. This macro is used by rustc_session to embed the compiler version into the binary.","triggerScenarios":"Building a rustc compiler crate (e.g., rustc_session) that invokes the current_version macro without the CFG_RELEASE environment variable set, or with a value that doesn't contain at least major.minor as numbers. Normal builds go through ./x.py which sets CFG_RELEASE via the bootstrap system.","commonSituations":"Running cargo build directly inside a rustc sub-crate instead of through ./x.py; CI scripts that build rustc components without invoking bootstrap; a broken or incomplete bootstrap configuration that fails to export CFG_RELEASE; manually setting CFG_RELEASE to a non-semver string.","solutions":["Always build the compiler through ./x.py build or ./x.py check, which sets CFG_RELEASE and all other required environment variables.","If you must invoke cargo directly, set CFG_RELEASE manually, e.g.: CFG_RELEASE=\"1.89.0-dev\" cargo build -p rustc_session.","Verify the value is parseable: it must contain at least two dot-separated numeric components (e.g., \"1.89.0\" or \"1.89.0-dev\").","Check bootstrap.example.toml and the bootstrap code for how CFG_RELEASE is derived from the version field."],"exampleFix":"# before: direct cargo build without bootstrap env\ncargo build -p rustc_session\n# error: CFG_RELEASE env var: ...\n# after: build through bootstrap which sets CFG_RELEASE\n./x.py build --stage 1 compiler/rustc_session\n# or set the env var manually:\nCFG_RELEASE=\"1.89.0-dev\" cargo build -p rustc_session","handlingStrategy":"validation","validationCode":"// Before building a rustc crate that uses the current_version macro,\n// verify that CFG_RELEASE is set and parseable.\nfn validate_cfg_release() -> Result<(), String> {\n    let val = std::env::var(\"CFG_RELEASE\").map_err(|_| \"CFG_RELEASE env var is not set\")?;\n    let core = val.split('-').next().unwrap_or(\"\");\n    let parts: Vec<&str> = core.split('.').collect();\n    if parts.len() < 2 {\n        return Err(format!(\"CFG_RELEASE '{}' is not a valid version (expected major.minor.patch)\", val));\n    }\n    for p in &parts {\n        p.parse::<u16>().map_err(|_| format!(\"CFG_RELEASE '{}' has non-numeric component\", val))?;\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"// This error is a compile-time syn::Error emitted by the proc macro.\n// It cannot be caught at runtime. Prevent it by ensuring the build\n// environment has CFG_RELEASE set (normally handled by ./x.py bootstrap).\n// The error appears as: error: CFG_RELEASE env var: <message>","preventionTips":["Always build the compiler through ./x.py, which sets CFG_RELEASE via bootstrap.","Never run bare cargo build on individual rustc crates without the bootstrap environment.","If scripting CI around rustc, export CFG_RELEASE explicitly (e.g., CFG_RELEASE=\"$(cat src/version)\"  ).","Ensure the version string is numeric major.minor[.patch] with an optional -suffix."],"tags":["rustc","proc-macro","build","bootstrap","env-var"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}