Skip to content

Commit 4f79199

Browse files
author
Paolo Tranquilli
committed
Rust: replace std::fs::canonicalize with dunce::canonicalize
Rust-analyzer turned out to be quite picky about paths, where `//?/`-prefixed paths can lead to flaky failures. See rust-lang/rust-analyzer#18894 for details. This makes paths always be canonicalized with `dunce`. Previously, `dunce` was used as a fallback, but that stopped working somewhere after version 0.0.248 of rust-analyzer.
1 parent cd95cc8 commit 4f79199

File tree

2 files changed

+9
-25
lines changed

2 files changed

+9
-25
lines changed

rust/extractor/src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,10 @@ fn main() -> anyhow::Result<()> {
183183
.iter()
184184
.map(|file| {
185185
let file = std::path::absolute(file).unwrap_or(file.to_path_buf());
186-
std::fs::canonicalize(&file).unwrap_or(file)
186+
// On Windows, rust analyzer expects non-`//?/` prefixed paths (see [1]), which is what
187+
// `std::fs::canonicalize` returns. So we use `dunce::canonicalize` instead.
188+
// [1]: https://github.com/rust-lang/rust-analyzer/issues/18894#issuecomment-2580014730
189+
dunce::canonicalize(&file).unwrap_or(file)
187190
})
188191
.collect();
189192
let manifests = rust_analyzer::find_project_manifests(&files)?;

rust/extractor/src/rust_analyzer.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use ra_ap_vfs::Vfs;
1717
use ra_ap_vfs::VfsPath;
1818
use ra_ap_vfs::{AbsPathBuf, FileId};
1919
use std::borrow::Cow;
20-
use std::iter;
2120
use std::path::{Path, PathBuf};
2221
use triomphe::Arc;
2322

@@ -189,28 +188,10 @@ fn from_utf8_lossy(v: &[u8]) -> (Cow<'_, str>, Option<SyntaxError>) {
189188
(Cow::Owned(res), Some(error))
190189
}
191190

192-
fn canonicalize_if_on_windows(path: &Path) -> Option<PathBuf> {
193-
if cfg!(windows) {
194-
dunce::canonicalize(path).ok()
195-
} else {
196-
None
197-
}
198-
}
199-
200191
pub(crate) fn path_to_file_id(path: &Path, vfs: &Vfs) -> Option<FileId> {
201-
// There seems to be some flaky inconsistencies around paths on Windows, where sometimes paths
202-
// are registered in `vfs` without the `//?/` long path prefix. Then it happens that paths with
203-
// that prefix are not found. To work around that, on Windows after failing to find `path` as
204-
// is, we then try to canonicalize it using dunce. Dunce will be able to losslessly convert a
205-
// `//?/` path into its equivalent one in `vfs` without the prefix, if there is one.
206-
iter::once(path.to_path_buf())
207-
.chain(canonicalize_if_on_windows(path))
208-
.filter_map(|p| {
209-
Utf8PathBuf::from_path_buf(p)
210-
.ok()
211-
.and_then(|x| AbsPathBuf::try_from(x).ok())
212-
.map(VfsPath::from)
213-
.and_then(|x| vfs.file_id(&x))
214-
})
215-
.next()
192+
Utf8PathBuf::from_path_buf(path.to_path_buf())
193+
.ok()
194+
.and_then(|x| AbsPathBuf::try_from(x).ok())
195+
.map(VfsPath::from)
196+
.and_then(|x| vfs.file_id(&x))
216197
}

0 commit comments

Comments
 (0)