]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs
Rollup merge of #100730 - CleanCut:diagnostics-rustc_monomorphize, r=davidtwco
[rust.git] / src / tools / rust-analyzer / crates / project-model / src / rustc_cfg.rs
1 //! Runs `rustc --print cfg` to get built-in cfg flags.
2
3 use std::process::Command;
4
5 use anyhow::Result;
6
7 use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath};
8
9 pub(crate) fn get(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Vec<CfgFlag> {
10     let _p = profile::span("rustc_cfg::get");
11     let mut res = Vec::with_capacity(6 * 2 + 1);
12
13     // Some nightly-only cfgs, which are required for stdlib
14     res.push(CfgFlag::Atom("target_thread_local".into()));
15     for ty in ["8", "16", "32", "64", "cas", "ptr"] {
16         for key in ["target_has_atomic", "target_has_atomic_load_store"] {
17             res.push(CfgFlag::KeyValue { key: key.to_string(), value: ty.into() });
18         }
19     }
20
21     match get_rust_cfgs(cargo_toml, target) {
22         Ok(rustc_cfgs) => {
23             tracing::debug!(
24                 "rustc cfgs found: {:?}",
25                 rustc_cfgs
26                     .lines()
27                     .map(|it| it.parse::<CfgFlag>().map(|it| it.to_string()))
28                     .collect::<Vec<_>>()
29             );
30             res.extend(rustc_cfgs.lines().filter_map(|it| it.parse().ok()));
31         }
32         Err(e) => tracing::error!("failed to get rustc cfgs: {e:?}"),
33     }
34
35     res
36 }
37
38 fn get_rust_cfgs(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Result<String> {
39     if let Some(cargo_toml) = cargo_toml {
40         let mut cargo_config = Command::new(toolchain::cargo());
41         cargo_config
42             .current_dir(cargo_toml.parent())
43             .args(&["-Z", "unstable-options", "rustc", "--print", "cfg"])
44             .env("RUSTC_BOOTSTRAP", "1");
45         if let Some(target) = target {
46             cargo_config.args(&["--target", target]);
47         }
48         match utf8_stdout(cargo_config) {
49             Ok(it) => return Ok(it),
50             Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
51         }
52     }
53     // using unstable cargo features failed, fall back to using plain rustc
54     let mut cmd = Command::new(toolchain::rustc());
55     cmd.args(&["--print", "cfg", "-O"]);
56     if let Some(target) = target {
57         cmd.args(&["--target", target]);
58     }
59     utf8_stdout(cmd)
60 }