Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,13 @@ impl MaybePackage {
}
}

pub fn as_package(&self) -> Option<&Package> {
match self {
MaybePackage::Package(p) => Some(p),
MaybePackage::Virtual(_) => None,
}
}

/// Has an embedded manifest (single-file package)
pub fn is_embedded(&self) -> bool {
match self {
Expand Down
1 change: 1 addition & 0 deletions src/cargo/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
//! # Adding a pass
//!
//! When a diagnostic requires adding a new pass, keep in mind:
//! - Cap lints (skip everything for non-local)
//! - Support for `build.warnings`
//! - When errors should block further evaluation within the pass
//! - Providing a summary at the end, like what is provided by [`ScopedDiagnosticStats::report_summary`]
Expand Down
22 changes: 19 additions & 3 deletions src/cargo/diagnostics/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,34 @@ pub fn emit_parse_diagnostics(
) -> CargoResult<()> {
let mut stats = GlobalDiagnosticStats::new();

emit_parse_ws_diagnostics(workspace, rules, &mut stats)?;
if is_local_workspace(workspace) {
emit_parse_ws_diagnostics(workspace, rules, &mut stats)?;
}

for maybe_pkg in workspace.loaded_maybe() {
if let MaybePackage::Package(pkg) = maybe_pkg {
let path = pkg.manifest_path();
emit_parse_pkg_diagnostics(workspace, pkg, &path, rules, &mut stats)?;
if is_local_package(pkg) {
let path = pkg.manifest_path();
emit_parse_pkg_diagnostics(workspace, pkg, &path, rules, &mut stats)?;
}
}
}

stats.ok()
}

fn is_local_workspace(workspace: &Workspace<'_>) -> bool {
workspace
.root_maybe()
.as_package()
.map(is_local_package)
.unwrap_or_else(|| workspace.members().any(is_local_package))
}

fn is_local_package(pkg: &Package) -> bool {
pkg.package_id().source_id().is_path()
}

fn emit_parse_pkg_diagnostics(
workspace: &Workspace<'_>,
pkg: &Package,
Expand Down
12 changes: 12 additions & 0 deletions src/cargo/diagnostics/rules/unused_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@ pub fn lint_build_results(
pkg.rust_version(),
pkg.manifest().unstable_features(),
);
if !pkg_id.source_id().is_path() {
for (dep_kind, state) in states.iter() {
for ext in state.unused_externs.iter().flatten() {
debug!(
"pkg {} v{} ({dep_kind:?}): ignoring unused extern `{ext}`, package is capped",
pkg_id.name(),
pkg_id.version(),
);
}
}
continue;
}
if level.level == LintLevel::Allow {
for (dep_kind, state) in states.iter() {
for ext in state.unused_externs.iter().flatten() {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub fn compile_with_exec<'a>(

/// Like [`compile_with_exec`] but without warnings from manifest parsing.
#[tracing::instrument(skip_all)]
pub fn compile_ws<'a>(
fn compile_ws<'a>(
ws: &Workspace<'a>,
options: &CompileOptions,
exec: &Arc<dyn Executor>,
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/ops/cargo_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl<'gctx> InstallablePackage<'gctx> {

// For bare `cargo install` (no `--bin` or `--example`), check if there is
// *something* to install. Explicit `--bin` or `--example` flags will be
// checked at the start of `compile_ws`.
// checked at the start of `compile_with_exec`.
if !opts.filter.is_specific() && !pkg.targets().iter().any(|t| t.is_bin()) {
bail!(
"there is nothing to install in `{}`, because it has no binaries\n\
Expand Down Expand Up @@ -392,7 +392,7 @@ impl<'gctx> InstallablePackage<'gctx> {

let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
self.opts.build_config.dry_run = dry_run;
let compile = ops::compile_ws(&self.ws, &self.opts, &exec).with_context(|| {
let compile = ops::compile_with_exec(&self.ws, &self.opts, &exec).with_context(|| {
if let Some(td) = td_opt.take() {
// preserve the temporary directory, so the user can inspect it
drop(td.keep());
Expand Down Expand Up @@ -645,7 +645,7 @@ impl<'gctx> InstallablePackage<'gctx> {
}
// It would be best if `source` could be passed in here to avoid a
// duplicate "Updating", but since `source` is taken by value, then it
// wouldn't be available for `compile_ws`.
// wouldn't be available for `compile_with_exec`.
let dry_run = false;
let (pkg_set, resolve) = ops::resolve_ws(&self.ws, dry_run)?;
ops::check_yanked(
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub use self::cargo_clean::{CleanContext, CleanOptions, clean};
pub use self::cargo_compile::unit_generator::UnitGenerator;
pub use self::cargo_compile::{CompileFilter, FilterRule, LibRule, Packages};
pub use self::cargo_compile::{
CompileOptions, compile, compile_with_exec, compile_ws, create_bcx, print, resolve_all_features,
CompileOptions, compile, compile_with_exec, create_bcx, print, resolve_all_features,
};
pub use self::cargo_doc::{DocOptions, OutputFormat, doc};
pub use self::cargo_fetch::{FetchOptions, fetch};
Expand Down
2 changes: 2 additions & 0 deletions tests/testsuite/https.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ fn github_works_cargo_install() {
.with_stderr_data(str![[r#"
[UPDATING] git repository `https://github.com/rust-lang/bitflags.git`
[INSTALLING] bitflags-smoke-test [..]
[WARNING] Cargo.toml: unused manifest key: dependencies.bitflags.all-features
[WARNING] `bitflags-smoke-test` (manifest) generated 1 warning

@epage epage Jun 16, 2026

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.

Note: there is an existing bug in cargo install --git where we download the git source and then load it as a path source so it is considered local and rustc and cargo lints are shown.

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.

See

let mut ws = if source_id.is_git() || source_id.is_path() {
Workspace::new(pkg.manifest_path(), gctx)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good finding. Kinda related to #13259

Comment on lines +174 to +175

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like a bug in its manifest.
Since now we have more dependencies on the shape of bigflags, should we install a specific commit install of HEAD?

https://github.com/bitflags/bitflags/blob/9253889ee93921055309908c46272bd6c5c6ad99/tests/smoke-test/Cargo.toml#L9

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.

I would say that is something for us to look into separately.

[LOCKING] 1 package to latest compatible version
...
[INSTALLED] package [..]
Expand Down
97 changes: 96 additions & 1 deletion tests/testsuite/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,13 +1631,17 @@ fn path_install_workspace_root_despite_default_members() {
.arg("ws-root")
.with_stderr_data(str![[r#"
[INSTALLING] ws-root v0.1.0 ([ROOT]/foo)
[WARNING] ws-member/Cargo.toml: `package.edition` is unspecified, defaulting to `2015` while the latest is `2024`
[WARNING] `ws-member` (manifest) generated 1 warning
[WARNING] Cargo.toml: `package.edition` is unspecified, defaulting to `2015` while the latest is `2024`
[WARNING] `ws-root` (manifest) generated 1 warning
[COMPILING] ws-root v0.1.0 ([ROOT]/foo)
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
[INSTALLING] [ROOT]/home/.cargo/bin/ws-root[EXE]
[INSTALLED] package `ws-root v0.1.0 ([ROOT]/foo)` (executable `ws-root[EXE]`)
[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries

"#]])
"#]].unordered())
// Particularly avoid "Installed package `ws-root v0.1.0 ([..]])` (executable `ws-member`)":
.with_stderr_does_not_contain("ws-member")
.run();
Expand Down Expand Up @@ -2149,6 +2153,8 @@ fn workspace_uses_workspace_target_dir() {
.arg(p.root().join("bar"))
.with_stderr_data(str![[r#"
[INSTALLING] bar v0.1.0 ([ROOT]/foo/bar)
[WARNING] Cargo.toml: `package.edition` is unspecified, defaulting to `2015` while the latest is `2024`
[WARNING] `foo` (manifest) generated 1 warning
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
[INSTALLING] [ROOT]/home/.cargo/bin/bar[EXE]
[INSTALLED] package `bar v0.1.0 ([ROOT]/foo/bar)` (executable `bar[EXE]`)
Expand Down Expand Up @@ -3043,6 +3049,8 @@ fn dry_run_incompatible_package_dependency() {
.with_status(101)
.with_stderr_data(str![[r#"
[INSTALLING] foo v0.1.0 ([ROOT]/foo)
[WARNING] Cargo.toml: `package.edition` is unspecified, defaulting to `2015` while the latest is `2024`
[WARNING] `foo` (manifest) generated 1 warning
[LOCKING] 1 package to latest compatible version
[ERROR] failed to compile `foo v0.1.0 ([ROOT]/foo)`, intermediate artifacts can be found at `[ROOT]/foo/target`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_BUILD_BUILD_DIR` to that path.
Expand Down Expand Up @@ -3181,3 +3189,90 @@ fn mistaken_flag_case() {
"#]])
.run();
}

#[cargo_test]
fn cap_lints_path() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["test-dummy-unstable"]

[package]
name = "foo"
version = "0.0.1"
edition = "2015"
authors = []
im-a-teapot = true

[lints.cargo]
im_a_teapot = "warn"
"#,
)
.file("src/main.rs", "fn main() { let unused = 10; }")
.build();
p.cargo("install --path . -Zcargo-lints")
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
.with_stdout_data(str![])
.with_stderr_data(str![[r#"
[INSTALLING] foo v0.0.1 ([ROOT]/foo)
[WARNING] `im_a_teapot` is specified
--> Cargo.toml:9:1
|
9 | im-a-teapot = true
| ^^^^^^^^^^^^^^^^^^
|
= [NOTE] `cargo::im_a_teapot` is set to `warn` in `[lints]`
[WARNING] `foo` (manifest) generated 1 warning
[COMPILING] foo v0.0.1 ([ROOT]/foo)
[WARNING] unused variable: `unused`
...
[WARNING] `foo` (bin "foo") generated 1 warning (run `cargo fix --bin "foo" -p foo` to apply 1 suggestion)
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
[INSTALLED] package `foo v0.0.1 ([ROOT]/foo)` (executable `foo[EXE]`)
[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries

"#]])
.run();
}

#[cargo_test]
fn cap_lints_registry() {
Package::new("foo", "1.0.0")
.file(
"Cargo.toml",
r#"
cargo-features = ["test-dummy-unstable"]

[package]
name = "foo"
version = "1.0.0"
edition = "2015"
authors = []
im-a-teapot = true

[lints.cargo]
im-a-teapot = "deny"
"#,
)
.file("src/main.rs", "fn main() { let unused = 10; }")
.publish();

cargo_process("install foo -Zcargo-lints")
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
.with_stdout_data(str![])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[DOWNLOADING] crates ...
[DOWNLOADED] foo v1.0.0 (registry `dummy-registry`)
[INSTALLING] foo v1.0.0
[COMPILING] foo v1.0.0
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
[INSTALLED] package `foo v1.0.0` (executable `foo[EXE]`)
[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries

"#]])
.run();
}
2 changes: 2 additions & 0 deletions tests/testsuite/install_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,8 @@ fn deletes_orphaned() {
p.cargo("install --path . --bins --examples")
.with_stderr_data(str![[r#"
[INSTALLING] foo v0.2.0 ([ROOT]/foo)
[WARNING] Cargo.toml: `package.edition` is unspecified, defaulting to `2015` while the latest is `2024`
[WARNING] `foo` (manifest) generated 1 warning
[COMPILING] foo v0.2.0 ([ROOT]/foo)
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
[INSTALLING] [ROOT]/home/.cargo/bin/ex2[EXE]
Expand Down