-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Running cargo check --release
is functionally equivalent to cargo check
.
Minimal test case:
// src/main.rs
// Warn about unused stuff when in debug mode, fail compilation in release
#![cfg_attr(debug_assertions, warn(unused))]
#![cfg_attr(not(debug_assertions), deny(unused))]
fn main() {
let unused = 0;
}
Results:
Command | Expected Result | Actual Result |
---|---|---|
cargo build |
warnings | warnings |
cargo build --release |
failure | failure |
cargo check |
warnings | warnings |
cargo check --release |
failure | warnings |
Reproduced on cargo 0.25.0 (96d8071da 2018-02-26)
and cargo 1.26.0-nightly (d6c3983fe 2018-03-16)
.
I did a bit of digging, and I think I know why this is happening:
When running cargo check --release
, the debug_assertions
variable is still set to true
instead of false
, but when running cargo build --release
, that flag is properly left disabled.
debug_assertions
is defined within the Profile
struct (manifest.rs
), and an instance of Profile
is retrieved during compilation:
cargo/src/cargo/ops/cargo_compile.rs
Lines 679 to 697 in b0a2252
let build = if release { | |
&profiles.release | |
} else { | |
&profiles.dev | |
}; | |
let test = if release { | |
&profiles.bench | |
} else { | |
&profiles.test | |
}; | |
let profile = match mode { | |
CompileMode::Test => test, | |
CompileMode::Bench => &profiles.bench, | |
CompileMode::Build => build, | |
CompileMode::Check { test: false } => &profiles.check, | |
CompileMode::Check { test: true } => &profiles.check_test, | |
CompileMode::Doc { .. } => &profiles.doc, | |
CompileMode::Doctest => &profiles.doctest, | |
}; |
As you can see above, when finding the correct Profile
we essentially just get the default Profile
instance defined for each action (assuming we're using a default Workspace
struct, which most people are) - with the notable exception of CompileMode::Build
: for that mode, we either return a Profile
made for release-mode or the default Profile
that has debug_assertions
enabled. We don't do this for CompileMode::Check
. So, assuming we just retrieve the default Profile
...
The default profiles are defined as such:
cargo/src/cargo/core/workspace.rs
Lines 647 to 659 in b0a2252
let default_profiles = Profiles { | |
release: Profile::default_release(), | |
dev: Profile::default_dev(), | |
test: Profile::default_test(), | |
test_deps: Profile::default_dev(), | |
bench: Profile::default_bench(), | |
bench_deps: Profile::default_release(), | |
doc: Profile::default_doc(), | |
custom_build: Profile::default_custom_build(), | |
check: Profile::default_check(), | |
check_test: Profile::default_check_test(), | |
doctest: Profile::default_doctest(), | |
}; |
Things to note: the release Profile
actually just corresponds to cargo build --release
; there isn't a definition for a check_release
field. The function definitions are here:
cargo/src/cargo/core/manifest.rs
Lines 708 to 799 in b0a2252
impl Profile { | |
pub fn default_dev() -> Profile { | |
Profile { | |
debuginfo: Some(2), | |
debug_assertions: true, | |
overflow_checks: true, | |
incremental: true, | |
..Profile::default() | |
} | |
} | |
pub fn default_release() -> Profile { | |
Profile { | |
opt_level: "3".to_string(), | |
debuginfo: None, | |
..Profile::default() | |
} | |
} | |
pub fn default_test() -> Profile { | |
Profile { | |
test: true, | |
..Profile::default_dev() | |
} | |
} | |
pub fn default_bench() -> Profile { | |
Profile { | |
test: true, | |
..Profile::default_release() | |
} | |
} | |
pub fn default_doc() -> Profile { | |
Profile { | |
doc: true, | |
..Profile::default_dev() | |
} | |
} | |
pub fn default_custom_build() -> Profile { | |
Profile { | |
run_custom_build: true, | |
..Profile::default_dev() | |
} | |
} | |
pub fn default_check() -> Profile { | |
Profile { | |
check: true, | |
..Profile::default_dev() | |
} | |
} | |
pub fn default_check_test() -> Profile { | |
Profile { | |
check: true, | |
test: true, | |
..Profile::default_dev() | |
} | |
} | |
pub fn default_doctest() -> Profile { | |
Profile { | |
doc: true, | |
test: true, | |
..Profile::default_dev() | |
} | |
} | |
} | |
impl Default for Profile { | |
fn default() -> Profile { | |
Profile { | |
opt_level: "0".to_string(), | |
lto: Lto::Bool(false), | |
codegen_units: None, | |
rustc_args: None, | |
rustdoc_args: None, | |
debuginfo: None, | |
debug_assertions: false, | |
overflow_checks: false, | |
rpath: false, | |
test: false, | |
doc: false, | |
run_custom_build: false, | |
check: false, | |
panic: None, | |
incremental: false, | |
} | |
} | |
} |
And as you can see, the default Profile
for CompileMode::Check
is equivalent to the default development Profile
, with debug_assertions
enabled. There is no Profile
for CompileMode::Check
that is also for release mode.