Skip to content

Cargo check does not respect the --release flag #5218

@bepzi

Description

@bepzi

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:

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:

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions