]> git.lizzy.rs Git - rust.git/commitdiff
Remember the difference between 'sysroot root' and 'sysroot src root', start looking...
authorAmos Wenger <amoswenger@gmail.com>
Mon, 25 Jul 2022 14:07:41 +0000 (16:07 +0200)
committerAmos Wenger <amoswenger@gmail.com>
Mon, 25 Jul 2022 14:07:41 +0000 (16:07 +0200)
crates/project-model/src/project_json.rs
crates/project-model/src/sysroot.rs
crates/project-model/src/tests.rs
crates/project-model/src/workspace.rs
crates/rust-analyzer/src/reload.rs

index a3c5ac167406d7f7ca8641f0d1aa3b087d4201d4..63d1d0ace96b973bd84f22e61f83348c120f34c6 100644 (file)
@@ -17,6 +17,9 @@
 /// Roots and crates that compose this Rust project.
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub struct ProjectJson {
+    /// e.g. `path/to/sysroot`
+    pub(crate) sysroot: Option<AbsPathBuf>,
+    /// e.g. `path/to/sysroot/lib/rustlib/src/rust`
     pub(crate) sysroot_src: Option<AbsPathBuf>,
     project_root: AbsPathBuf,
     crates: Vec<Crate>,
@@ -52,6 +55,7 @@ impl ProjectJson {
     ///            configuration.
     pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
         ProjectJson {
+            sysroot: data.sysroot.map(|it| base.join(it)),
             sysroot_src: data.sysroot_src.map(|it| base.join(it)),
             project_root: base.to_path_buf(),
             crates: data
@@ -122,6 +126,7 @@ pub fn path(&self) -> &AbsPath {
 
 #[derive(Deserialize, Debug, Clone)]
 pub struct ProjectJsonData {
+    sysroot: Option<PathBuf>,
     sysroot_src: Option<PathBuf>,
     crates: Vec<CrateData>,
 }
index 52750f48969f7032fa6384242a43fa5dbc3cc992..b17a59b10bb57c84fff1e32775e112e7bd578b7d 100644 (file)
@@ -15,6 +15,7 @@
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Sysroot {
     root: AbsPathBuf,
+    src_root: AbsPathBuf,
     crates: Arena<SysrootCrateData>,
 }
 
@@ -35,6 +36,15 @@ fn index(&self, index: SysrootCrate) -> &SysrootCrateData {
 }
 
 impl Sysroot {
+    /// Returns sysroot directory, where `bin/`, `etc/`, `lib/`, `libexec/`
+    /// subfolder live, like:
+    /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library`
+    pub fn src_root(&self) -> &AbsPath {
+        &self.src_root
+    }
+
+    /// Returns sysroot "src" directory, where stdlib sources are located, like:
+    /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu`
     pub fn root(&self) -> &AbsPath {
         &self.root
     }
@@ -61,7 +71,7 @@ pub fn discover(dir: &AbsPath) -> Result<Sysroot> {
         tracing::debug!("Discovering sysroot for {}", dir.display());
         let sysroot_dir = discover_sysroot_dir(dir)?;
         let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir)?;
-        let res = Sysroot::load(sysroot_src_dir)?;
+        let res = Sysroot::load(sysroot_dir, sysroot_src_dir)?;
         Ok(res)
     }
 
@@ -71,14 +81,15 @@ pub fn discover_rustc(cargo_toml: &ManifestPath) -> Option<ManifestPath> {
         discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
     }
 
-    pub fn load(sysroot_src_dir: AbsPathBuf) -> Result<Sysroot> {
-        let mut sysroot = Sysroot { root: sysroot_src_dir, crates: Arena::default() };
+    pub fn load(sysroot_dir: AbsPathBuf, sysroot_src_dir: AbsPathBuf) -> Result<Sysroot> {
+        let mut sysroot =
+            Sysroot { root: sysroot_dir, src_root: sysroot_src_dir, crates: Arena::default() };
 
         for path in SYSROOT_CRATES.trim().lines() {
             let name = path.split('/').last().unwrap();
             let root = [format!("{}/src/lib.rs", path), format!("lib{}/lib.rs", path)]
                 .into_iter()
-                .map(|it| sysroot.root.join(it))
+                .map(|it| sysroot.src_root.join(it))
                 .filter_map(|it| ManifestPath::try_from(it).ok())
                 .find(|it| fs::metadata(it).is_ok());
 
@@ -119,7 +130,7 @@ pub fn load(sysroot_src_dir: AbsPathBuf) -> Result<Sysroot> {
             };
             anyhow::bail!(
                 "could not find libcore in sysroot path `{}`{}",
-                sysroot.root.as_path().display(),
+                sysroot.src_root.as_path().display(),
                 var_note,
             );
         }
index ddfea0ce4c4f1af0f188cdb83b984790a7802342..e304a59c0180bf7ef9c38e8f6269c35f4c167973 100644 (file)
@@ -75,8 +75,11 @@ fn get_test_path(file: &str) -> PathBuf {
 
 fn get_fake_sysroot() -> Sysroot {
     let sysroot_path = get_test_path("fake-sysroot");
-    let sysroot_src_dir = AbsPathBuf::assert(sysroot_path);
-    Sysroot::load(sysroot_src_dir).unwrap()
+    // there's no `libexec/` directory with a `proc-macro-srv` binary in that
+    // fake sysroot, so we give them both the same path:
+    let sysroot_dir = AbsPathBuf::assert(sysroot_path);
+    let sysroot_src_dir = sysroot_dir.clone();
+    Sysroot::load(sysroot_dir, sysroot_src_dir).unwrap()
 }
 
 fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
index de42458354566f481b944db43b753c2328c3cefd..63882466fa4162db8645b79e9576c76eaee0bff4 100644 (file)
@@ -230,8 +230,14 @@ pub fn load_inline(
         project_json: ProjectJson,
         target: Option<&str>,
     ) -> Result<ProjectWorkspace> {
-        let sysroot = match &project_json.sysroot_src {
-            Some(path) => Some(Sysroot::load(path.clone())?),
+        let sysroot = match project_json.sysroot_src.clone() {
+            Some(sysroot_src) => {
+                // if `sysroot` isn't specified (only `sysroot_src`), we won't have
+                // a real sysroot path, that's fine. it's just used to discover
+                // the standalone `proc-macro-srv` binary.
+                let sysroot = project_json.sysroot.clone().unwrap_or_else(|| sysroot_src.clone());
+                Some(Sysroot::load(sysroot, sysroot_src)?)
+            }
             None => None,
         };
         let rustc_cfg = rustc_cfg::get(None, target);
@@ -345,7 +351,7 @@ pub fn to_roots(&self) -> Vec<PackageRoot> {
                     })
                     .chain(sysroot.iter().map(|sysroot| PackageRoot {
                         is_local: false,
-                        include: vec![sysroot.root().to_path_buf()],
+                        include: vec![sysroot.src_root().to_path_buf()],
                         exclude: Vec::new(),
                     }))
                     .chain(rustc.iter().flat_map(|rustc| {
index e5802773e74739168bc7b68e94a0d6cd2ba9daa6..4256c2a764a33227ff54ecdb9811279a0ba0ae49 100644 (file)
@@ -305,8 +305,34 @@ fn eq_ignore_build_data<'a>(
 
         if self.proc_macro_clients.is_empty() {
             if let Some((path, args)) = self.config.proc_macro_srv() {
-                self.proc_macro_clients = (0..self.workspaces.len())
-                    .map(|_| {
+                self.proc_macro_clients = self
+                    .workspaces
+                    .iter()
+                    .map(|ws| {
+                        let mut path = path.clone();
+                        if let ProjectWorkspace::Cargo { sysroot, .. } = ws {
+                            tracing::info!("Found a cargo workspace...");
+                            if let Some(sysroot) = sysroot.as_ref() {
+                                tracing::info!("Found a cargo workspace with a sysroot...");
+                                let server_path = sysroot
+                                    .root()
+                                    .join("libexec")
+                                    .join("rust-analyzer-proc-macro-srv");
+                                if std::fs::metadata(&server_path).is_ok() {
+                                    tracing::info!(
+                                        "And the server exists at {}",
+                                        server_path.display()
+                                    );
+                                    path = server_path;
+                                } else {
+                                    tracing::info!(
+                                        "And the server does not exist at {}",
+                                        server_path.display()
+                                    );
+                                }
+                            }
+                        }
+
                         ProcMacroServer::spawn(path.clone(), args.clone()).map_err(|err| {
                             let error = format!(
                                 "Failed to run proc_macro_srv from path {}, error: {:?}",