Skip to content

Commit e2eacc6

Browse files
committed
Don't distinguish Debuginfo::None and Debuginfo::Explicit(None)
Previously, `Debuginfo::None` meant "don't pass -C debuginfo" and `Explicit(None)` meant "-C debuginfo=0", which occasionally led to caching bugs where cargo would sometimes pass `-C debuginfo=0` and sometimes not. There are no such bugs currently that we know of, but representing them the same within cargo avoids the possibility of the bug popping up again in the future. I tested the `with_stderr_does_not_contain_tests` with this diff to ensure they did not pass: ```diff diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 55ec17182..c186dd00a 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1073,9 +1073,7 @@ fn build_base_args( let debuginfo = debuginfo.into_inner(); // Shorten the number of arguments if possible. - if debuginfo != TomlDebugInfo::None { cmd.arg("-C").arg(format!("debuginfo={}", debuginfo)); - } cmd.args(unit.pkg.manifest().lint_rustflags()); if !rustflags.is_empty() { ```
1 parent f7b95e3 commit e2eacc6

File tree

6 files changed

+61
-58
lines changed

6 files changed

+61
-58
lines changed

src/cargo/core/compiler/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu
604604
}
605605

606606
if json_messages {
607-
let debuginfo = profile.debuginfo.to_option().map(|d| match d {
607+
let debuginfo = match profile.debuginfo.into_inner() {
608608
TomlDebugInfo::None => machine_message::ArtifactDebuginfo::Int(0),
609609
TomlDebugInfo::Limited => machine_message::ArtifactDebuginfo::Int(1),
610610
TomlDebugInfo::Full => machine_message::ArtifactDebuginfo::Int(2),
@@ -614,10 +614,10 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu
614614
TomlDebugInfo::LineTablesOnly => {
615615
machine_message::ArtifactDebuginfo::Named("line-tables-only")
616616
}
617-
});
617+
};
618618
let art_profile = machine_message::ArtifactProfile {
619619
opt_level: profile.opt_level.as_str(),
620-
debuginfo,
620+
debuginfo: Some(debuginfo),
621621
debug_assertions: profile.debug_assertions,
622622
overflow_checks: profile.overflow_checks,
623623
test: unit_mode.is_any_test(),
@@ -1071,7 +1071,9 @@ fn build_base_args(
10711071
cmd.arg("-C").arg(&format!("codegen-units={}", n));
10721072
}
10731073

1074-
if let Some(debuginfo) = debuginfo.to_option() {
1074+
let debuginfo = debuginfo.into_inner();
1075+
// Shorten the number of arguments if possible.
1076+
if debuginfo != TomlDebugInfo::None {
10751077
cmd.arg("-C").arg(format!("debuginfo={}", debuginfo));
10761078
}
10771079

src/cargo/core/profiles.rs

+22-32
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,7 @@ impl ProfileMaker {
449449
// a unit is shared. If that's the case, we'll use the deferred value
450450
// below so the unit can be reused, otherwise we can avoid emitting
451451
// the unit's debuginfo.
452-
if let Some(debuginfo) = profile.debuginfo.to_option() {
453-
profile.debuginfo = DebugInfo::Deferred(debuginfo);
454-
}
452+
profile.debuginfo = DebugInfo::Deferred(profile.debuginfo.into_inner());
455453
}
456454
// ... and next comes any other sorts of overrides specified in
457455
// profiles, such as `[profile.release.build-override]` or
@@ -529,7 +527,7 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
529527
profile.codegen_units = toml.codegen_units;
530528
}
531529
if let Some(debuginfo) = toml.debug {
532-
profile.debuginfo = DebugInfo::Explicit(debuginfo);
530+
profile.debuginfo = DebugInfo::Resolved(debuginfo);
533531
}
534532
if let Some(debug_assertions) = toml.debug_assertions {
535533
profile.debug_assertions = debug_assertions;
@@ -611,7 +609,7 @@ impl Default for Profile {
611609
lto: Lto::Bool(false),
612610
codegen_backend: None,
613611
codegen_units: None,
614-
debuginfo: DebugInfo::None,
612+
debuginfo: DebugInfo::Resolved(TomlDebugInfo::None),
615613
debug_assertions: false,
616614
split_debuginfo: None,
617615
overflow_checks: false,
@@ -680,7 +678,7 @@ impl Profile {
680678
Profile {
681679
name: InternedString::new("dev"),
682680
root: ProfileRoot::Debug,
683-
debuginfo: DebugInfo::Explicit(TomlDebugInfo::Full),
681+
debuginfo: DebugInfo::Resolved(TomlDebugInfo::Full),
684682
debug_assertions: true,
685683
overflow_checks: true,
686684
incremental: true,
@@ -720,11 +718,8 @@ impl Profile {
720718

721719
/// The debuginfo level setting.
722720
///
723-
/// This is semantically an `Option<u32>`, and should be used as so via the
724-
/// [DebugInfo::to_option] method for all intents and purposes:
725-
/// - `DebugInfo::None` corresponds to `None`
726-
/// - `DebugInfo::Explicit(u32)` and `DebugInfo::Deferred` correspond to
727-
/// `Option<u32>::Some`
721+
/// This is semantically a [`TomlDebugInfo`], and should be used as so via the
722+
/// [DebugInfo::into_inner] method for all intents and purposes.
728723
///
729724
/// Internally, it's used to model a debuginfo level whose value can be deferred
730725
/// for optimization purposes: host dependencies usually don't need the same
@@ -736,35 +731,34 @@ impl Profile {
736731
#[derive(Debug, Copy, Clone, serde::Serialize)]
737732
#[serde(untagged)]
738733
pub enum DebugInfo {
739-
/// No debuginfo level was set.
740-
None,
741-
/// A debuginfo level that is explicitly set, by a profile or a user.
742-
Explicit(TomlDebugInfo),
734+
/// A debuginfo level that is fixed and will not change.
735+
///
736+
/// This can be set by a profile, user, or default value.
737+
Resolved(TomlDebugInfo),
743738
/// For internal purposes: a deferred debuginfo level that can be optimized
744739
/// away, but has this value otherwise.
745740
///
746-
/// Behaves like `Explicit` in all situations except for the default build
741+
/// Behaves like `Resolved` in all situations except for the default build
747742
/// dependencies profile: whenever a build dependency is not shared with
748743
/// runtime dependencies, this level is weakened to a lower level that is
749-
/// faster to build (see [DebugInfo::weaken]).
744+
/// faster to build (see [`DebugInfo::weaken`]).
750745
///
751746
/// In all other situations, this level value will be the one to use.
752747
Deferred(TomlDebugInfo),
753748
}
754749

755750
impl DebugInfo {
756-
/// The main way to interact with this debuginfo level, turning it into an Option.
757-
pub fn to_option(self) -> Option<TomlDebugInfo> {
751+
/// The main way to interact with this debuginfo level, turning it into a [`TomlDebugInfo`].
752+
pub fn into_inner(self) -> TomlDebugInfo {
758753
match self {
759-
DebugInfo::None => None,
760-
DebugInfo::Explicit(v) | DebugInfo::Deferred(v) => Some(v),
754+
DebugInfo::Resolved(v) | DebugInfo::Deferred(v) => v,
761755
}
762756
}
763757

764758
/// Returns true if any debuginfo will be generated. Helper
765759
/// for a common operation on the usual `Option` representation.
766760
pub(crate) fn is_turned_on(&self) -> bool {
767-
!matches!(self.to_option(), None | Some(TomlDebugInfo::None))
761+
!matches!(self.into_inner(), TomlDebugInfo::None)
768762
}
769763

770764
pub(crate) fn is_deferred(&self) -> bool {
@@ -774,44 +768,40 @@ impl DebugInfo {
774768
/// Force the deferred, preferred, debuginfo level to a finalized explicit value.
775769
pub(crate) fn finalize(self) -> Self {
776770
match self {
777-
DebugInfo::Deferred(v) => DebugInfo::Explicit(v),
771+
DebugInfo::Deferred(v) => DebugInfo::Resolved(v),
778772
_ => self,
779773
}
780774
}
781775

782776
/// Reset to the lowest level: no debuginfo.
783-
/// If it is explicitly set, keep it explicit.
784777
pub(crate) fn weaken(self) -> Self {
785-
match self {
786-
DebugInfo::None => DebugInfo::None,
787-
_ => DebugInfo::Explicit(TomlDebugInfo::None),
788-
}
778+
DebugInfo::Resolved(TomlDebugInfo::None)
789779
}
790780
}
791781

792782
impl PartialEq for DebugInfo {
793783
fn eq(&self, other: &DebugInfo) -> bool {
794-
self.to_option().eq(&other.to_option())
784+
self.into_inner().eq(&other.into_inner())
795785
}
796786
}
797787

798788
impl Eq for DebugInfo {}
799789

800790
impl Hash for DebugInfo {
801791
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
802-
self.to_option().hash(state);
792+
self.into_inner().hash(state);
803793
}
804794
}
805795

806796
impl PartialOrd for DebugInfo {
807797
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
808-
self.to_option().partial_cmp(&other.to_option())
798+
self.into_inner().partial_cmp(&other.into_inner())
809799
}
810800
}
811801

812802
impl Ord for DebugInfo {
813803
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
814-
self.to_option().cmp(&other.to_option())
804+
self.into_inner().cmp(&other.into_inner())
815805
}
816806
}
817807

tests/testsuite/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4074,7 +4074,7 @@ fn message_format_json_forward_stderr() {
40744074
},
40754075
"profile":{
40764076
"debug_assertions":false,
4077-
"debuginfo":null,
4077+
"debuginfo":0,
40784078
"opt_level":"3",
40794079
"overflow_checks": false,
40804080
"test":false

tests/testsuite/profile_config.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ fn named_config_profile() {
437437
assert_eq!(p.name, "foo");
438438
assert_eq!(p.codegen_units, Some(2)); // "foo" from config
439439
assert_eq!(p.opt_level, "1"); // "middle" from manifest
440-
assert_eq!(p.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // "bar" from config
440+
assert_eq!(p.debuginfo.into_inner(), TomlDebugInfo::Limited); // "bar" from config
441441
assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override)
442442
assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)
443443

@@ -446,7 +446,7 @@ fn named_config_profile() {
446446
assert_eq!(bo.name, "foo");
447447
assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
448448
assert_eq!(bo.opt_level, "0"); // default to zero
449-
assert_eq!(bo.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // SAME as normal
449+
assert_eq!(bo.debuginfo.into_inner(), TomlDebugInfo::Limited); // SAME as normal
450450
assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
451451
assert_eq!(bo.overflow_checks, true); // SAME as normal
452452

@@ -455,7 +455,7 @@ fn named_config_profile() {
455455
assert_eq!(po.name, "foo");
456456
assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config
457457
assert_eq!(po.opt_level, "1"); // SAME as normal
458-
assert_eq!(po.debuginfo.to_option(), Some(TomlDebugInfo::Limited)); // SAME as normal
458+
assert_eq!(po.debuginfo.into_inner(), TomlDebugInfo::Limited); // SAME as normal
459459
assert_eq!(po.debug_assertions, true); // SAME as normal
460460
assert_eq!(po.overflow_checks, false); // "middle" package override from manifest
461461
}
@@ -509,12 +509,13 @@ fn test_with_dev_profile() {
509509
[DOWNLOADING] [..]
510510
[DOWNLOADED] [..]
511511
[COMPILING] somedep v1.0.0
512-
[RUNNING] `rustc --crate-name somedep [..]-C debuginfo=0[..]
512+
[RUNNING] `rustc --crate-name somedep [..]
513513
[COMPILING] foo v0.1.0 [..]
514-
[RUNNING] `rustc --crate-name foo [..]-C debuginfo=0[..]
514+
[RUNNING] `rustc --crate-name foo [..]
515515
[FINISHED] [..]
516516
[EXECUTABLE] `[..]/target/debug/deps/foo-[..][EXE]`
517517
",
518518
)
519+
.with_stdout_does_not_contain("[..] -C debuginfo=0[..]")
519520
.run();
520521
}

tests/testsuite/profile_targets.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,19 @@ fn profile_selection_build() {
8888
.with_stderr_unordered("\
8989
[COMPILING] bar [..]
9090
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
91-
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
91+
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
9292
[COMPILING] bdep [..]
93-
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
93+
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
9494
[COMPILING] foo [..]
95-
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
95+
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
9696
[RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build`
9797
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
9898
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
9999
[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
100100
[FINISHED] dev [unoptimized + debuginfo] [..]
101101
"
102102
)
103+
.with_stdout_does_not_contain("[..] -C debuginfo=0[..]")
103104
.run();
104105
p.cargo("build -vv")
105106
.with_stderr_unordered(
@@ -154,8 +155,9 @@ fn profile_selection_build_all_targets() {
154155
// `build.rs` is a plugin.
155156
// - Benchmark dependencies are compiled in `dev` mode, which may be
156157
// surprising. See issue rust-lang/cargo#4929.
157-
// - We make sure that the build dependencies bar, bdep, and build.rs
158-
// are built with debuginfo=0.
158+
// - We make sure that the build dependencies bar, bdep, and build.rs are built with
159+
// debuginfo=0; but since we don't pass `-C debuginfo` when it's set to 0, we have to test
160+
// explicitly that there's no `-C debuginfo` flag.
159161
//
160162
// - Dependency profiles:
161163
// Pkg Target Profile Reason
@@ -181,11 +183,11 @@ fn profile_selection_build_all_targets() {
181183
[COMPILING] bar [..]
182184
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=1 -C debuginfo=2 [..]
183185
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
184-
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
186+
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
185187
[COMPILING] bdep [..]
186-
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
188+
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
187189
[COMPILING] foo [..]
188-
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=0[..]
190+
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
189191
[RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build`
190192
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
191193
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]`
@@ -199,6 +201,7 @@ fn profile_selection_build_all_targets() {
199201
[FINISHED] dev [unoptimized + debuginfo] [..]
200202
"
201203
)
204+
.with_stdout_does_not_contain("[..] -C debuginfo=0[..]")
202205
.run();
203206
p.cargo("build -vv")
204207
.with_stderr_unordered(

tests/testsuite/profiles.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,11 @@ fn debug_0_report() {
467467
.with_stderr(
468468
"\
469469
[COMPILING] foo v0.1.0 [..]
470-
[RUNNING] `rustc --crate-name foo src/lib.rs [..]-C debuginfo=0 [..]
470+
[RUNNING] `rustc --crate-name foo src/lib.rs [..]
471471
[FINISHED] dev [unoptimized] target(s) in [..]
472472
",
473473
)
474+
.with_stderr_does_not_contain("-C debuginfo")
474475
.run();
475476
}
476477

@@ -745,13 +746,7 @@ Caused by:
745746

746747
#[cargo_test(nightly, reason = "debug options stabilized in 1.70")]
747748
fn debug_options_valid() {
748-
for (option, cli) in [
749-
("line-directives-only", "line-directives-only"),
750-
("line-tables-only", "line-tables-only"),
751-
("none", "0"),
752-
("limited", "1"),
753-
("full", "2"),
754-
] {
749+
let build = |option| {
755750
let p = project()
756751
.file(
757752
"Cargo.toml",
@@ -771,7 +766,19 @@ fn debug_options_valid() {
771766
.build();
772767

773768
p.cargo("build -v")
769+
};
770+
771+
for (option, cli) in [
772+
("line-directives-only", "line-directives-only"),
773+
("line-tables-only", "line-tables-only"),
774+
("limited", "1"),
775+
("full", "2"),
776+
] {
777+
build(option)
774778
.with_stderr_contains(&format!("[RUNNING] `rustc [..]-C debuginfo={cli} [..]"))
775779
.run();
776780
}
781+
build("none")
782+
.with_stderr_does_not_contain("[..]-C debuginfo[..]")
783+
.run();
777784
}

0 commit comments

Comments
 (0)