From 154cb8243b4212fddf73b3b3c48b5f5e8a712876 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 24 Jun 2020 13:34:24 +0200 Subject: Be more explicit about absolute paths at various places --- crates/paths/src/lib.rs | 26 ++++++++++-- crates/ra_project_model/Cargo.toml | 1 + crates/ra_project_model/src/cargo_workspace.rs | 42 ++++++++++--------- crates/ra_project_model/src/lib.rs | 51 +++++++++++------------ crates/ra_project_model/src/sysroot.rs | 23 +++++----- crates/rust-analyzer/src/bin/main.rs | 37 +++++++++------- crates/rust-analyzer/src/cli/load_cargo.rs | 2 +- crates/rust-analyzer/src/config.rs | 22 +++++----- crates/rust-analyzer/src/global_state.rs | 7 ++-- crates/rust-analyzer/tests/heavy_tests/support.rs | 8 ++-- 10 files changed, 125 insertions(+), 94 deletions(-) (limited to 'crates') diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs index 45b19c45a..1b259682d 100644 --- a/crates/paths/src/lib.rs +++ b/crates/paths/src/lib.rs @@ -28,6 +28,12 @@ impl AsRef for AbsPathBuf { } } +impl AsRef for AbsPathBuf { + fn as_ref(&self) -> &AbsPath { + self.as_path() + } +} + impl TryFrom for AbsPathBuf { type Error = PathBuf; fn try_from(path_buf: PathBuf) -> Result { @@ -45,9 +51,19 @@ impl TryFrom<&str> for AbsPathBuf { } } +impl PartialEq for AbsPathBuf { + fn eq(&self, other: &AbsPath) -> bool { + self.as_path() == other + } +} + impl AbsPathBuf { + pub fn assert(path: PathBuf) -> AbsPathBuf { + AbsPathBuf::try_from(path) + .unwrap_or_else(|path| panic!("expected absolute path, got {}", path.display())) + } pub fn as_path(&self) -> &AbsPath { - AbsPath::new_unchecked(self.0.as_path()) + AbsPath::assert(self.0.as_path()) } pub fn pop(&mut self) -> bool { self.0.pop() @@ -77,15 +93,19 @@ impl<'a> TryFrom<&'a Path> for &'a AbsPath { if !path.is_absolute() { return Err(path); } - Ok(AbsPath::new_unchecked(path)) + Ok(AbsPath::assert(path)) } } impl AbsPath { - fn new_unchecked(path: &Path) -> &AbsPath { + pub fn assert(path: &Path) -> &AbsPath { + assert!(path.is_absolute()); unsafe { &*(path as *const Path as *const AbsPath) } } + pub fn parent(&self) -> Option<&AbsPath> { + self.0.parent().map(AbsPath::assert) + } pub fn join(&self, path: impl AsRef) -> AbsPathBuf { self.as_ref().join(path).try_into().unwrap() } diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index e4a60f4c0..818947014 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -18,6 +18,7 @@ ra_cfg = { path = "../ra_cfg" } ra_db = { path = "../ra_db" } ra_toolchain = { path = "../ra_toolchain" } ra_proc_macro = { path = "../ra_proc_macro" } +paths = { path = "../paths" } serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.48" diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 4b7444039..8ce63ab3c 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -1,14 +1,10 @@ //! FIXME: write short doc here -use std::{ - ffi::OsStr, - ops, - path::{Path, PathBuf}, - process::Command, -}; +use std::{ffi::OsStr, ops, path::Path, process::Command}; use anyhow::{Context, Result}; use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId}; +use paths::{AbsPath, AbsPathBuf}; use ra_arena::{Arena, Idx}; use ra_db::Edition; use rustc_hash::FxHashMap; @@ -20,11 +16,14 @@ use rustc_hash::FxHashMap; /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, /// while this knows about `Packages` & `Targets`: purely cargo-related /// concepts. +/// +/// We use absolute paths here, `cargo metadata` guarantees to always produce +/// abs paths. #[derive(Debug, Clone)] pub struct CargoWorkspace { packages: Arena, targets: Arena, - workspace_root: PathBuf, + workspace_root: AbsPathBuf, } impl ops::Index for CargoWorkspace { @@ -80,15 +79,15 @@ pub type Target = Idx; pub struct PackageData { pub version: String, pub name: String, - pub manifest: PathBuf, + pub manifest: AbsPathBuf, pub targets: Vec, pub is_member: bool, pub dependencies: Vec, pub edition: Edition, pub features: Vec, pub cfgs: Vec, - pub out_dir: Option, - pub proc_macro_dylib_path: Option, + pub out_dir: Option, + pub proc_macro_dylib_path: Option, } #[derive(Debug, Clone)] @@ -101,7 +100,7 @@ pub struct PackageDependency { pub struct TargetData { pub package: Package, pub name: String, - pub root: PathBuf, + pub root: AbsPathBuf, pub kind: TargetKind, pub is_proc_macro: bool, } @@ -135,7 +134,7 @@ impl TargetKind { } impl PackageData { - pub fn root(&self) -> &Path { + pub fn root(&self) -> &AbsPath { self.manifest.parent().unwrap() } } @@ -193,7 +192,7 @@ impl CargoWorkspace { let pkg = packages.alloc(PackageData { name, version: version.to_string(), - manifest: manifest_path, + manifest: AbsPathBuf::assert(manifest_path), targets: Vec::new(), is_member, edition, @@ -210,7 +209,7 @@ impl CargoWorkspace { let tgt = targets.alloc(TargetData { package: pkg, name: meta_tgt.name, - root: meta_tgt.src_path.clone(), + root: AbsPathBuf::assert(meta_tgt.src_path.clone()), kind: TargetKind::new(meta_tgt.kind.as_slice()), is_proc_macro, }); @@ -246,16 +245,17 @@ impl CargoWorkspace { packages[source].features.extend(node.features); } - Ok(CargoWorkspace { packages, targets, workspace_root: meta.workspace_root }) + let workspace_root = AbsPathBuf::assert(meta.workspace_root); + Ok(CargoWorkspace { packages, targets, workspace_root: workspace_root }) } pub fn packages<'a>(&'a self) -> impl Iterator + ExactSizeIterator + 'a { self.packages.iter().map(|(id, _pkg)| id) } - pub fn target_by_root(&self, root: &Path) -> Option { + pub fn target_by_root(&self, root: &AbsPath) -> Option { self.packages() - .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root)) + .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| &self[it].root == root)) .next() .copied() } @@ -279,8 +279,8 @@ impl CargoWorkspace { #[derive(Debug, Clone, Default)] pub struct ExternResources { - out_dirs: FxHashMap, - proc_dylib_paths: FxHashMap, + out_dirs: FxHashMap, + proc_dylib_paths: FxHashMap, cfgs: FxHashMap>, } @@ -308,6 +308,7 @@ pub fn load_extern_resources( if let Ok(message) = message { match message { Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => { + let out_dir = AbsPathBuf::assert(out_dir); res.out_dirs.insert(package_id.clone(), out_dir); res.cfgs.insert(package_id, cfgs); } @@ -317,7 +318,8 @@ pub fn load_extern_resources( // Skip rmeta file if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name)) { - res.proc_dylib_paths.insert(package_id, filename.clone()); + let filename = AbsPathBuf::assert(filename.clone()); + res.proc_dylib_paths.insert(package_id, filename); } } } diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index fe3e81689..ac88532f0 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -7,11 +7,12 @@ mod sysroot; use std::{ fs::{read_dir, File, ReadDir}, io::{self, BufReader}, - path::{Path, PathBuf}, + path::Path, process::{Command, Output}, }; use anyhow::{bail, Context, Result}; +use paths::{AbsPath, AbsPathBuf}; use ra_cfg::CfgOptions; use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -29,7 +30,7 @@ pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, /// Project workspace was manually specified using a `rust-project.json` file. - Json { project: JsonProject, project_location: PathBuf }, + Json { project: JsonProject, project_location: AbsPathBuf }, } /// `PackageRoot` describes a package root folder. @@ -38,22 +39,22 @@ pub enum ProjectWorkspace { #[derive(Debug, Clone)] pub struct PackageRoot { /// Path to the root folder - path: PathBuf, + path: AbsPathBuf, /// Is a member of the current workspace is_member: bool, - out_dir: Option, + out_dir: Option, } impl PackageRoot { - pub fn new_member(path: PathBuf) -> PackageRoot { + pub fn new_member(path: AbsPathBuf) -> PackageRoot { Self { path, is_member: true, out_dir: None } } - pub fn new_non_member(path: PathBuf) -> PackageRoot { + pub fn new_non_member(path: AbsPathBuf) -> PackageRoot { Self { path, is_member: false, out_dir: None } } - pub fn path(&self) -> &Path { + pub fn path(&self) -> &AbsPath { &self.path } - pub fn out_dir(&self) -> Option<&Path> { + pub fn out_dir(&self) -> Option<&AbsPath> { self.out_dir.as_deref() } pub fn is_member(&self) -> bool { @@ -63,12 +64,12 @@ impl PackageRoot { #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] pub enum ProjectManifest { - ProjectJson(PathBuf), - CargoToml(PathBuf), + ProjectJson(AbsPathBuf), + CargoToml(AbsPathBuf), } impl ProjectManifest { - pub fn from_manifest_file(path: PathBuf) -> Result { + pub fn from_manifest_file(path: AbsPathBuf) -> Result { if path.ends_with("rust-project.json") { return Ok(ProjectManifest::ProjectJson(path)); } @@ -78,7 +79,7 @@ impl ProjectManifest { bail!("project root must point to Cargo.toml or rust-project.json: {}", path.display()) } - pub fn discover_single(path: &Path) -> Result { + pub fn discover_single(path: &AbsPath) -> Result { let mut candidates = ProjectManifest::discover(path)?; let res = match candidates.pop() { None => bail!("no projects"), @@ -91,23 +92,23 @@ impl ProjectManifest { Ok(res) } - pub fn discover(path: &Path) -> io::Result> { + pub fn discover(path: &AbsPath) -> io::Result> { if let Some(project_json) = find_in_parent_dirs(path, "rust-project.json") { return Ok(vec![ProjectManifest::ProjectJson(project_json)]); } return find_cargo_toml(path) .map(|paths| paths.into_iter().map(ProjectManifest::CargoToml).collect()); - fn find_cargo_toml(path: &Path) -> io::Result> { + fn find_cargo_toml(path: &AbsPath) -> io::Result> { match find_in_parent_dirs(path, "Cargo.toml") { Some(it) => Ok(vec![it]), None => Ok(find_cargo_toml_in_child_dir(read_dir(path)?)), } } - fn find_in_parent_dirs(path: &Path, target_file_name: &str) -> Option { + fn find_in_parent_dirs(path: &AbsPath, target_file_name: &str) -> Option { if path.ends_with(target_file_name) { - return Some(path.to_owned()); + return Some(path.to_path_buf()); } let mut curr = Some(path); @@ -123,17 +124,18 @@ impl ProjectManifest { None } - fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec { + fn find_cargo_toml_in_child_dir(entities: ReadDir) -> Vec { // Only one level down to avoid cycles the easy way and stop a runaway scan with large projects entities .filter_map(Result::ok) .map(|it| it.path().join("Cargo.toml")) .filter(|it| it.exists()) + .map(AbsPathBuf::assert) .collect() } } - pub fn discover_all(paths: &[impl AsRef]) -> Vec { + pub fn discover_all(paths: &[impl AsRef]) -> Vec { let mut res = paths .iter() .filter_map(|it| ProjectManifest::discover(it.as_ref()).ok()) @@ -158,15 +160,12 @@ impl ProjectWorkspace { format!("Failed to open json file {}", project_json.display()) })?; let reader = BufReader::new(file); - let project_location = match project_json.parent() { - Some(parent) => PathBuf::from(parent), - None => PathBuf::new(), - }; + let project_location = project_json.parent().unwrap().to_path_buf(); ProjectWorkspace::Json { project: from_reader(reader).with_context(|| { format!("Failed to deserialize json file {}", project_json.display()) })?, - project_location: project_location, + project_location, } } ProjectManifest::CargoToml(cargo_toml) => { @@ -218,13 +217,13 @@ impl ProjectWorkspace { } } - pub fn proc_macro_dylib_paths(&self) -> Vec { + pub fn proc_macro_dylib_paths(&self) -> Vec { match self { - ProjectWorkspace::Json { project, .. } => project + ProjectWorkspace::Json { project, project_location } => project .crates .iter() .filter_map(|krate| krate.proc_macro_dylib_path.as_ref()) - .cloned() + .map(|it| project_location.join(it)) .collect(), ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo .packages() diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index a8a196e64..943ff92df 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs @@ -1,15 +1,12 @@ //! FIXME: write short doc here -use std::{ - env, ops, - path::{Path, PathBuf}, - process::Command, -}; +use std::{convert::TryFrom, env, ops, path::Path, process::Command}; -use anyhow::{bail, Result}; +use anyhow::{bail, format_err, Result}; use ra_arena::{Arena, Idx}; use crate::output; +use paths::{AbsPath, AbsPathBuf}; #[derive(Default, Debug, Clone)] pub struct Sysroot { @@ -21,7 +18,7 @@ pub type SysrootCrate = Idx; #[derive(Debug, Clone)] pub struct SysrootCrateData { pub name: String, - pub root: PathBuf, + pub root: AbsPathBuf, pub deps: Vec, } @@ -53,7 +50,7 @@ impl Sysroot { self.crates.iter().map(|(id, _data)| id) } - pub fn discover(cargo_toml: &Path) -> Result { + pub fn discover(cargo_toml: &AbsPath) -> Result { let src = get_or_install_rust_src(cargo_toml)?; let mut sysroot = Sysroot { crates: Arena::default() }; for name in SYSROOT_CRATES.trim().lines() { @@ -86,16 +83,18 @@ impl Sysroot { } } -fn get_or_install_rust_src(cargo_toml: &Path) -> Result { +fn get_or_install_rust_src(cargo_toml: &AbsPath) -> Result { if let Ok(path) = env::var("RUST_SRC_PATH") { - return Ok(path.into()); + let path = AbsPathBuf::try_from(path.as_str()) + .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?; + return Ok(path); } let current_dir = cargo_toml.parent().unwrap(); let mut rustc = Command::new(ra_toolchain::rustc()); rustc.current_dir(current_dir).args(&["--print", "sysroot"]); let rustc_output = output(rustc)?; let stdout = String::from_utf8(rustc_output.stdout)?; - let sysroot_path = Path::new(stdout.trim()); + let sysroot_path = AbsPath::assert(Path::new(stdout.trim())); let src_path = sysroot_path.join("lib/rustlib/src/rust/src"); if !src_path.exists() { @@ -116,7 +115,7 @@ fn get_or_install_rust_src(cargo_toml: &Path) -> Result { } impl SysrootCrateData { - pub fn root_dir(&self) -> &Path { + pub fn root_dir(&self) -> &AbsPath { self.root.parent().unwrap() } } diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 99e3f7173..45204d1a3 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -3,6 +3,8 @@ //! Based on cli flags, either spawns an LSP server, or runs a batch analysis mod args; +use std::convert::TryFrom; + use lsp_server::Connection; use rust_analyzer::{ cli, @@ -10,9 +12,11 @@ use rust_analyzer::{ from_json, Result, }; -use crate::args::HelpPrinted; +use ra_db::AbsPathBuf; use ra_project_model::ProjectManifest; +use crate::args::HelpPrinted; + fn main() -> Result<()> { setup_logging()?; let args = match args::Args::parse()? { @@ -20,6 +24,9 @@ fn main() -> Result<()> { Err(HelpPrinted) => return Ok(()), }; match args.command { + args::Command::RunServer => run_server()?, + args::Command::ProcMacro => ra_proc_macro_srv::cli::run()?, + args::Command::Parse { no_dump } => cli::parse(no_dump)?, args::Command::Symbols => cli::symbols()?, args::Command::Highlight { rainbow } => cli::highlight(rainbow)?, @@ -41,7 +48,6 @@ fn main() -> Result<()> { load_output_dirs, with_proc_macro, )?, - args::Command::Bench { path, what, load_output_dirs, with_proc_macro } => { cli::analysis_bench( args.verbosity, @@ -51,13 +57,9 @@ fn main() -> Result<()> { with_proc_macro, )? } - args::Command::Diagnostics { path, load_output_dirs, with_proc_macro, all } => { cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)? } - - args::Command::ProcMacro => run_proc_macro_srv()?, - args::Command::RunServer => run_server()?, args::Command::Version => println!("rust-analyzer {}", env!("REV")), } Ok(()) @@ -70,11 +72,6 @@ fn setup_logging() -> Result<()> { Ok(()) } -fn run_proc_macro_srv() -> Result<()> { - ra_proc_macro_srv::cli::run()?; - Ok(()) -} - fn run_server() -> Result<()> { log::info!("lifecycle: server started"); @@ -103,14 +100,23 @@ fn run_server() -> Result<()> { } let config = { - let mut config = Config::default(); + let root_path = match initialize_params + .root_uri + .and_then(|it| it.to_file_path().ok()) + .and_then(|it| AbsPathBuf::try_from(it).ok()) + { + Some(it) => it, + None => { + let cwd = std::env::current_dir()?; + AbsPathBuf::assert(cwd) + } + }; + + let mut config = Config::new(root_path); if let Some(value) = &initialize_params.initialization_options { config.update(value); } config.update_caps(&initialize_params.capabilities); - let cwd = std::env::current_dir()?; - config.root_path = - initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); if config.linked_projects.is_empty() { let workspace_roots = initialize_params @@ -119,6 +125,7 @@ fn run_server() -> Result<()> { workspaces .into_iter() .filter_map(|it| it.uri.to_file_path().ok()) + .filter_map(|it| AbsPathBuf::try_from(it).ok()) .collect::>() }) .filter(|workspaces| !workspaces.is_empty()) diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 00bbbaf40..e910db6eb 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -16,7 +16,7 @@ pub fn load_cargo( load_out_dirs_from_check: bool, with_proc_macro: bool, ) -> Result<(AnalysisHost, vfs::Vfs)> { - let root = std::env::current_dir()?.join(root); + let root = AbsPathBuf::assert(std::env::current_dir()?.join(root)); let root = ProjectManifest::discover_single(&root)?; let ws = ProjectWorkspace::load( root, diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index aa2c4ae15..0be34c43f 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -11,6 +11,7 @@ use std::{ffi::OsString, path::PathBuf}; use crate::diagnostics::DiagnosticsConfig; use lsp_types::ClientCapabilities; +use ra_db::AbsPathBuf; use ra_flycheck::FlycheckConfig; use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig}; use ra_project_model::{CargoConfig, JsonProject, ProjectManifest}; @@ -40,7 +41,7 @@ pub struct Config { pub with_sysroot: bool, pub linked_projects: Vec, - pub root_path: PathBuf, + pub root_path: AbsPathBuf, } #[derive(Debug, Clone)] @@ -131,8 +132,8 @@ pub struct ClientCapsConfig { pub hover_actions: bool, } -impl Default for Config { - fn default() -> Self { +impl Config { + pub fn new(root_path: AbsPathBuf) -> Self { Config { client_caps: ClientCapsConfig::default(), @@ -171,18 +172,16 @@ impl Default for Config { lens: LensConfig::default(), hover: HoverConfig::default(), linked_projects: Vec::new(), - root_path: PathBuf::new(), + root_path, } } -} -impl Config { #[rustfmt::skip] pub fn update(&mut self, value: &serde_json::Value) { log::info!("Config::update({:#})", value); let client_caps = self.client_caps.clone(); - *self = Default::default(); + *self = Config::new(self.root_path.clone()); self.client_caps = client_caps; set(value, "/withSysroot", &mut self.with_sysroot); @@ -279,9 +278,12 @@ impl Config { self.linked_projects.clear(); for linked_project in linked_projects { let linked_project = match linked_project { - ManifestOrJsonProject::Manifest(it) => match ProjectManifest::from_manifest_file(it) { - Ok(it) => it.into(), - Err(_) => continue, + ManifestOrJsonProject::Manifest(it) => { + let path = self.root_path.join(it); + match ProjectManifest::from_manifest_file(path) { + Ok(it) => it.into(), + Err(_) => continue, + } } ManifestOrJsonProject::JsonProject(it) => it.into(), }; diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index e2ddb7933..f18694feb 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -310,11 +310,10 @@ impl ProjectFolders { let mut file_set_roots: Vec = vec![]; - let path = AbsPathBuf::try_from(path).unwrap(); let entry = if root.is_member() { - vfs::loader::Entry::local_cargo_package(path.clone()) + vfs::loader::Entry::local_cargo_package(path.to_path_buf()) } else { - vfs::loader::Entry::cargo_package_dependency(path.clone()) + vfs::loader::Entry::cargo_package_dependency(path.to_path_buf()) }; res.load.push(entry); if root.is_member() { @@ -329,7 +328,7 @@ impl ProjectFolders { } file_set_roots.push(out_dir.into()); } - file_set_roots.push(path.into()); + file_set_roots.push(path.to_path_buf().into()); if root.is_member() { local_filesets.push(fsc.len()); diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index 8d88f992d..49f194f7e 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs @@ -17,6 +17,7 @@ use serde_json::{to_string_pretty, Value}; use tempfile::TempDir; use test_utils::{find_mismatch, Fixture}; +use ra_db::AbsPathBuf; use ra_project_model::ProjectManifest; use rust_analyzer::{ config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject}, @@ -70,10 +71,11 @@ impl<'a> Project<'a> { fs::write(path.as_path(), entry.text.as_bytes()).unwrap(); } + let tmp_dir_path = AbsPathBuf::assert(tmp_dir.path().to_path_buf()); let mut roots = - self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect::>(); + self.roots.into_iter().map(|root| tmp_dir_path.join(root)).collect::>(); if roots.is_empty() { - roots.push(tmp_dir.path().to_path_buf()); + roots.push(tmp_dir_path.clone()); } let linked_projects = roots .into_iter() @@ -91,7 +93,7 @@ impl<'a> Project<'a> { with_sysroot: self.with_sysroot, linked_projects, files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() }, - ..Config::default() + ..Config::new(tmp_dir_path) }; if let Some(f) = &self.config { f(&mut config) -- cgit v1.2.3