fix(path): clarify error message when path dependency has wrong package#16927
fix(path): clarify error message when path dependency has wrong package#16927raushan728 wants to merge 2 commits intorust-lang:masterfrom
Conversation
|
r? @epage rustbot has assigned @epage. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| crate::sources::RecursivePathSource::new(&path, dep.source_id(), gctx); | ||
|
|
||
| if let Ok(packages) = src.read_packages() { | ||
| if !packages.is_empty() { |
There was a problem hiding this comment.
This is pretty deeply nested. I wonder if there is a better path for this.
There was a problem hiding this comment.
This nesting has been refactored the logic is now extracted into a
standalone helper function activation_error_path_hints which returns
early with false for each guard condition, eliminating the deep nesting.
The call site in activation_error is now a single line.
| for pkg in &packages { | ||
| let p_name = pkg.name().as_str(); | ||
| if p_name == dep.package_name().as_str() { | ||
| let _ = writeln!( |
There was a problem hiding this comment.
Should we be consistent in where we write the hints?
There was a problem hiding this comment.
all hints now consistently written to hints buffer only
There was a problem hiding this comment.
That wasn't what I meant. You have a loop for searching for items. In some cases it directly creates the hint and in some it handles it afterwards.
There was a problem hiding this comment.
Fixed - the loop now only collects data (exact_match, found_dir,
names_found) and all hints are written after the loop ends.
| pub fn load(&self) -> CargoResult<()> { | ||
| let mut package = self.package.borrow_mut(); | ||
| if package.is_none() { | ||
| if !self.path.join("Cargo.toml").exists() { |
There was a problem hiding this comment.
It was an earlier attempt to handle missing Cargo.toml - reverted because it was too broad and broke existing tests. Now i use typed error detection in registry.rs
There was a problem hiding this comment.
From #16927 (comment)
Note for reviewers: The change in
registry.rsis needed to handle case 2 and case 3 (wherebar/exists as a directory but has noCargo.toml). Without it the IO error fires before the resolver reachesactivation_error_path_hints. The suppression is guarded by three conditions: path source, typedManifestErrorwithNotFound, andhas_nearby_manifestsconfirming subdirectory packages exist.
| if s.is_empty() { | ||
| s.push('.'); | ||
| } | ||
| if !s.ends_with('/') { |
There was a problem hiding this comment.
use file_name() to show the actual directory name (e.g. foo/) instead of ./ when the path equals the parent root
There was a problem hiding this comment.
That isn't a complete sentence, making it harder to follow what you mean. I don't see how a file_name() (which?) even fits into this.
There was a problem hiding this comment.
When path == parent_root, strip_prefix returns an empty string. In that case we fall back to path.file_name() to show the directory name (e.g. foo/) rather than an empty or confusing path
| is_handled_custom_path_error = true; | ||
| let _ = writeln!( | ||
| &mut msg, | ||
| "no matching package named `{}` found at `{}`\nnote: required by {}", |
There was a problem hiding this comment.
This adds a note on only this "required by",
Either we want this generally and a commit before this should add it or we should remove thisd
There was a problem hiding this comment.
Looks like this was resolved by dropping the note:?
There was a problem hiding this comment.
Yes, resolved by dropping the note: prefix.
|
Note for reviewers: The change in |
| } else { | ||
| let _ = writeln!( | ||
| &mut msg, | ||
| "no matching package named `{}` found", | ||
| dep.package_name() | ||
| ); | ||
| } |
There was a problem hiding this comment.
This change involves a refactor where more things are put into the else branch, If this is kept, I'd recommend splitting that out into its own commit.
There was a problem hiding this comment.
the else branch restructuring is gone since we switched to the else if let Some(packages) = alt_paths(dep, gctx) pattern.
| let mut location_searched_msg = registry.describe_source(dep.source_id()); | ||
| if location_searched_msg.is_empty() { | ||
| location_searched_msg = format!("{}", dep.source_id()); | ||
| if !is_handled_custom_path_error { |
There was a problem hiding this comment.
We have two if !is_handled_custom_path_error in a row. Is there a reason these aren't merged and we just get rid of is_handled_custom_path_error?
There was a problem hiding this comment.
The two consecutive blocks are merged into one. The flag itself is still needed - location searched must appear for !candidates.is_empty() too.
| } else { | ||
| if activation_error_path_hints(dep, parent, gctx, resolver_ctx, &mut msg, &mut hints) { |
There was a problem hiding this comment.
If you make a function just for getting the recursive path source packages, you can keep the existing else-if pattern by having an } else if let Some(path_packages) = alt_paths(...)? { which I think will make this a bit cleaner / easier to follow
There was a problem hiding this comment.
Fixed - extracted alt_paths() function and using
} else if let Some(packages) = alt_paths(dep, gctx) { pattern.
| let res = source.query(dep, kind, f).await; | ||
| if let Err(e) = &res { | ||
| if dep.source_id().is_path() | ||
| && crate::core::resolver::errors::is_manifest_not_found(e) | ||
| && has_nearby_manifests(dep) | ||
| { | ||
| return Ok(()); | ||
| } | ||
| } | ||
| res.with_context(|| format!("unable to update {}", source.source_id())) |
There was a problem hiding this comment.
This has really ballooned in complexity, including the idea of "catching" specific errors.
There was a problem hiding this comment.
The registry.rs change was needed because without it, the IO error fires before the resolver reaches the diagnostic code for cases 2/3.
Is there a cleaner way you'd suggest to intercept this early failure so we can still provide helpful hints for those cases? Happy to rework the approach if you have a better path in mind.
d4eb6f0 to
d5f8d89
Compare
…ge (rust-lang#15296) When a path dependency points to a directory with a different package, show which package exists there and where the correct one can be found.
|
Regarding |
View all comments
Fixes #15296
When a path dependency specifies a package name that doesn't match what's
found at that path, Cargo now shows helpful hints about what packages exist
nearby instead of the confusing "location searched" message.