From 3a5d0a00db3fc75537aea8c452dde97e9d70c376 Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Wed, 22 Apr 2026 06:00:41 +0000 Subject: [PATCH 1/3] test(path): add tests for path dependency wrong package error message (#15296) --- tests/testsuite/path.rs | 147 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/tests/testsuite/path.rs b/tests/testsuite/path.rs index 0305ea58e8a..b27d16d2741 100644 --- a/tests/testsuite/path.rs +++ b/tests/testsuite/path.rs @@ -1918,3 +1918,150 @@ foo v1.0.0 ([ROOT]/foo) "#]]) .run(); } + +#[cargo_test] +fn path_dep_wrong_package_name() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + [dependencies] + definitely_not_bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("bar/src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_data( + "\ +[ERROR] no matching package named `definitely_not_bar` found +location searched: [ROOT]/foo/bar +required by package `foo v0.1.0 ([ROOT]/foo)` +", + ) + .run(); +} + +#[cargo_test] +fn path_dep_package_in_subdirectory() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + [dependencies] + definitely_not_bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file( + "bar/definitely_not_bar/Cargo.toml", + r#" + [package] + name = "definitely_not_bar" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("bar/definitely_not_bar/src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_data( + "\ +[ERROR] failed to get `definitely_not_bar` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `definitely_not_bar` + +Caused by: + unable to update [ROOT]/foo/bar + +Caused by: + failed to read `[ROOT]/foo/bar/Cargo.toml` + +Caused by: + [NOT_FOUND] +", + ) + .run(); +} + +#[cargo_test] +fn path_dep_other_packages_nearby() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + [dependencies] + definitely_not_bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file( + "bar/alice/Cargo.toml", + r#" + [package] + name = "alice" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("bar/alice/src/lib.rs", "") + .file( + "bar/bob/Cargo.toml", + r#" + [package] + name = "bob" + version = "0.1.0" + edition = "2024" + "#, + ) + .file("bar/bob/src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_data( + "\ +[ERROR] failed to get `definitely_not_bar` as a dependency of package `foo v0.1.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `definitely_not_bar` + +Caused by: + unable to update [ROOT]/foo/bar + +Caused by: + failed to read `[ROOT]/foo/bar/Cargo.toml` + +Caused by: + [NOT_FOUND] +", + ) + .run(); +} From e22a6d3d9edc127f84cf2abe762b917d40c96577 Mon Sep 17 00:00:00 2001 From: Raushan Kumar Date: Fri, 1 May 2026 02:34:29 +0000 Subject: [PATCH 2/3] refactor(path): return Ok(None) from read_package when Cargo.toml is missing (#15296) --- src/cargo/sources/path.rs | 56 ++++++++++--- .../cargo_add/invalid_path/stderr.term.svg | 22 +---- tests/testsuite/path.rs | 80 ++++--------------- tests/testsuite/workspaces.rs | 16 +--- 4 files changed, 65 insertions(+), 109 deletions(-) diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 78dbe2027ee..74399fc9353 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -38,6 +38,8 @@ pub struct PathSource<'gctx> { path: PathBuf, /// Packages that this sources has discovered. package: RefCell>, + /// Whether the source has been loaded. + loaded: Cell, gctx: &'gctx GlobalContext, } @@ -51,6 +53,7 @@ impl<'gctx> PathSource<'gctx> { source_id, path: path.to_path_buf(), package: RefCell::new(None), + loaded: Cell::new(false), gctx, } } @@ -64,6 +67,7 @@ impl<'gctx> PathSource<'gctx> { source_id, path, package: RefCell::new(Some(pkg)), + loaded: Cell::new(true), gctx, } } @@ -76,10 +80,14 @@ impl<'gctx> PathSource<'gctx> { match &*self.package.borrow() { Some(pkg) => Ok(pkg.clone()), - None => Err(internal(format!( - "no package found in source {:?}", - self.path - ))), + None => { + let path = self.path.join("Cargo.toml"); + ops::read_package(&path, self.source_id, self.gctx)?; + Err(internal(format!( + "no package found in source {:?}", + self.path + ))) + } } } @@ -116,18 +124,44 @@ impl<'gctx> PathSource<'gctx> { /// Discovers packages inside this source if it hasn't yet done. pub fn load(&self) -> CargoResult<()> { - let mut package = self.package.borrow_mut(); - if package.is_none() { - *package = Some(self.read_package()?); + if !self.loaded.get() { + self.loaded.set(true); + *self.package.borrow_mut() = self.read_package()?; } - Ok(()) } - fn read_package(&self) -> CargoResult { + /// Reads the package from the manifest file. + /// + /// Returns `Ok(None)` if `Cargo.toml` does not exist at the source path. + /// Other errors (permissions, malformed TOML, etc.) still propagate. + fn read_package(&self) -> CargoResult> { let path = self.path.join("Cargo.toml"); - let pkg = ops::read_package(&path, self.source_id, self.gctx)?; - Ok(pkg) + match ops::read_package(&path, self.source_id, self.gctx) { + Ok(pkg) => Ok(Some(pkg)), + Err(e) => { + if e.downcast_ref::() + .map_or(false, |io_err| io_err.kind() == io::ErrorKind::NotFound) + { + return Ok(None); + } + // Walk the error chain for ManifestError wrapping NotFound. + for cause in e.chain() { + if let Some(manifest_err) = + cause.downcast_ref::() + { + if let Some(io_err) = std::error::Error::source(manifest_err) + .and_then(|s| s.downcast_ref::()) + { + if io_err.kind() == io::ErrorKind::NotFound { + return Ok(None); + } + } + } + } + Err(e) + } + } } } diff --git a/tests/testsuite/cargo_add/invalid_path/stderr.term.svg b/tests/testsuite/cargo_add/invalid_path/stderr.term.svg index 203ba67dc93..f82f0733b67 100644 --- a/tests/testsuite/cargo_add/invalid_path/stderr.term.svg +++ b/tests/testsuite/cargo_add/invalid_path/stderr.term.svg @@ -1,4 +1,4 @@ - +