From 688c11216aca1d7449b07b3ebbcee3ba114d0d51 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 17 Jul 2019 01:16:49 +0200 Subject: [PATCH 1/5] Override Cycle::try_fold --- src/libcore/iter/adapters/mod.rs | 30 ++++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 12 ++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index c2edcd22f953b..07526e58fd7ef 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -387,6 +387,36 @@ impl Iterator for Cycle where I: Clone + Iterator { _ => (usize::MAX, None) } } + + #[inline] + fn try_fold(&mut self, mut acc: Acc, mut f: F) -> R + where + F: FnMut(Acc, Self::Item) -> R, + R: Try, + { + // fully iterate the current iterator. this is necessary because + // `self.iter` may be empty even when `self.orig` isn't + acc = self.iter.try_fold(acc, &mut f)?; + self.iter = self.orig.clone(); + + // complete a full cycle, keeping track of whether the cycled + // iterator is empty or not. we need to return early in case + // of an empty iterator to prevent an infinite loop + let mut is_empty = true; + acc = self.iter.try_fold(acc, |acc, x| { + is_empty = false; + f(acc, x) + })?; + + if is_empty { + return Try::from_ok(acc); + } + + loop { + self.iter = self.orig.clone(); + acc = self.iter.try_fold(acc, &mut f)?; + } + } } #[stable(feature = "fused", since = "1.26.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b7b0849e2129b..194975661067c 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1015,6 +1015,18 @@ fn test_cycle() { assert_eq!(empty::().cycle().fold(0, |acc, x| acc + x), 0); assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4); + + assert_eq!((0..10).cycle().take(5).sum::(), 10); + assert_eq!((0..10).cycle().take(15).sum::(), 55); + assert_eq!((0..10).cycle().take(25).sum::(), 100); + + let mut iter = (0..10).cycle(); + iter.nth(14); + assert_eq!(iter.take(8).sum::(), 38); + + let mut iter = (0..10).cycle(); + iter.nth(9); + assert_eq!(iter.take(3).sum::(), 3); } #[test] From e9e45c59a7a5a1ea500fd667a56c0d0ab101365a Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 12 Aug 2019 09:34:41 -0700 Subject: [PATCH 2/5] Hash the remapped sysroot instead of the original. This will help reproducible builds, as the sysroot depends on the working directory. --- src/librustc/session/config.rs | 11 +++++++++-- .../run-make-fulldeps/reproducible-build-2/Makefile | 12 +++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3536b2aa8fffe..0a0f72a72c00c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -395,7 +395,8 @@ top_level_options!( output_types: OutputTypes [TRACKED], search_paths: Vec [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], - maybe_sysroot: Option [TRACKED], + maybe_sysroot: Option [UNTRACKED], + maybe_sysroot_remapped: Option [TRACKED], target_triple: TargetTriple [TRACKED], @@ -610,6 +611,7 @@ impl Default for Options { output_types: OutputTypes(BTreeMap::new()), search_paths: vec![], maybe_sysroot: None, + maybe_sysroot_remapped: None, target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, @@ -2453,7 +2455,7 @@ pub fn build_session_options_and_crate_config( let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix = matches + let remap_path_prefix: Vec<(PathBuf, PathBuf)> = matches .opt_strs("remap-path-prefix") .into_iter() .map(|remap| { @@ -2470,6 +2472,10 @@ pub fn build_session_options_and_crate_config( }) .collect(); + let sysroot_remapped_opt = sysroot_opt + .clone() + .map(|sysroot| FilePathMapping::new(remap_path_prefix.clone()).map_prefix(sysroot).0); + ( Options { crate_types, @@ -2481,6 +2487,7 @@ pub fn build_session_options_and_crate_config( output_types: OutputTypes(output_types), search_paths, maybe_sysroot: sysroot_opt, + maybe_sysroot_remapped: sysroot_remapped_opt, target_triple, test, incremental, diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile index b96954fea0d1e..45c9a7427230b 100644 --- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile @@ -5,7 +5,8 @@ # Objects are reproducible but their path is not. all: \ - fat_lto + fat_lto \ + sysroot fat_lto: rm -rf $(TMPDIR) && mkdir $(TMPDIR) @@ -14,3 +15,12 @@ fat_lto: cp $(TMPDIR)/reproducible-build $(TMPDIR)/reproducible-build-a $(RUSTC) reproducible-build.rs -C lto=fat cmp "$(TMPDIR)/reproducible-build-a" "$(TMPDIR)/reproducible-build" || exit 1 + +sysroot: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot + cp -r $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 From 692c0bf4ff8d1f551850962bd8d3af62033dee39 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 13 Aug 2019 09:12:06 -0700 Subject: [PATCH 3/5] Do not track the sysroot. As suggested by @alexcrichton, the sysroot only loads libraries that are themselves tracked. --- src/librustc/session/config.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0a0f72a72c00c..8e3b910e0da3a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -396,7 +396,6 @@ top_level_options!( search_paths: Vec [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [UNTRACKED], - maybe_sysroot_remapped: Option [TRACKED], target_triple: TargetTriple [TRACKED], @@ -611,7 +610,6 @@ impl Default for Options { output_types: OutputTypes(BTreeMap::new()), search_paths: vec![], maybe_sysroot: None, - maybe_sysroot_remapped: None, target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, @@ -2455,7 +2453,7 @@ pub fn build_session_options_and_crate_config( let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix: Vec<(PathBuf, PathBuf)> = matches + let remap_path_prefix = matches .opt_strs("remap-path-prefix") .into_iter() .map(|remap| { @@ -2472,10 +2470,6 @@ pub fn build_session_options_and_crate_config( }) .collect(); - let sysroot_remapped_opt = sysroot_opt - .clone() - .map(|sysroot| FilePathMapping::new(remap_path_prefix.clone()).map_prefix(sysroot).0); - ( Options { crate_types, @@ -2487,7 +2481,6 @@ pub fn build_session_options_and_crate_config( output_types: OutputTypes(output_types), search_paths, maybe_sysroot: sysroot_opt, - maybe_sysroot_remapped: sysroot_remapped_opt, target_triple, test, incremental, From c1758d5918b8c5e99b34c83e83266dc5f79b0da7 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 14 Aug 2019 18:53:22 +0300 Subject: [PATCH 4/5] rustc_codegen_utils: account for 1-indexed anonymous lifetimes in v0 mangling. --- src/librustc_codegen_utils/symbol_names/v0.rs | 12 ++++++++++-- src/test/ui/symbol-names/impl1.rs | 6 +++--- src/test/ui/symbol-names/impl1.v0.stderr | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs index 47601da8b7b23..8d6a1d757e014 100644 --- a/src/librustc_codegen_utils/symbol_names/v0.rs +++ b/src/librustc_codegen_utils/symbol_names/v0.rs @@ -198,10 +198,14 @@ impl SymbolMangler<'tcx> { let lifetimes = regions.into_iter().map(|br| { match br { - ty::BrAnon(i) => i + 1, + ty::BrAnon(i) => { + // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`. + assert_ne!(i, 0); + i - 1 + }, _ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value), } - }).max().unwrap_or(0); + }).max().map_or(0, |max| max + 1); self.push_opt_integer_62("G", lifetimes as u64); lifetime_depths.end += lifetimes; @@ -297,6 +301,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Late-bound lifetimes use indices starting at 1, // see `BinderLevel` for more details. ty::ReLateBound(debruijn, ty::BrAnon(i)) => { + // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`. + assert_ne!(i, 0); + let i = i - 1; + let binder = &self.binders[self.binders.len() - 1 - debruijn.index()]; let depth = binder.lifetime_depths.start + i; diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 52bb118fa23a0..137b72dcd9c44 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -64,9 +64,9 @@ fn main() { //[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) - //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) - //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) + //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) + //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) + //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) #[rustc_def_path] //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 1c4b256c9e933..e024799df867c 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -46,19 +46,19 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) +error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) +error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) +error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] From 191603653b90e25d8e0e67f125aec523412b51f9 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 15 Aug 2019 12:55:03 -0700 Subject: [PATCH 5/5] Modify librustc_llvm to pass -DNDEBUG while compiling. Currently, librustc_llvm builds are not reproducible because the LLVM files it compiles use the debug version of llvm_unreachable, which uses __FILE__. To fix this, we propagate NDEBUG from bootstrap if applicable and use it when compiling librustc_llvm. --- src/bootstrap/compile.rs | 3 +++ src/librustc_llvm/build.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4cd793adaf574..8bd14fbce35aa 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -795,6 +795,9 @@ pub fn build_codegen_backend(builder: &Builder<'_>, if builder.config.llvm_use_libcxx { cargo.env("LLVM_USE_LIBCXX", "1"); } + if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo { + cargo.env("LLVM_NDEBUG", "1"); + } } _ => panic!("unknown backend: {}", backend), } diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 16cdbb7dd4d39..c84ec4e560138 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -151,6 +151,10 @@ fn main() { cfg.define("LLVM_RUSTLLVM", None); } + if env::var_os("LLVM_NDEBUG").is_some() { + cfg.define("NDEBUG", None); + } + build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); cfg.file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp")