about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/base-db/src/fixture.rs10
-rw-r--r--crates/hir-ty/src/layout/tests.rs40
-rw-r--r--crates/project-model/src/lib.rs1
-rw-r--r--crates/project-model/src/target_data_layout.rs40
-rw-r--r--crates/project-model/src/tests.rs26
-rw-r--r--crates/project-model/src/workspace.rs45
-rw-r--r--crates/test-utils/src/fixture.rs4
7 files changed, 111 insertions, 55 deletions
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 0ba12e7ee8e..83286cf6b77 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -162,7 +162,7 @@ impl ChangeFixture {
                     Ok(Vec::new()),
                     false,
                     origin,
-                    None,
+                    meta.target_data_layout.as_deref().map(Arc::from),
                 );
                 let prev = crates.insert(crate_name.clone(), crate_id);
                 assert!(prev.is_none());
@@ -212,6 +212,8 @@ impl ChangeFixture {
                     .unwrap();
             }
         }
+        let target_layout =
+            crate_graph.iter().next().and_then(|it| crate_graph[it].target_layout.clone());
 
         if let Some(mini_core) = mini_core {
             let core_file = file_id;
@@ -236,7 +238,7 @@ impl ChangeFixture {
                 Ok(Vec::new()),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::Core),
-                None,
+                target_layout.clone(),
             );
 
             for krate in all_crates {
@@ -274,7 +276,7 @@ impl ChangeFixture {
                 Ok(proc_macro),
                 true,
                 CrateOrigin::CratesIo { repo: None, name: None },
-                None,
+                target_layout,
             );
 
             for krate in all_crates {
@@ -395,6 +397,7 @@ struct FileMeta {
     edition: Edition,
     env: Env,
     introduce_new_source_root: Option<SourceRootKind>,
+    target_data_layout: Option<String>,
 }
 
 fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
@@ -438,6 +441,7 @@ impl From<Fixture> for FileMeta {
                 "library" => SourceRootKind::Library,
                 invalid => panic!("invalid source root kind '{}'", invalid),
             }),
+            target_data_layout: f.target_data_layout,
         }
     }
 }
diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs
index bcd02043482..ba821235f3f 100644
--- a/crates/hir-ty/src/layout/tests.rs
+++ b/crates/hir-ty/src/layout/tests.rs
@@ -9,8 +9,22 @@ use crate::{test_db::TestDB, Interner, Substitution};
 
 use super::layout_of_ty;
 
-fn eval_goal(ra_fixture: &str) -> Result<Layout, LayoutError> {
-    let (db, file_id) = TestDB::with_single_file(ra_fixture);
+fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
+    // using unstable cargo features failed, fall back to using plain rustc
+    let mut cmd = std::process::Command::new("rustc");
+    cmd.args(&["-Z", "unstable-options", "--print", "target-spec-json"])
+        .env("RUSTC_BOOTSTRAP", "1");
+    let output = cmd.output().unwrap();
+    assert!(output.status.success(), "{}", output.status);
+    let stdout = String::from_utf8(output.stdout).unwrap();
+    let target_data_layout =
+        stdout.split_once(r#""data-layout": ""#).unwrap().1.split_once('"').unwrap().0.to_owned();
+
+    let ra_fixture = format!(
+        "{minicore}//- /main.rs crate:test target_data_layout:{target_data_layout}\n{ra_fixture}",
+    );
+
+    let (db, file_id) = TestDB::with_single_file(&ra_fixture);
     let module_id = db.module_for_file(file_id);
     let def_map = module_id.def_map(&db);
     let scope = &def_map[module_id.local_id].scope;
@@ -20,15 +34,11 @@ fn eval_goal(ra_fixture: &str) -> Result<Layout, LayoutError> {
         .find_map(|x| match x {
             hir_def::ModuleDefId::AdtId(x) => {
                 let name = match x {
-                    hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_string(),
-                    hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_string(),
-                    hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_string(),
+                    hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
+                    hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
+                    hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
                 };
-                if name == "Goal" {
-                    Some(x)
-                } else {
-                    None
-                }
+                (name == "Goal").then(|| x)
             }
             _ => None,
         })
@@ -38,15 +48,15 @@ fn eval_goal(ra_fixture: &str) -> Result<Layout, LayoutError> {
 }
 
 #[track_caller]
-fn check_size_and_align(ra_fixture: &str, size: u64, align: u64) {
-    let l = eval_goal(ra_fixture).unwrap();
+fn check_size_and_align(ra_fixture: &str, minicore: &str, size: u64, align: u64) {
+    let l = eval_goal(ra_fixture, minicore).unwrap();
     assert_eq!(l.size.bytes(), size);
     assert_eq!(l.align.abi.bytes(), align);
 }
 
 #[track_caller]
 fn check_fail(ra_fixture: &str, e: LayoutError) {
-    let r = eval_goal(ra_fixture);
+    let r = eval_goal(ra_fixture, "");
     assert_eq!(r, Err(e));
 }
 
@@ -56,7 +66,8 @@ macro_rules! size_and_align {
             #[allow(dead_code)]
             $($t)*
             check_size_and_align(
-                &format!("//- minicore: {}\n{}", stringify!($($x),*), stringify!($($t)*)),
+                stringify!($($t)*),
+                &format!("//- minicore: {}\n", stringify!($($x),*)),
                 ::std::mem::size_of::<Goal>() as u64,
                 ::std::mem::align_of::<Goal>() as u64,
             );
@@ -68,6 +79,7 @@ macro_rules! size_and_align {
             $($t)*
             check_size_and_align(
                 stringify!($($t)*),
+                "",
                 ::std::mem::size_of::<Goal>() as u64,
                 ::std::mem::align_of::<Goal>() as u64,
             );
diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs
index 575581fa543..835f2b3dd03 100644
--- a/crates/project-model/src/lib.rs
+++ b/crates/project-model/src/lib.rs
@@ -25,6 +25,7 @@ mod sysroot;
 mod workspace;
 mod rustc_cfg;
 mod build_scripts;
+mod target_data_layout;
 
 #[cfg(test)]
 mod tests;
diff --git a/crates/project-model/src/target_data_layout.rs b/crates/project-model/src/target_data_layout.rs
new file mode 100644
index 00000000000..b9d7d2338c3
--- /dev/null
+++ b/crates/project-model/src/target_data_layout.rs
@@ -0,0 +1,40 @@
+//! Runs `rustc --print target-spec-json` to get the target_data_layout.
+use std::process::Command;
+
+use rustc_hash::FxHashMap;
+
+use crate::{utf8_stdout, ManifestPath};
+
+pub(super) fn get(
+    cargo_toml: Option<&ManifestPath>,
+    target: Option<&str>,
+    extra_env: &FxHashMap<String, String>,
+) -> Option<String> {
+    let output = (|| {
+        if let Some(cargo_toml) = cargo_toml {
+            let mut cmd = Command::new(toolchain::rustc());
+            cmd.envs(extra_env);
+            cmd.current_dir(cargo_toml.parent())
+                .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
+                .env("RUSTC_BOOTSTRAP", "1");
+            if let Some(target) = target {
+                cmd.args(&["--target", target]);
+            }
+            match utf8_stdout(cmd) {
+                Ok(it) => return Ok(it),
+                Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
+            }
+        }
+        // using unstable cargo features failed, fall back to using plain rustc
+        let mut cmd = Command::new(toolchain::rustc());
+        cmd.envs(extra_env)
+            .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
+            .env("RUSTC_BOOTSTRAP", "1");
+        if let Some(target) = target {
+            cmd.args(&["--target", target]);
+        }
+        utf8_stdout(cmd)
+    })()
+    .ok()?;
+    Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned())
+}
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index 27ab75baccd..adb106e9793 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -151,6 +151,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -220,6 +221,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -298,6 +300,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -376,6 +379,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -463,6 +467,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "feature=use_std",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -548,6 +553,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -619,6 +625,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -699,6 +706,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -779,6 +787,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -866,6 +875,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "feature=use_std",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -942,6 +952,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1013,6 +1024,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1093,6 +1105,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1173,6 +1186,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1260,6 +1274,7 @@ fn cargo_hello_world_project_model() {
                                 "feature=use_std",
                             ],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1328,6 +1343,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1372,6 +1388,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1406,6 +1423,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1440,6 +1458,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1474,6 +1493,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1518,6 +1538,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1552,6 +1573,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1659,6 +1681,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1693,6 +1716,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1727,6 +1751,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1761,6 +1786,7 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
+                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 7f82b9de907..52ac3b6dc02 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -21,8 +21,8 @@ use crate::{
     cfg_flag::CfgFlag,
     rustc_cfg,
     sysroot::SysrootCrate,
-    utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath, Package,
-    ProjectJson, ProjectManifest, Sysroot, TargetKind, WorkspaceBuildScripts,
+    target_data_layout, utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath,
+    Package, ProjectJson, ProjectManifest, Sysroot, TargetKind, WorkspaceBuildScripts,
 };
 
 /// A set of cfg-overrides per crate.
@@ -143,40 +143,6 @@ impl fmt::Debug for ProjectWorkspace {
     }
 }
 
-fn data_layout(
-    cargo_toml: Option<&ManifestPath>,
-    target: Option<&str>,
-    extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
-    let output = (|| {
-        if let Some(cargo_toml) = cargo_toml {
-            let mut cmd = Command::new(toolchain::rustc());
-            cmd.envs(extra_env);
-            cmd.current_dir(cargo_toml.parent())
-                .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
-                .env("RUSTC_BOOTSTRAP", "1");
-            if let Some(target) = target {
-                cmd.args(&["--target", target]);
-            }
-            match utf8_stdout(cmd) {
-                Ok(it) => return Ok(it),
-                Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
-            }
-        }
-        // using unstable cargo features failed, fall back to using plain rustc
-        let mut cmd = Command::new(toolchain::rustc());
-        cmd.envs(extra_env)
-            .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
-            .env("RUSTC_BOOTSTRAP", "1");
-        if let Some(target) = target {
-            cmd.args(&["--target", target]);
-        }
-        utf8_stdout(cmd)
-    })()
-    .ok()?;
-    Some(output.split_once(r#""data-layout": "#)?.1.trim_matches('"').to_owned())
-}
-
 impl ProjectWorkspace {
     pub fn load(
         manifest: ProjectManifest,
@@ -278,8 +244,11 @@ impl ProjectWorkspace {
                     rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), &config.extra_env);
 
                 let cfg_overrides = config.cfg_overrides();
-                let data_layout =
-                    data_layout(Some(&cargo_toml), config.target.as_deref(), &config.extra_env);
+                let data_layout = target_data_layout::get(
+                    Some(&cargo_toml),
+                    config.target.as_deref(),
+                    &config.extra_env,
+                );
                 ProjectWorkspace::Cargo {
                     cargo,
                     build_scripts: WorkspaceBuildScripts::default(),
diff --git a/crates/test-utils/src/fixture.rs b/crates/test-utils/src/fixture.rs
index c824f5af725..73e72c18809 100644
--- a/crates/test-utils/src/fixture.rs
+++ b/crates/test-utils/src/fixture.rs
@@ -78,6 +78,7 @@ pub struct Fixture {
     pub edition: Option<String>,
     pub env: FxHashMap<String, String>,
     pub introduce_new_source_root: Option<String>,
+    pub target_data_layout: Option<String>,
 }
 
 pub struct MiniCore {
@@ -181,6 +182,7 @@ impl Fixture {
         let mut cfg_key_values = Vec::new();
         let mut env = FxHashMap::default();
         let mut introduce_new_source_root = None;
+        let mut target_data_layout = None;
         for component in components[1..].iter() {
             let (key, value) = component
                 .split_once(':')
@@ -213,6 +215,7 @@ impl Fixture {
                     }
                 }
                 "new_source_root" => introduce_new_source_root = Some(value.to_string()),
+                "target_data_layout" => target_data_layout = Some(value.to_string()),
                 _ => panic!("bad component: {:?}", component),
             }
         }
@@ -237,6 +240,7 @@ impl Fixture {
             edition,
             env,
             introduce_new_source_root,
+            target_data_layout,
         }
     }
 }