Skip to content

fix(path): clarify error message when path dependency has wrong package#16927

Open
raushan728 wants to merge 2 commits intorust-lang:masterfrom
raushan728:fix-15296
Open

fix(path): clarify error message when path dependency has wrong package#16927
raushan728 wants to merge 2 commits intorust-lang:masterfrom
raushan728:fix-15296

Conversation

@raushan728
Copy link
Copy Markdown
Contributor

@raushan728 raushan728 commented Apr 22, 2026

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.

@rustbot rustbot added A-dependency-resolution Area: dependency resolution and the resolver S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 22, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 22, 2026

r? @epage

rustbot has assigned @epage.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

Copy link
Copy Markdown
Contributor

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/sources/path.rs Outdated
pub fn load(&self) -> CargoResult<()> {
let mut package = self.package.borrow_mut();
if package.is_none() {
if !self.path.join("Cargo.toml").exists() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this added?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From #16927 (comment)

Note for reviewers: The change in registry.rs is needed to handle case 2 and case 3 (where bar/ exists as a directory but has no Cargo.toml). Without it the IO error fires before the resolver reaches activation_error_path_hints. The suppression is guarded by three conditions: path source, typed ManifestError with NotFound, and has_nearby_manifests confirming subdirectory packages exist.

Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread tests/testsuite/path.rs Outdated
@rustbot rustbot added the A-registries Area: registries label Apr 23, 2026
@raushan728

This comment has been minimized.

@raushan728 raushan728 requested a review from epage April 23, 2026 12:47
Comment thread src/cargo/core/resolver/errors.rs
Comment thread src/cargo/core/resolver/errors.rs
Comment thread src/cargo/core/resolver/errors.rs Outdated
Comment thread src/cargo/core/registry.rs Outdated
Comment on lines +734 to +743
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()))
Copy link
Copy Markdown
Contributor

@epage epage Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has really ballooned in complexity, including the idea of "catching" specific errors.

View changes since the review

Copy link
Copy Markdown
Contributor Author

@raushan728 raushan728 Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From #16927 (comment)

Regarding registry.rs - every alternative approach I tried but they broke existing tests. This is the cleanest I could find while keeping everything green.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have strong reservations about this approach and would need to understand why there is no other way, rather than being told that.

Copy link
Copy Markdown
Contributor Author

@raushan728 raushan728 Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage I found a approach may be it help - catching the missing manifest in PathSource::query() and returning Ok(()) with zero candidates, similar to how RecursivePathSource already silently skips missing manifests. This removes all the interception machinery from registry.rs entirely. Would this approach work for you?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented the PathSource::query() approach catching missing manifest there and returning Ok(()) with zero candidates. This removes all the interception machinery from registry.rs entirely.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't read_package return a CargoResult<Option<_>>, returning Ok(None) if the file does not exist?

Also, any change along these lines would likely be best done in a commit before the rest so help isolate behavior/test changes

@raushan728 raushan728 force-pushed the fix-15296 branch 3 times, most recently from d5f8d89 to 603d687 Compare April 24, 2026 06:58
@raushan728

This comment was marked as duplicate.

@raushan728 raushan728 requested a review from epage April 26, 2026 14:48
Comment on lines +390 to +400
let _ = writeln!(
&mut msg,
"no matching package named `{}` found at `{}`",
dep.package_name(),
rel_path(&path),
);
let _ = write!(
&mut msg,
"required by {}",
describe_path_in_context(resolver_ctx, &parent.package_id()),
);
Copy link
Copy Markdown
Contributor

@epage epage Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does is_handled_custom_path_error till exist?

On the surface, it looks like we use it to move the location searched: message into the line before it but it isn't clear why we feel that complexity is worth it.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It prevents location searched from appearing in the alt_paths branch without it, location searched would also appear for path hint errors where it's redundant since we already show the path in the error message.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was what my second paragraph was about which ends with

but it isn't clear why we feel that complexity is worth it.

Comment thread src/cargo/core/resolver/errors.rs Outdated
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 30, 2026

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@raushan728
Copy link
Copy Markdown
Contributor Author

Since PathSource::query() now returns zero candidates for missing Cargo.toml instead of an IO error, some existing tests that expected the old error chain now show the resolver-level error message instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-dependency-resolution Area: dependency resolution and the resolver A-registries Area: registries S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve error message when wrong package found in a path dependency

3 participants