Closed w93163red closed 2 years ago
Note that the issue is unactionable (impossible to fix) given the provided information.
See https://rust-analyzer.github.io/manual.html#troubleshooting for how to debug such problems.
@matklad Sorry for the unclear info! I have updated the info accordingly.
I think I found the commit that introduced the same issue for me at least. with 980a67f44629ed67a54b603aaf9d015a81d61f7a completions seemingly work in every file in my workspace, with 69b79e3a73f9a1b820cf6d5ebc9968d8b08d4e68 completion breaks in at least one file.
I suspect https://github.com/rust-analyzer/rust-analyzer/blob/69b79e3a73f9a1b820cf6d5ebc9968d8b08d4e68/crates/vfs/src/file_set.rs#L72-L82 is the cause of this, taking a long time for some things, not sure how to prove it though. Guidance for troubleshooting would be happily accepted :)
ra client
```
INFO [7/25/2020, 3:03:44 AM]: Extension version: 0.4.0-dev
INFO [7/25/2020, 3:03:44 AM]: Using configuration {
diagnostics: { enable: true, warningsAsInfo: [], warningsAsHint: [] },
lruCapacity: 30,
files: { watcher: 'client', exclude: [] },
notifications: { cargoTomlNotFound: true },
cargo: {
noDefaultFeatures: false,
allFeatures: false,
features: [],
loadOutDirsFromCheck: true,
target: null
},
rustfmt: { extraArgs: [], overrideCommand: null },
checkOnSave: {
enable: true,
extraArgs: [],
command: 'clippy',
overrideCommand: null,
allTargets: false,
allFeatures: null,
features: null
},
cargoRunner: null,
runnableEnv: null,
inlayHints: {
enable: true,
typeHints: true,
chainingHints: false,
parameterHints: true,
maxLength: 20
},
completion: {
addCallParenthesis: true,
addCallArgumentSnippets: true,
postfix: { enable: true }
},
callInfo: { full: true },
updates: { channel: 'nightly', askBeforeDownload: true },
serverPath: 'C:/Users/Emil/.cargo/bin/rust-analyzer.exe',
trace: { server: 'verbose', extension: true },
procMacro: { enable: true },
debug: {
engine: 'auto',
sourceFileMap: {
'/rustc/
@Emilgardis interesting, see also https://github.com/rust-analyzer/rust-analyzer/pull/5252#issuecomment-656065453 which is older than https://github.com/rust-analyzer/rust-analyzer/commit/980a67f44629ed67a54b603aaf9d015a81d61f7a but related to https://github.com/rust-analyzer/rust-analyzer/commit/69b79e3a73f9a1b820cf6d5ebc9968d8b08d4e68.
@edwin0cheng do you still have historical data? I should have pasted a screenshot in my comment above.
After doing some more debugging, I'm starting to think the old implementation satisfied a condition not satisfied by the new implementation.
I reverted file_set.rs
only to the "bad-trie" implementation (which had completions working) , and did some eprintlns to check latency, but timing was pretty much the same. One difference though is the output, still checking on it but it does seem reverting it fixes the issue.
Changing FileSetConfig::partition
to
pub fn partition(&self, vfs: &Vfs) -> Vec<FileSet> {
let mut scratch_space = Vec::new();
let mut res = vec![FileSet::default(); self.len()];
eprintln!("Started partition:");
for (file_id, path) in vfs.iter() {
let root = self.classify(&path, &mut scratch_space);
eprintln!("\tidx = {} for {:?}", root, path);
res[root].insert(file_id, path.clone())
}
res
}
and doing the same to the "bad-trie" impl reveals the following difference (Note I've tried to anonymize the contents and removed noise)
So, crate-b\\src\\context\\mod.rs
(which is the file I'm trying to autocomplete in), gets misclassified as crate-a.
crate-b
is named foo-things
, and crate-a
is named foo
, if that is of any significance.
EDIT: Some more investigating, seems this error is only present on this file when the vs workspace loads up with it open in an editor. Closing the file in editor, making sure there's another workspace rs file in editor tabs, saving workspace layout (by closing vsc) and reopening workspace makes the file able to complete after opening it again.
So, the trace from original PR looks like the completion is legitimately cancelled by typing more stuff, and it seems like the client hadn't re-sent the request for some reason:
[Trace - 11:35:59 AM] Sending request 'textDocument/completion - (163)'.
[Trace - 11:35:59 AM] Sending notification 'textDocument/didChange'. <- this'll invalidate completions from the previous requests
[Trace - 11:35:59 AM] Received response 'textDocument/completion - (163)' in 93ms. Request failed: content modified (-32801). <- so that's why we cancel them
Although, produced no valid metatdata
sounds like there might be some project structure problems?
About @Emilgardis issue, not sure what's going on here. I've added the test for prefixed paths: https://github.com/rust-analyzer/rust-analyzer/pull/5537.
This is windows, so it could be that we don't normilize paths in the same way somewhere, especially for in-memory documents.
For both problems (which seem like they are different) having a minimal reproducible example would help.
@lnicola :
Oh, I forgot about the pagination links :facepalm:.
I'm not sure if related but I seems to have lost any analysis after the aforementioned commit as well. For example on this
use std::collections::XXX;
fn main() {
println!("Hello, world!");
}
won't give me diagnostics that use is incorrect. while it works perfectly fine when built from 980a67f works perfectly fine. However, this happens only if I set rust-analyzer.procMacro.enable to true.
@theli-ua see https://github.com/rust-analyzer/rust-analyzer/pull/5651 if you're using nightly.
@Emilgardis @matklad
This is windows, so it could be that we don't normalize paths in the same way somewhere
I think I've found a problem with the FileSet
partitioning: It seems that paths on Windows are entering RA with either uppercase or lowercase drive letters, not a problem, because Path
, AbsPath
, VfsPath
all handle that correctly and treat the drive letter case insensitive, but not so the VfsPath::encode
function that is used as a basis for partitioning the file sets: As soon the encode
function returns consistent results in regard to the drive letter casing, lots of Windows problems disappear, for example the module not found problem described in #5484. Here is a hack f0d511e6d0f65a1c6ee40b7ea3a2b57d76863022 that I am testing right now.
Indeed, I discovered this (but not that it mattered) as well but never got to implement it or report it as the error I was having seems to be gone for me now either way.
I implemented a fix for this stealing code from the path normalization in the ra path workspace crate, unfortunately though we need a unstable fearure to make the drive letter uppercase.
Excellent catch @pragmatrix ! Could you check if the following works for you?
// Don't make this `pub`
pub(crate) fn encode(&self, buf: &mut Vec<u8>) {
let tag = match &self.0 {
VfsPathRepr::PathBuf(_) => 0,
VfsPathRepr::VirtualPath(_) => 1,
};
buf.push(tag);
match &self.0 {
VfsPathRepr::PathBuf(path) => {
#[cfg(windows)]
{
use std::os::windows::ffi::OsStrExt;
for component in path.components() {
buf.push(b'\\');
for wchar in component.as_os_str().encode_wide() {
buf.extend(wchar.to_le_bytes().iter());
}
}
}
#[cfg(unix)]
{
use std::os::unix::ffi::OsStrExt;
let path: &std::ffi::OsStr = it.as_os_str();
buf.extend(path.as_bytes());
}
#[cfg(not(any(windows, unix)))]
{
let path: &std::ffi::OsStr = it.as_os_str();
buf.extend(path.to_string_lossy().as_bytes());
}
}
VfsPathRepr::VirtualPath(VirtualPath(s)) => buf.extend(s.as_bytes()),
}
}
I think components
should do normalization here: https://github.com/rust-lang/rust/blob/cee14d8c300feb2ac2a949848911bf4c3b143e70/library/std/src/sys/windows/path.rs#L61
VerbatimDisk
is uncommon, it should also be https://github.com/rust-lang/rust/blob/cee14d8c300feb2ac2a949848911bf4c3b143e70/library/std/src/sys/windows/path.rs#L86
I don't know why, but using the path components does not seem to change the drive letter, the same symptoms reappeared, here is a minimal test-case:
#[cfg(windows)]
#[test]
fn test_encode_consistency_on_windows() {
let p1 = VfsPath::from(AbsPathBuf::try_from("C:\\t").unwrap());
let p2 = VfsPath::from(AbsPathBuf::try_from("c:\\t").unwrap());
let mut buf1 = Vec::new();
let mut buf2 = Vec::new();
p1.encode(&mut buf1);
p2.encode(&mut buf2);
assert_eq!(buf1, buf2);
}
which fails:
thread 'vfs_path::test_encode_consistency_on_windows' panicked at 'assertion failed: `(left == right)`
left: `[0, 92, 67, 0, 58, 0, 92, 92, 0, 92, 116, 0]`,
right: `[0, 92, 99, 0, 58, 0, 92, 92, 0, 92, 116, 0]`', crates\vfs\src\vfs_path.rs:98:5
Is this still relevant? From the looks of it, #5756 implemented a fix to the mentioned problem here right?
I have not encountered this specific issue anymore. Other issues have been solved with multiple proc-macro abis and other fixes.
Im sure there are other cases but this specific one is solved imo
Then let's close this, if it pops up again for anyone it should go into a new issue.
Ra Version:
Ra Log:![image](https://user-images.githubusercontent.com/7308728/88073888-b5691980-cb44-11ea-8dc6-21935a25bf08.png)
Verbose log: https://gist.github.com/w93163red/fb1709102d88916ae4ce0ff0337cf5da