]> git.lizzy.rs Git - rust.git/blobdiff - crates/project_model/src/workspace.rs
Don't load auxiliary crates outside the workspace
[rust.git] / crates / project_model / src / workspace.rs
index 0335f8b1746247c6ca7a13d7040ba358ca03f0b8..96522bf070a4ccc1dddef77d689bb985d5d0b423 100644 (file)
@@ -387,10 +387,14 @@ pub fn n_packages(&self) -> usize {
 
     pub fn to_crate_graph(
         &self,
-        load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+        dummy_replace: &FxHashMap<Box<str>, Box<[Box<str>]>>,
+        load_proc_macro: &mut dyn FnMut(&AbsPath, &[Box<str>]) -> Vec<ProcMacro>,
         load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     ) -> CrateGraph {
         let _p = profile::span("ProjectWorkspace::to_crate_graph");
+        let load_proc_macro = &mut |crate_name: &_, path: &_| {
+            load_proc_macro(path, dummy_replace.get(crate_name).map(|it| &**it).unwrap_or_default())
+        };
 
         let mut crate_graph = match self {
             ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
@@ -432,7 +436,7 @@ pub fn to_crate_graph(
 
 fn project_json_to_crate_graph(
     rustc_cfg: Vec<CfgFlag>,
-    load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     project: &ProjectJson,
     sysroot: &Option<Sysroot>,
@@ -452,7 +456,12 @@ fn project_json_to_crate_graph(
         })
         .map(|(crate_id, krate, file_id)| {
             let env = krate.env.clone().into_iter().collect();
-            let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| load_proc_macro(&it));
+            let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| {
+                load_proc_macro(
+                    krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
+                    &it,
+                )
+            });
 
             let target_cfgs = match krate.target.as_deref() {
                 Some(target) => {
@@ -513,7 +522,7 @@ fn project_json_to_crate_graph(
 fn cargo_to_crate_graph(
     rustc_cfg: Vec<CfgFlag>,
     override_cfg: &CfgOverrides,
-    load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     cargo: &CargoWorkspace,
     build_scripts: &WorkspaceBuildScripts,
@@ -565,13 +574,22 @@ fn cargo_to_crate_graph(
         has_private |= cargo[pkg].metadata.rustc_private;
         let mut lib_tgt = None;
         for &tgt in cargo[pkg].targets.iter() {
+            if cargo[tgt].kind != TargetKind::Lib && !cargo[pkg].is_member {
+                // For non-workspace-members, Cargo does not resolve dev-dependencies, so we don't
+                // add any targets except the library target, since those will not work correctly if
+                // they use dev-dependencies.
+                // In fact, they can break quite badly if multiple client workspaces get merged:
+                // https://github.com/rust-analyzer/rust-analyzer/issues/11300
+                continue;
+            }
+
             if let Some(file_id) = load(&cargo[tgt].root) {
                 let crate_id = add_target_crate_root(
                     &mut crate_graph,
                     &cargo[pkg],
                     build_scripts.outputs.get(pkg),
                     cfg_options,
-                    load_proc_macro,
+                    &mut |path| load_proc_macro(&cargo[tgt].name, path),
                     file_id,
                     &cargo[tgt].name,
                 );
@@ -595,6 +613,9 @@ fn cargo_to_crate_graph(
 
         // Set deps to the core, std and to the lib target of the current package
         for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
+            // Add sysroot deps first so that a lib target named `core` etc. can overwrite them.
+            public_deps.add(*from, &mut crate_graph);
+
             if let Some((to, name)) = lib_tgt.clone() {
                 if to != *from && *kind != TargetKind::BuildScript {
                     // (build script can not depend on its library target)
@@ -606,7 +627,6 @@ fn cargo_to_crate_graph(
                     add_dep(&mut crate_graph, *from, name, to);
                 }
             }
-            public_deps.add(*from, &mut crate_graph);
         }
     }
 
@@ -700,7 +720,7 @@ fn handle_rustc_crates(
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     crate_graph: &mut CrateGraph,
     cfg_options: &CfgOptions,
-    load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+    load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
     pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
     public_deps: &SysrootPublicDeps,
     cargo: &CargoWorkspace,
@@ -736,7 +756,7 @@ fn handle_rustc_crates(
                         &rustc_workspace[pkg],
                         None,
                         cfg_options,
-                        load_proc_macro,
+                        &mut |path| load_proc_macro(&rustc_workspace[tgt].name, path),
                         file_id,
                         &rustc_workspace[tgt].name,
                     );