Skip to content

Commit f3c7e06

Browse files
committed
Auto merge of #8658 - ehuss:beta-fix-doctest-lto, r=alexcrichton
[beta] Fix LTO with doctests. Beta packports: * #8653 Fix cache_messages::rustdoc test broken on beta. — so that CI tests pass * #8648 Add spaces after -C and -Z flags for consistency — so that #8657 can be merged * #8657 Fix LTO with doctests. Although the LTO regression is on 1.46, I probably won't do a stable backport even if there is a point release, as I think it would be good to have sufficient time for testing on nightly, and I don't want to rush it. I'm willing to reconsider that, though.
2 parents 51b6612 + d1ff577 commit f3c7e06

File tree

5 files changed

+124
-72
lines changed

5 files changed

+124
-72
lines changed

src/cargo/core/compiler/context/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
210210
// Collect information for `rustdoc --test`.
211211
if unit.mode.is_doc_test() {
212212
let mut unstable_opts = false;
213-
let args = compiler::extern_args(&self, unit, &mut unstable_opts)?;
213+
let mut args = compiler::extern_args(&self, unit, &mut unstable_opts)?;
214+
args.extend(compiler::lto_args(&self, unit));
214215
self.compilation.to_doc_test.push(compilation::Doctest {
215216
unit: unit.clone(),
216217
args,

src/cargo/core/compiler/mod.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
207207

208208
rustc.args(cx.bcx.rustflags_args(unit));
209209
if cx.bcx.config.cli_unstable().binary_dep_depinfo {
210-
rustc.arg("-Zbinary-dep-depinfo");
210+
rustc.arg("-Z").arg("binary-dep-depinfo");
211211
}
212212
let mut output_options = OutputOptions::new(cx, unit);
213213
let package_id = unit.pkg.package_id();
@@ -533,7 +533,7 @@ fn prepare_rustc(
533533
if cx.bcx.config.cli_unstable().jobserver_per_rustc {
534534
let client = cx.new_jobserver()?;
535535
base.inherit_jobserver(&client);
536-
base.arg("-Zjobserver-token-requests");
536+
base.arg("-Z").arg("jobserver-token-requests");
537537
assert!(cx.rustc_clients.insert(unit.clone(), client).is_none());
538538
} else {
539539
base.inherit_jobserver(&cx.jobserver);
@@ -797,28 +797,9 @@ fn build_base_args(
797797
cmd.arg("-C").arg(format!("panic={}", panic));
798798
}
799799

800-
match cx.lto[unit] {
801-
lto::Lto::Run(None) => {
802-
cmd.arg("-C").arg("lto");
803-
}
804-
lto::Lto::Run(Some(s)) => {
805-
cmd.arg("-C").arg(format!("lto={}", s));
806-
}
807-
lto::Lto::Off => {
808-
cmd.arg("-C").arg("lto=off");
809-
}
810-
lto::Lto::ObjectAndBitcode => {} // this is rustc's default
811-
lto::Lto::OnlyBitcode => {
812-
cmd.arg("-Clinker-plugin-lto");
813-
}
814-
lto::Lto::OnlyObject => {
815-
cmd.arg("-Cembed-bitcode=no");
816-
}
817-
}
800+
cmd.args(&lto_args(cx, unit));
818801

819802
if let Some(n) = codegen_units {
820-
// There are some restrictions with LTO and codegen-units, so we
821-
// only add codegen units when LTO is not used.
822803
cmd.arg("-C").arg(&format!("codegen-units={}", n));
823804
}
824805

@@ -862,7 +843,7 @@ fn build_base_args(
862843
// will simply not be needed when the behavior is stabilized in the Rust
863844
// compiler itself.
864845
if *panic == PanicStrategy::Abort {
865-
cmd.arg("-Zpanic-abort-tests");
846+
cmd.arg("-Z").arg("panic-abort-tests");
866847
}
867848
} else if test {
868849
cmd.arg("--cfg").arg("test");
@@ -922,7 +903,8 @@ fn build_base_args(
922903
// any non-public crate in the sysroot).
923904
//
924905
// RUSTC_BOOTSTRAP allows unstable features on stable.
925-
cmd.arg("-Zforce-unstable-if-unmarked")
906+
cmd.arg("-Z")
907+
.arg("force-unstable-if-unmarked")
926908
.env("RUSTC_BOOTSTRAP", "1");
927909
}
928910

@@ -945,6 +927,23 @@ fn build_base_args(
945927
Ok(())
946928
}
947929

930+
fn lto_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
931+
let mut result = Vec::new();
932+
let mut push = |arg: &str| {
933+
result.push(OsString::from("-C"));
934+
result.push(OsString::from(arg));
935+
};
936+
match cx.lto[unit] {
937+
lto::Lto::Run(None) => push("lto"),
938+
lto::Lto::Run(Some(s)) => push(&format!("lto={}", s)),
939+
lto::Lto::Off => push("lto=off"),
940+
lto::Lto::ObjectAndBitcode => {} // this is rustc's default
941+
lto::Lto::OnlyBitcode => push("linker-plugin-lto"),
942+
lto::Lto::OnlyObject => push("embed-bitcode=no"),
943+
}
944+
result
945+
}
946+
948947
fn build_deps_args(
949948
cmd: &mut ProcessBuilder,
950949
cx: &mut Context<'_, '_>,

src/cargo/core/profiles.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl Profiles {
299299
let release = matches!(self.requested_profile.as_str(), "release" | "bench");
300300

301301
match mode {
302-
CompileMode::Test | CompileMode::Bench => {
302+
CompileMode::Test | CompileMode::Bench | CompileMode::Doctest => {
303303
if release {
304304
(
305305
InternedString::new("bench"),
@@ -312,10 +312,7 @@ impl Profiles {
312312
)
313313
}
314314
}
315-
CompileMode::Build
316-
| CompileMode::Check { .. }
317-
| CompileMode::Doctest
318-
| CompileMode::RunCustomBuild => {
315+
CompileMode::Build | CompileMode::Check { .. } | CompileMode::RunCustomBuild => {
319316
// Note: `RunCustomBuild` doesn't normally use this code path.
320317
// `build_unit_profiles` normally ensures that it selects the
321318
// ancestor's profile. However, `cargo clean -p` can hit this

tests/testsuite/cache_messages.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,8 @@ fn rustdoc() {
238238
.file(
239239
"src/lib.rs",
240240
"
241-
#![warn(private_doc_tests)]
242-
/// asdf
243-
/// ```
244-
/// let x = 1;
245-
/// ```
246-
fn f() {}
241+
#![warn(missing_docs)]
242+
pub fn f() {}
247243
",
248244
)
249245
.build();
@@ -254,7 +250,7 @@ fn rustdoc() {
254250
.expect("rustdoc to run");
255251
assert!(rustdoc_output.status.success());
256252
let rustdoc_stderr = as_str(&rustdoc_output.stderr);
257-
assert!(rustdoc_stderr.contains("private"));
253+
assert!(rustdoc_stderr.contains("missing"));
258254
assert!(rustdoc_stderr.contains("\x1b["));
259255
assert_eq!(
260256
p.glob("target/debug/.fingerprint/foo-*/output-*").count(),

tests/testsuite/lto.rs

Lines changed: 94 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use cargo::core::compiler::Lto;
22
use cargo_test_support::registry::Package;
3-
use cargo_test_support::{project, Project};
3+
use cargo_test_support::{basic_manifest, project, Project};
44
use std::process::Output;
55

66
#[cargo_test]
@@ -25,7 +25,7 @@ fn with_deps() {
2525
.file("src/main.rs", "extern crate bar; fn main() {}")
2626
.build();
2727
p.cargo("build -v --release")
28-
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-Clinker-plugin-lto[..]`")
28+
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-C linker-plugin-lto[..]`")
2929
.with_stderr_contains("[..]`rustc[..]--crate-name test[..]-C lto[..]`")
3030
.run();
3131
}
@@ -83,7 +83,7 @@ fn build_dep_not_ltod() {
8383
.file("src/main.rs", "fn main() {}")
8484
.build();
8585
p.cargo("build -v --release")
86-
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-Cembed-bitcode=no[..]`")
86+
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-C embed-bitcode=no[..]`")
8787
.with_stderr_contains("[..]`rustc[..]--crate-name test[..]-C lto[..]`")
8888
.run();
8989
}
@@ -188,30 +188,32 @@ fn complicated() {
188188
p.cargo("build -v --release")
189189
// normal deps and their transitive dependencies do not need object
190190
// code, so they should have linker-plugin-lto specified
191-
.with_stderr_contains("[..]`rustc[..]--crate-name dep_normal2 [..]-Clinker-plugin-lto[..]`")
192-
.with_stderr_contains("[..]`rustc[..]--crate-name dep_normal [..]-Clinker-plugin-lto[..]`")
191+
.with_stderr_contains(
192+
"[..]`rustc[..]--crate-name dep_normal2 [..]-C linker-plugin-lto[..]`",
193+
)
194+
.with_stderr_contains("[..]`rustc[..]--crate-name dep_normal [..]-C linker-plugin-lto[..]`")
193195
// build dependencies and their transitive deps don't need any bitcode,
194196
// so embedding should be turned off
195-
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build2 [..]-Cembed-bitcode=no[..]`")
196-
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build [..]-Cembed-bitcode=no[..]`")
197+
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build2 [..]-C embed-bitcode=no[..]`")
198+
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build [..]-C embed-bitcode=no[..]`")
197199
.with_stderr_contains(
198-
"[..]`rustc[..]--crate-name build_script_build [..]-Cembed-bitcode=no[..]`",
200+
"[..]`rustc[..]--crate-name build_script_build [..]-C embed-bitcode=no[..]`",
199201
)
200202
// proc macro deps are the same as build deps here
201203
.with_stderr_contains(
202-
"[..]`rustc[..]--crate-name dep_proc_macro2 [..]-Cembed-bitcode=no[..]`",
204+
"[..]`rustc[..]--crate-name dep_proc_macro2 [..]-C embed-bitcode=no[..]`",
203205
)
204206
.with_stderr_contains(
205-
"[..]`rustc[..]--crate-name dep_proc_macro [..]-Cembed-bitcode=no[..]`",
207+
"[..]`rustc[..]--crate-name dep_proc_macro [..]-C embed-bitcode=no[..]`",
206208
)
207209
.with_stderr_contains("[..]`rustc[..]--crate-name test [..]--crate-type bin[..]-C lto[..]`")
208210
.with_stderr_contains(
209211
"[..]`rustc[..]--crate-name test [..]--crate-type cdylib[..]-C lto[..]`",
210212
)
211213
.with_stderr_contains("[..]`rustc[..]--crate-name dep_shared [..]`")
212214
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C lto[..]")
213-
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-Clinker-plugin-lto[..]")
214-
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-Cembed-bitcode[..]")
215+
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C linker-plugin-lto[..]")
216+
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C embed-bitcode[..]")
215217
.run();
216218
}
217219

@@ -252,9 +254,9 @@ fn off_in_manifest_works() {
252254
[DOWNLOADING] [..]
253255
[DOWNLOADED] [..]
254256
[COMPILING] bar v0.0.1
255-
[RUNNING] `rustc --crate-name bar [..]--crate-type lib [..]-Cembed-bitcode=no[..]
257+
[RUNNING] `rustc --crate-name bar [..]--crate-type lib [..]-C embed-bitcode=no[..]
256258
[COMPILING] test [..]
257-
[RUNNING] `rustc --crate-name test [..]--crate-type lib [..]-Cembed-bitcode=no[..]
259+
[RUNNING] `rustc --crate-name test [..]--crate-type lib [..]-C embed-bitcode=no[..]
258260
[RUNNING] `rustc --crate-name test src/main.rs [..]--crate-type bin [..]-C lto=off[..]
259261
[FINISHED] [..]
260262
",
@@ -283,7 +285,7 @@ fn between_builds() {
283285
.with_stderr(
284286
"\
285287
[COMPILING] test [..]
286-
[RUNNING] `rustc [..]--crate-type lib[..]-Clinker-plugin-lto[..]
288+
[RUNNING] `rustc [..]--crate-type lib[..]-C linker-plugin-lto[..]
287289
[FINISHED] [..]
288290
",
289291
)
@@ -447,9 +449,9 @@ fn verify_lto(output: &Output, krate: &str, krate_info: &str, expected_lto: Lto)
447449
}
448450
} else if line.contains("-C lto") {
449451
Lto::Run(None)
450-
} else if line.contains("-Clinker-plugin-lto") {
452+
} else if line.contains("-C linker-plugin-lto") {
451453
Lto::OnlyBitcode
452-
} else if line.contains("-Cembed-bitcode=no") {
454+
} else if line.contains("-C embed-bitcode=no") {
453455
Lto::OnlyObject
454456
} else {
455457
Lto::ObjectAndBitcode
@@ -491,8 +493,8 @@ fn cdylib_and_rlib() {
491493
[FRESH] registry-shared v0.0.1
492494
[FRESH] bar v0.0.0 [..]
493495
[COMPILING] foo [..]
494-
[RUNNING] `rustc --crate-name foo [..]-Cembed-bitcode=no --test[..]
495-
[RUNNING] `rustc --crate-name a [..]-Cembed-bitcode=no --test[..]
496+
[RUNNING] `rustc --crate-name foo [..]-C embed-bitcode=no --test[..]
497+
[RUNNING] `rustc --crate-name a [..]-C embed-bitcode=no --test[..]
496498
[FINISHED] [..]
497499
[RUNNING] [..]
498500
[RUNNING] [..]
@@ -512,16 +514,19 @@ fn cdylib_and_rlib() {
512514
p.cargo("test --release -v --manifest-path bar/Cargo.toml")
513515
.with_stderr_unordered(
514516
"\
515-
[FRESH] registry v0.0.1
516-
[FRESH] registry-shared v0.0.1
517+
[COMPILING] registry v0.0.1
518+
[COMPILING] registry-shared v0.0.1
519+
[RUNNING] `rustc --crate-name registry [..]-C embed-bitcode=no[..]
520+
[RUNNING] `rustc --crate-name registry_shared [..]-C embed-bitcode=no[..]
517521
[COMPILING] bar [..]
518-
[RUNNING] `rustc --crate-name bar [..]-Cembed-bitcode=no --test[..]
519-
[RUNNING] `rustc --crate-name b [..]-Cembed-bitcode=no --test[..]
522+
[RUNNING] `rustc --crate-name bar [..]--crate-type cdylib --crate-type rlib [..]-C embed-bitcode=no[..]
523+
[RUNNING] `rustc --crate-name bar [..]-C embed-bitcode=no --test[..]
524+
[RUNNING] `rustc --crate-name b [..]-C embed-bitcode=no --test[..]
520525
[FINISHED] [..]
521-
[RUNNING] [..]
522-
[RUNNING] [..]
526+
[RUNNING] [..]target/release/deps/bar-[..]
527+
[RUNNING] [..]target/release/deps/b-[..]
523528
[DOCTEST] bar
524-
[RUNNING] `rustdoc --crate-type cdylib --crate-type rlib --test [..]
529+
[RUNNING] `rustdoc --crate-type cdylib --crate-type rlib --test [..]-C embed-bitcode=no[..]
525530
",
526531
)
527532
.run();
@@ -547,8 +552,8 @@ fn dylib() {
547552
[FRESH] registry-shared v0.0.1
548553
[FRESH] bar v0.0.0 [..]
549554
[COMPILING] foo [..]
550-
[RUNNING] `rustc --crate-name foo [..]-Cembed-bitcode=no --test[..]
551-
[RUNNING] `rustc --crate-name a [..]-Cembed-bitcode=no --test[..]
555+
[RUNNING] `rustc --crate-name foo [..]-C embed-bitcode=no --test[..]
556+
[RUNNING] `rustc --crate-name a [..]-C embed-bitcode=no --test[..]
552557
[FINISHED] [..]
553558
[RUNNING] [..]
554559
[RUNNING] [..]
@@ -560,9 +565,9 @@ fn dylib() {
560565
"\
561566
[COMPILING] registry-shared v0.0.1
562567
[FRESH] registry v0.0.1
563-
[RUNNING] `rustc --crate-name registry_shared [..]-Cembed-bitcode=no[..]
568+
[RUNNING] `rustc --crate-name registry_shared [..]-C embed-bitcode=no[..]
564569
[COMPILING] bar [..]
565-
[RUNNING] `rustc --crate-name bar [..]--crate-type dylib [..]-Cembed-bitcode=no[..]
570+
[RUNNING] `rustc --crate-name bar [..]--crate-type dylib [..]-C embed-bitcode=no[..]
566571
[FINISHED] [..]
567572
",
568573
)
@@ -573,8 +578,8 @@ fn dylib() {
573578
[FRESH] registry-shared v0.0.1
574579
[FRESH] registry v0.0.1
575580
[COMPILING] bar [..]
576-
[RUNNING] `rustc --crate-name bar [..]-Cembed-bitcode=no --test[..]
577-
[RUNNING] `rustc --crate-name b [..]-Cembed-bitcode=no --test[..]
581+
[RUNNING] `rustc --crate-name bar [..]-C embed-bitcode=no --test[..]
582+
[RUNNING] `rustc --crate-name b [..]-C embed-bitcode=no --test[..]
578583
[FINISHED] [..]
579584
[RUNNING] [..]
580585
[RUNNING] [..]
@@ -625,7 +630,7 @@ fn test_profile() {
625630
[COMPILING] bar v0.0.1
626631
[RUNNING] `rustc --crate-name bar [..]crate-type lib[..]
627632
[COMPILING] foo [..]
628-
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -Cembed-bitcode=no[..]
633+
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -C linker-plugin-lto[..]
629634
[RUNNING] `rustc --crate-name foo [..]--emit=dep-info,link -C lto=thin [..]--test[..]
630635
[FINISHED] [..]
631636
[RUNNING] [..]
@@ -678,12 +683,66 @@ fn dev_profile() {
678683
[COMPILING] bar v0.0.1
679684
[RUNNING] `rustc --crate-name bar [..]crate-type lib[..]
680685
[COMPILING] foo [..]
681-
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -Clinker-plugin-lto [..]
682-
[RUNNING] `rustc --crate-name foo [..]--emit=dep-info,link -Cembed-bitcode=no [..]--test[..]
686+
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no [..]
687+
[RUNNING] `rustc --crate-name foo [..]--emit=dep-info,link -C embed-bitcode=no [..]--test[..]
683688
[FINISHED] [..]
684689
[RUNNING] [..]
685690
[DOCTEST] foo
686691
[RUNNING] `rustdoc [..]
687692
")
688693
.run();
689694
}
695+
696+
#[cargo_test]
697+
fn doctest() {
698+
let p = project()
699+
.file(
700+
"Cargo.toml",
701+
r#"
702+
[package]
703+
name = "foo"
704+
version = "0.1.0"
705+
edition = "2018"
706+
707+
[profile.release]
708+
lto = true
709+
710+
[dependencies]
711+
bar = { path = "bar" }
712+
"#,
713+
)
714+
.file(
715+
"src/lib.rs",
716+
r#"
717+
/// Foo!
718+
///
719+
/// ```
720+
/// foo::foo();
721+
/// ```
722+
pub fn foo() { bar::bar(); }
723+
"#,
724+
)
725+
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
726+
.file(
727+
"bar/src/lib.rs",
728+
r#"
729+
pub fn bar() { println!("hi!"); }
730+
"#,
731+
)
732+
.build();
733+
734+
p.cargo("test --doc --release -v")
735+
.with_stderr_contains("[..]`rustc --crate-name bar[..]-C embed-bitcode=no[..]")
736+
.with_stderr_contains("[..]`rustc --crate-name foo[..]-C embed-bitcode=no[..]")
737+
// embed-bitcode should be harmless here
738+
.with_stderr_contains("[..]`rustdoc [..]-C embed-bitcode=no[..]")
739+
.run();
740+
741+
// Try with bench profile.
742+
p.cargo("test --doc --release -v")
743+
.env("CARGO_PROFILE_BENCH_LTO", "true")
744+
.with_stderr_contains("[..]`rustc --crate-name bar[..]-C linker-plugin-lto[..]")
745+
.with_stderr_contains("[..]`rustc --crate-name foo[..]-C linker-plugin-lto[..]")
746+
.with_stderr_contains("[..]`rustdoc [..]-C lto[..]")
747+
.run();
748+
}

0 commit comments

Comments
 (0)