Rollup merge of #64509 - varkor:convert-identity-doc-fixes, r=Centril
Make some adjustments to the documentation for `std::convert::identity`
Fixes some extra blank lines and makes some minor tweaks to the wording.
diff --git a/Cargo.lock b/Cargo.lock
index 679a024..0fe3138 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -201,7 +201,9 @@
name = "build-manifest"
version = "0.1.0"
dependencies = [
+ "reqwest",
"serde",
+ "serde_json",
"toml",
]
@@ -232,9 +234,9 @@
[[package]]
name = "byteorder"
-version = "1.2.7"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
+checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
[[package]]
name = "bytes"
@@ -2065,7 +2067,7 @@
"hex",
"log",
"num-traits",
- "rand 0.6.1",
+ "rand 0.7.0",
"rustc-workspace-hack",
"rustc_version",
"shell-escape",
@@ -3017,7 +3019,7 @@
"log",
"measureme",
"num_cpus",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
"polonius-engine",
"rustc-rayon",
"rustc-rayon-core",
@@ -3253,7 +3255,6 @@
name = "rustc-workspace-hack"
version = "1.0.0"
dependencies = [
- "byteorder",
"crossbeam-utils 0.6.5",
"serde",
"serde_json",
@@ -3311,7 +3312,7 @@
"log",
"memmap",
"num_cpus",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
"rustc",
"rustc_apfloat",
"rustc_codegen_utils",
@@ -3354,7 +3355,7 @@
"jobserver",
"lazy_static 1.3.0",
"log",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
"rustc-hash",
"rustc-rayon",
"rustc-rayon-core",
@@ -4261,13 +4262,13 @@
[[package]]
name = "tempfile"
-version = "3.0.5"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
+checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"libc",
- "rand 0.6.1",
+ "rand 0.7.0",
"redox_syscall",
"remove_dir_all",
"winapi 0.3.6",
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 500d576..076bcd8 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2000,6 +2000,8 @@
}
fn run(self, builder: &Builder<'_>) {
+ // This gets called by `promote-release`
+ // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
let mut cmd = builder.tool_cmd(Tool::BuildManifest);
if builder.config.dry_run {
return;
@@ -2010,10 +2012,14 @@
let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
});
- let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
- panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
- });
- let pass = t!(fs::read_to_string(&file));
+ let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
+ let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
+ panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
+ });
+ t!(fs::read_to_string(&file))
+ } else {
+ String::new()
+ };
let today = output(Command::new("date").arg("+%Y-%m-%d"));
diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index ac6b344..da0a899 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -147,8 +147,15 @@
git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
cd rust-toolstate
python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" ""
+ # Only check maintainers if this build is supposed to publish toolstate.
+ # Builds that are not supposed to publish don't have the access token.
+ if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
+ TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py"
+ fi
cd ..
rm -rf rust-toolstate
+ env:
+ TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check'))
displayName: Verify the publish_toolstate script works
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index d3af910..0cb91ba 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -3,7 +3,7 @@
use core::borrow::Borrow;
use core::cmp::Ordering::{self, Less, Greater, Equal};
-use core::cmp::max;
+use core::cmp::{max, min};
use core::fmt::{self, Debug};
use core::iter::{Peekable, FromIterator, FusedIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds};
@@ -187,8 +187,8 @@
}
enum IntersectionInner<'a, T: 'a> {
Stitch {
- small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets
- other_iter: Iter<'a, T>,
+ a: Iter<'a, T>,
+ b: Iter<'a, T>,
},
Search {
small_iter: Iter<'a, T>,
@@ -201,12 +201,12 @@
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => f
.debug_tuple("Intersection")
- .field(&small_iter)
- .field(&other_iter)
+ .field(&a)
+ .field(&b)
.finish(),
IntersectionInner::Search {
small_iter,
@@ -397,8 +397,8 @@
// Iterate both sets jointly, spotting matches along the way.
Intersection {
inner: IntersectionInner::Stitch {
- small_iter: small.iter(),
- other_iter: other.iter(),
+ a: small.iter(),
+ b: other.iter(),
},
}
} else {
@@ -1221,11 +1221,11 @@
Intersection {
inner: match &self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => IntersectionInner::Stitch {
- small_iter: small_iter.clone(),
- other_iter: other_iter.clone(),
+ a: a.clone(),
+ b: b.clone(),
},
IntersectionInner::Search {
small_iter,
@@ -1245,16 +1245,16 @@
fn next(&mut self) -> Option<&'a T> {
match &mut self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => {
- let mut small_next = small_iter.next()?;
- let mut other_next = other_iter.next()?;
+ let mut a_next = a.next()?;
+ let mut b_next = b.next()?;
loop {
- match Ord::cmp(small_next, other_next) {
- Less => small_next = small_iter.next()?,
- Greater => other_next = other_iter.next()?,
- Equal => return Some(small_next),
+ match Ord::cmp(a_next, b_next) {
+ Less => a_next = a.next()?,
+ Greater => b_next = b.next()?,
+ Equal => return Some(a_next),
}
}
}
@@ -1272,7 +1272,7 @@
fn size_hint(&self) -> (usize, Option<usize>) {
let min_len = match &self.inner {
- IntersectionInner::Stitch { small_iter, .. } => small_iter.len(),
+ IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
IntersectionInner::Search { small_iter, .. } => small_iter.len(),
};
(0, Some(min_len))
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 370e5cf..9e6ed92 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -117,7 +117,7 @@
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
#![feature(rustc_const_unstable)]
-#![feature(const_vec_new)]
+#![cfg_attr(bootstrap, feature(const_vec_new))]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
#![feature(alloc_layout_extra)]
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index cf025ee..ee75fc2 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -113,13 +113,38 @@
}
impl<T> RawVec<T, Global> {
+ /// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform
+ /// to `min_const_fn` and so they cannot be called in `min_const_fn`s either.
+ ///
+ /// If you change `RawVec<T>::new` or dependencies, please take care to not
+ /// introduce anything that would truly violate `min_const_fn`.
+ ///
+ /// NOTE: We could avoid this hack and check conformance with some
+ /// `#[rustc_force_min_const_fn]` attribute which requires conformance
+ /// with `min_const_fn` but does not necessarily allow calling it in
+ /// `stable(...) const fn` / user code not enabling `foo` when
+ /// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
+ pub const NEW: Self = Self::new();
+
/// Creates the biggest possible `RawVec` (on the system heap)
/// without allocating. If `T` has positive size, then this makes a
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
/// delayed allocation.
pub const fn new() -> Self {
- Self::new_in(Global)
+ // FIXME(Centril): Reintegrate this with `fn new_in` when we can.
+
+ // `!0` is `usize::MAX`. This branch should be stripped at compile time.
+ // FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
+ //let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+
+ // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
+ RawVec {
+ ptr: Unique::empty(),
+ // FIXME(mark-i-m): use `cap` when ifs are allowed in const
+ cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
+ a: Global,
+ }
}
/// Creates a `RawVec` (on the system heap) with exactly the
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index b65f191..1166e7b 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -369,7 +369,7 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_string_new")]
+ #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))]
pub const fn new() -> String {
String { vec: Vec::new() }
}
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index 62ccb53..35db18c 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -91,6 +91,17 @@
}
#[test]
+fn test_intersection_size_hint() {
+ let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
+ let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
+ let mut iter = x.intersection(&y);
+ assert_eq!(iter.size_hint(), (0, Some(2)));
+ assert_eq!(iter.next(), Some(&3));
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+}
+
+#[test]
fn test_difference() {
fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
check(a, b, expected, |x, y, f| x.difference(y).all(f))
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index c513658..405969a 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -314,10 +314,10 @@
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_vec_new")]
+ #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))]
pub const fn new() -> Vec<T> {
Vec {
- buf: RawVec::new(),
+ buf: RawVec::NEW,
len: 0,
}
}
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 66071d6..0834faf 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -30,8 +30,8 @@
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
backtrace = "0.3.3"
-parking_lot = "0.7"
-byteorder = { version = "1.1", features = ["i128"]}
+parking_lot = "0.9"
+byteorder = { version = "1.3" }
chalk-engine = { version = "0.9.0", default-features=false }
rustc_fs_util = { path = "../librustc_fs_util" }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index c74b2fe..723855c 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -7,6 +7,7 @@
use crate::session::search_paths::SearchPath;
use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
use rustc_target::spec::{Target, TargetTriple};
@@ -19,6 +20,7 @@
use syntax::parse::token;
use syntax::symbol::{sym, Symbol};
use syntax::feature_gate::UnstableFeatures;
+use syntax::source_map::SourceMap;
use errors::emitter::HumanReadableErrorType;
use errors::{ColorConfig, FatalError, Handler};
@@ -1850,11 +1852,20 @@
opts
}
+struct NullEmitter;
+
+impl errors::emitter::Emitter for NullEmitter {
+ fn emit_diagnostic(&mut self, _: &errors::DiagnosticBuilder<'_>) {}
+}
+
// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
syntax::with_default_globals(move || {
let cfg = cfgspecs.into_iter().map(|s| {
- let sess = ParseSess::new(FilePathMapping::empty());
+
+ let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+ let handler = Handler::with_emitter(false, None, Box::new(NullEmitter));
+ let sess = ParseSess::with_span_handler(handler, cm);
let filename = FileName::cfg_spec_source_code(&s);
let mut parser = new_parser_from_source_str(&sess, filename, s.to_string());
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 25d921b..0155803 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -205,26 +205,24 @@
fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
hir_id: hir::HirId,
mut_access: bool) {
- if cfg!(debug_assertions) {
- if let Some(local_id_root) = local_id_root {
- if hir_id.owner != local_id_root.index {
- ty::tls::with(|tcx| {
- bug!("node {} with HirId::owner {:?} cannot be placed in \
- TypeckTables with local_id_root {:?}",
- tcx.hir().node_to_string(hir_id),
- DefId::local(hir_id.owner),
- local_id_root)
- });
- }
- } else {
- // We use "Null Object" TypeckTables in some of the analysis passes.
- // These are just expected to be empty and their `local_id_root` is
- // `None`. Therefore we cannot verify whether a given `HirId` would
- // be a valid key for the given table. Instead we make sure that
- // nobody tries to write to such a Null Object table.
- if mut_access {
- bug!("access to invalid TypeckTables")
- }
+ if let Some(local_id_root) = local_id_root {
+ if hir_id.owner != local_id_root.index {
+ ty::tls::with(|tcx| {
+ bug!("node {} with HirId::owner {:?} cannot be placed in \
+ TypeckTables with local_id_root {:?}",
+ tcx.hir().node_to_string(hir_id),
+ DefId::local(hir_id.owner),
+ local_id_root)
+ });
+ }
+ } else {
+ // We use "Null Object" TypeckTables in some of the analysis passes.
+ // These are just expected to be empty and their `local_id_root` is
+ // `None`. Therefore we cannot verify whether a given `HirId` would
+ // be a valid key for the given table. Instead we make sure that
+ // nobody tries to write to such a Null Object table.
+ if mut_access {
+ bug!("access to invalid TypeckTables")
}
}
}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 41e4295..5ca819e 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1938,9 +1938,15 @@
pub vis: Visibility,
}
-/// The definition of an abstract data type -- a struct or enum.
+/// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`.
///
/// These are all interned (by `intern_adt_def`) into the `adt_defs` table.
+///
+/// The initialism *"Adt"* stands for an [*algebraic data type (ADT)*][adt].
+/// This is slightly wrong because `union`s are not ADTs.
+/// Moreover, Rust only allows recursive data types through indirection.
+///
+/// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type
pub struct AdtDef {
/// `DefId` of the struct, enum or union item.
pub did: DefId,
@@ -2894,6 +2900,13 @@
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId)
-> Option<ImplOverlapKind>
{
+ // If either trait impl references an error, they're allowed to overlap,
+ // as one of them essentially doesn't exist.
+ if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) ||
+ self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) {
+ return Some(ImplOverlapKind::Permitted);
+ }
+
let is_legit = if self.features().overlapping_marker_traits {
let trait1_is_empty = self.impl_trait_ref(def_id1)
.map_or(false, |trait_ref| {
diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs
index cc856ba..645707c 100644
--- a/src/librustc_asan/build.rs
+++ b/src/librustc_asan/build.rs
@@ -4,6 +4,7 @@
use cmake::Config;
fn main() {
+ println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
return;
}
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 9f2c303..34e39af 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -226,21 +226,21 @@
for &(name, _) in back::write::RELOC_MODEL_ARGS.iter() {
println!(" {}", name);
}
- println!("");
+ println!();
}
PrintRequest::CodeModels => {
println!("Available code models:");
for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter(){
println!(" {}", name);
}
- println!("");
+ println!();
}
PrintRequest::TlsModels => {
println!("Available TLS models:");
for &(name, _) in back::write::TLS_MODEL_ARGS.iter(){
println!(" {}", name);
}
- println!("");
+ println!();
}
req => llvm_util::print(req, sess),
}
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 89a6ec2..bc028d6 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -17,8 +17,8 @@
log = "0.4.5"
libc = "0.2.44"
jobserver = "0.1.11"
-parking_lot = "0.7"
-tempfile = "3.0.5"
+parking_lot = "0.9"
+tempfile = "3.1"
rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 288676c..be9f79c 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -26,5 +26,5 @@
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
[dependencies.parking_lot]
-version = "0.7"
+version = "0.9"
features = ["nightly"]
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 005cdcf..8c5d853 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -134,8 +134,11 @@
impl Callbacks for TimePassesCallbacks {
fn config(&mut self, config: &mut interface::Config) {
+ // If a --prints=... option has been given, we don't print the "total"
+ // time because it will mess up the --prints output. See #64339.
self.time_passes =
- config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time;
+ config.opts.prints.is_empty() &&
+ (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time);
}
}
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 21ea476..c397509 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -370,7 +370,8 @@
right_pos: Option<BytePos>) {
match value.node {
ast::ExprKind::Paren(ref inner) => {
- if !Self::is_expr_parens_necessary(inner, followed_by_block) {
+ if !Self::is_expr_parens_necessary(inner, followed_by_block) &&
+ value.attrs.is_empty() {
let expr_text = if let Ok(snippet) = cx.sess().source_map()
.span_to_snippet(value.span) {
snippet
diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs
index d5f3e37..73720d8 100644
--- a/src/librustc_lsan/build.rs
+++ b/src/librustc_lsan/build.rs
@@ -4,6 +4,7 @@
use cmake::Config;
fn main() {
+ println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
return;
}
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index e027360..0691390 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -24,6 +24,6 @@
rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
-byteorder = { version = "1.1", features = ["i128"] }
+byteorder = { version = "1.3" }
rustc_apfloat = { path = "../librustc_apfloat" }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 57ddaa4..3f53f84 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -134,9 +134,8 @@
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
cid: GlobalId<'tcx>,
body: &'mir mir::Body<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
- debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env);
+ debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
let tcx = ecx.tcx.tcx;
let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?;
assert!(!layout.is_unsized());
@@ -162,7 +161,6 @@
ecx,
cid.instance.def_id(),
ret,
- param_env,
)?;
debug!("eval_body_using_ecx done: {:?}", *ret);
@@ -658,7 +656,7 @@
let res = ecx.load_mir(cid.instance.def, cid.promoted);
res.and_then(
- |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env)
+ |body| eval_body_using_ecx(&mut ecx, cid, body)
).and_then(|place| {
Ok(RawConst {
alloc_id: place.ptr.assert_ptr().alloc_id,
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 4cbbc0f..95647ce 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -3,7 +3,7 @@
//! After a const evaluation has computed a value, before we destroy the const evaluator's session
//! memory, we need to extract all memory allocations to the global memory pool so they stay around.
-use rustc::ty::{Ty, TyCtxt, ParamEnv, self};
+use rustc::ty::{Ty, self};
use rustc::mir::interpret::{InterpResult, ErrorHandled};
use rustc::hir;
use rustc::hir::def_id::DefId;
@@ -11,32 +11,29 @@
use rustc_data_structures::fx::FxHashSet;
use syntax::ast::Mutability;
-use syntax_pos::Span;
use super::{
- ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, Scalar,
+ ValueVisitor, MemoryKind, AllocId, MPlaceTy, Scalar,
};
use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext};
struct InternVisitor<'rt, 'mir, 'tcx> {
- /// previously encountered safe references
- ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
+ /// The ectx from which we intern.
ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
- param_env: ParamEnv<'tcx>,
+ /// Previously encountered safe references.
+ ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
+ /// A list of all encountered allocations. After type-based interning, we traverse this list to
+ /// also intern allocations that are only referenced by a raw pointer or inside a union.
+ leftover_allocations: &'rt mut FxHashSet<AllocId>,
/// The root node of the value that we're looking at. This field is never mutated and only used
/// for sanity assertions that will ICE when `const_qualif` screws up.
mode: InternMode,
/// This field stores the mutability of the value *currently* being checked.
- /// It is set to mutable when an `UnsafeCell` is encountered
- /// When recursing across a reference, we don't recurse but store the
- /// value to be checked in `ref_tracking` together with the mutability at which we are checking
- /// the value.
- /// When encountering an immutable reference, we treat everything as immutable that is behind
- /// it.
+ /// When encountering a mutable reference, we determine the pointee mutability
+ /// taking into account the mutability of the context: `& &mut i32` is entirely immutable,
+ /// despite the nested mutable reference!
+ /// The field gets updated when an `UnsafeCell` is encountered.
mutability: Mutability,
- /// A list of all encountered relocations. After type-based interning, we traverse this list to
- /// also intern allocations that are only referenced by a raw pointer or inside a union.
- leftover_relocations: &'rt mut FxHashSet<AllocId>,
}
#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
@@ -45,9 +42,10 @@
/// `static`. In a `static mut` we start out as mutable and thus can also contain further `&mut`
/// that will actually be treated as mutable.
Static,
- /// UnsafeCell is OK in the value of a constant, but not behind references in a constant
+ /// UnsafeCell is OK in the value of a constant: `const FOO = Cell::new(0)` creates
+ /// a new cell every time it is used.
ConstBase,
- /// `UnsafeCell` ICEs
+ /// `UnsafeCell` ICEs.
Const,
}
@@ -55,48 +53,100 @@
/// into the memory of other constants or statics
struct IsStaticOrFn;
+/// Intern an allocation without looking at its children.
+/// `mode` is the mode of the environment where we found this pointer.
+/// `mutablity` is the mutability of the place to be interned; even if that says
+/// `immutable` things might become mutable if `ty` is not frozen.
+/// `ty` can be `None` if there is no potential interior mutability
+/// to account for (e.g. for vtables).
+fn intern_shallow<'rt, 'mir, 'tcx>(
+ ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
+ leftover_allocations: &'rt mut FxHashSet<AllocId>,
+ mode: InternMode,
+ alloc_id: AllocId,
+ mutability: Mutability,
+ ty: Option<Ty<'tcx>>,
+) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
+ trace!(
+ "InternVisitor::intern {:?} with {:?}",
+ alloc_id, mutability,
+ );
+ // remove allocation
+ let tcx = ecx.tcx;
+ let memory = ecx.memory_mut();
+ let (kind, mut alloc) = match memory.alloc_map.remove(&alloc_id) {
+ Some(entry) => entry,
+ None => {
+ // Pointer not found in local memory map. It is either a pointer to the global
+ // map, or dangling.
+ // If the pointer is dangling (neither in local nor global memory), we leave it
+ // to validation to error. The `delay_span_bug` ensures that we don't forget such
+ // a check in validation.
+ if tcx.alloc_map.lock().get(alloc_id).is_none() {
+ tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
+ }
+ // treat dangling pointers like other statics
+ // just to stop trying to recurse into them
+ return Ok(Some(IsStaticOrFn));
+ },
+ };
+ // This match is just a canary for future changes to `MemoryKind`, which most likely need
+ // changes in this function.
+ match kind {
+ MemoryKind::Stack | MemoryKind::Vtable => {},
+ }
+ // Set allocation mutability as appropriate. This is used by LLVM to put things into
+ // read-only memory, and also by Miri when evluating other constants/statics that
+ // access this one.
+ if mode == InternMode::Static {
+ // When `ty` is `None`, we assume no interior mutability.
+ let frozen = ty.map_or(true, |ty| ty.is_freeze(
+ ecx.tcx.tcx,
+ ecx.param_env,
+ ecx.tcx.span,
+ ));
+ // For statics, allocation mutability is the combination of the place mutability and
+ // the type mutability.
+ // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
+ if mutability == Mutability::Immutable && frozen {
+ alloc.mutability = Mutability::Immutable;
+ } else {
+ // Just making sure we are not "upgrading" an immutable allocation to mutable.
+ assert_eq!(alloc.mutability, Mutability::Mutable);
+ }
+ } else {
+ // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
+ // But we still intern that as immutable as the memory cannot be changed once the
+ // initial value was computed.
+ // Constants are never mutable.
+ assert_eq!(
+ mutability, Mutability::Immutable,
+ "Something went very wrong: mutability requested for a constant"
+ );
+ alloc.mutability = Mutability::Immutable;
+ };
+ // link the alloc id to the actual allocation
+ let alloc = tcx.intern_const_alloc(alloc);
+ leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
+ tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
+ Ok(None)
+}
+
impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
- /// Intern an allocation without looking at its children
fn intern_shallow(
&mut self,
- ptr: Pointer,
+ alloc_id: AllocId,
mutability: Mutability,
+ ty: Option<Ty<'tcx>>,
) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
- trace!(
- "InternVisitor::intern {:?} with {:?}",
- ptr, mutability,
- );
- // remove allocation
- let tcx = self.ecx.tcx;
- let memory = self.ecx.memory_mut();
- let (kind, mut alloc) = match memory.alloc_map.remove(&ptr.alloc_id) {
- Some(entry) => entry,
- None => {
- // if the pointer is dangling (neither in local nor global memory), we leave it
- // to validation to error. The `delay_span_bug` ensures that we don't forget such
- // a check in validation.
- if tcx.alloc_map.lock().get(ptr.alloc_id).is_none() {
- tcx.sess.delay_span_bug(self.ecx.tcx.span, "tried to intern dangling pointer");
- }
- // treat dangling pointers like other statics
- // just to stop trying to recurse into them
- return Ok(Some(IsStaticOrFn));
- },
- };
- // This match is just a canary for future changes to `MemoryKind`, which most likely need
- // changes in this function.
- match kind {
- MemoryKind::Stack | MemoryKind::Vtable => {},
- }
- // Ensure llvm knows to only put this into immutable memory if the value is immutable either
- // by being behind a reference or by being part of a static or const without interior
- // mutability
- alloc.mutability = mutability;
- // link the alloc id to the actual allocation
- let alloc = tcx.intern_const_alloc(alloc);
- self.leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
- tcx.alloc_map.lock().set_alloc_id_memory(ptr.alloc_id, alloc);
- Ok(None)
+ intern_shallow(
+ self.ecx,
+ self.leftover_allocations,
+ self.mode,
+ alloc_id,
+ mutability,
+ ty,
+ )
}
}
@@ -119,14 +169,16 @@
) -> InterpResult<'tcx> {
if let Some(def) = mplace.layout.ty.ty_adt_def() {
if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() {
- // We are crossing over an `UnsafeCell`, we can mutate again
+ // We are crossing over an `UnsafeCell`, we can mutate again. This means that
+ // References we encounter inside here are interned as pointing to mutable
+ // allocations.
let old = std::mem::replace(&mut self.mutability, Mutability::Mutable);
assert_ne!(
self.mode, InternMode::Const,
"UnsafeCells are not allowed behind references in constants. This should have \
been prevented statically by const qualification. If this were allowed one \
- would be able to change a constant at one use site and other use sites may \
- arbitrarily decide to change, too.",
+ would be able to change a constant at one use site and other use sites could \
+ observe that mutation.",
);
let walked = self.walk_aggregate(mplace, fields);
self.mutability = old;
@@ -145,12 +197,13 @@
// Handle trait object vtables
if let Ok(meta) = value.to_meta() {
if let ty::Dynamic(..) =
- self.ecx.tcx.struct_tail_erasing_lifetimes(referenced_ty, self.param_env).sty
+ self.ecx.tcx.struct_tail_erasing_lifetimes(
+ referenced_ty, self.ecx.param_env).sty
{
if let Ok(vtable) = meta.unwrap().to_ptr() {
// explitly choose `Immutable` here, since vtables are immutable, even
// if the reference of the fat pointer is mutable
- self.intern_shallow(vtable, Mutability::Immutable)?;
+ self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
}
}
}
@@ -177,7 +230,7 @@
(InternMode::Const, hir::Mutability::MutMutable) => {
match referenced_ty.sty {
ty::Array(_, n)
- if n.eval_usize(self.ecx.tcx.tcx, self.param_env) == 0 => {}
+ if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
ty::Slice(_)
if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
_ => bug!("const qualif failed to prevent mutable references"),
@@ -195,21 +248,13 @@
(Mutability::Mutable, hir::Mutability::MutMutable) => Mutability::Mutable,
_ => Mutability::Immutable,
};
- // Compute the mutability of the allocation
- let intern_mutability = intern_mutability(
- self.ecx.tcx.tcx,
- self.param_env,
- mplace.layout.ty,
- self.ecx.tcx.span,
- mutability,
- );
// Recursing behind references changes the intern mode for constants in order to
// cause assertions to trigger if we encounter any `UnsafeCell`s.
let mode = match self.mode {
InternMode::ConstBase => InternMode::Const,
other => other,
};
- match self.intern_shallow(ptr, intern_mutability)? {
+ match self.intern_shallow(ptr.alloc_id, mutability, Some(mplace.layout.ty))? {
// No need to recurse, these are interned already and statics may have
// cycles, so we don't want to recurse there
Some(IsStaticOrFn) => {},
@@ -224,69 +269,45 @@
}
}
-/// Figure out the mutability of the allocation.
-/// Mutable if it has interior mutability *anywhere* in the type.
-fn intern_mutability<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- ty: Ty<'tcx>,
- span: Span,
- mutability: Mutability,
-) -> Mutability {
- let has_interior_mutability = !ty.is_freeze(tcx, param_env, span);
- if has_interior_mutability {
- Mutability::Mutable
- } else {
- mutability
- }
-}
-
pub fn intern_const_alloc_recursive(
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
def_id: DefId,
ret: MPlaceTy<'tcx>,
- // FIXME(oli-obk): can we scrap the param env? I think we can, the final value of a const eval
- // must always be monomorphic, right?
- param_env: ty::ParamEnv<'tcx>,
) -> InterpResult<'tcx> {
let tcx = ecx.tcx;
// this `mutability` is the mutability of the place, ignoring the type
- let (mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
+ let (base_mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
Some(hir::Mutability::MutImmutable) => (Mutability::Immutable, InternMode::Static),
- None => (Mutability::Immutable, InternMode::ConstBase),
// `static mut` doesn't care about interior mutability, it's mutable anyway
Some(hir::Mutability::MutMutable) => (Mutability::Mutable, InternMode::Static),
+ // consts, promoteds. FIXME: what about array lengths, array initializers?
+ None => (Mutability::Immutable, InternMode::ConstBase),
};
- // type based interning
- let mut ref_tracking = RefTracking::new((ret, mutability, base_intern_mode));
- let leftover_relocations = &mut FxHashSet::default();
-
- // This mutability is the combination of the place mutability and the type mutability. If either
- // is mutable, `alloc_mutability` is mutable. This exists because the entire allocation needs
- // to be mutable if it contains an `UnsafeCell` anywhere. The other `mutability` exists so that
- // the visitor does not treat everything outside the `UnsafeCell` as mutable.
- let alloc_mutability = intern_mutability(
- tcx.tcx, param_env, ret.layout.ty, tcx.span, mutability,
- );
+ // Type based interning.
+ // `ref_tracking` tracks typed references we have seen and still need to crawl for
+ // more typed information inside them.
+ // `leftover_allocations` collects *all* allocations we see, because some might not
+ // be available in a typed way. They get interned at the end.
+ let mut ref_tracking = RefTracking::new((ret, base_mutability, base_intern_mode));
+ let leftover_allocations = &mut FxHashSet::default();
// start with the outermost allocation
- InternVisitor {
- ref_tracking: &mut ref_tracking,
+ intern_shallow(
ecx,
- mode: base_intern_mode,
- leftover_relocations,
- param_env,
- mutability,
- }.intern_shallow(ret.ptr.to_ptr()?, alloc_mutability)?;
+ leftover_allocations,
+ base_intern_mode,
+ ret.ptr.to_ptr()?.alloc_id,
+ base_mutability,
+ Some(ret.layout.ty)
+ )?;
while let Some(((mplace, mutability, mode), _)) = ref_tracking.todo.pop() {
let interned = InternVisitor {
ref_tracking: &mut ref_tracking,
ecx,
mode,
- leftover_relocations,
- param_env,
+ leftover_allocations,
mutability,
}.visit_value(mplace);
if let Err(error) = interned {
@@ -309,15 +330,23 @@
// Intern the rest of the allocations as mutable. These might be inside unions, padding, raw
// pointers, ... So we can't intern them according to their type rules
- let mut todo: Vec<_> = leftover_relocations.iter().cloned().collect();
+ let mut todo: Vec<_> = leftover_allocations.iter().cloned().collect();
while let Some(alloc_id) = todo.pop() {
- if let Some((_, alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
- // We can't call the `intern` method here, as its logic is tailored to safe references.
- // So we hand-roll the interning logic here again
+ if let Some((_, mut alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
+ // We can't call the `intern_shallow` method here, as its logic is tailored to safe
+ // references and a `leftover_allocations` set (where we only have a todo-list here).
+ // So we hand-roll the interning logic here again.
+ if base_intern_mode != InternMode::Static {
+ // If it's not a static, it *must* be immutable.
+ // We cannot have mutable memory inside a constant.
+ // FIXME: ideally we would assert that they already are immutable, to double-
+ // check our static checks.
+ alloc.mutability = Mutability::Immutable;
+ }
let alloc = tcx.intern_const_alloc(alloc);
tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
for &(_, ((), reloc)) in alloc.relocations().iter() {
- if leftover_relocations.insert(reloc) {
+ if leftover_allocations.insert(reloc) {
todo.push(reloc);
}
}
diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs
index de1676f..a81786e 100644
--- a/src/librustc_msan/build.rs
+++ b/src/librustc_msan/build.rs
@@ -4,6 +4,7 @@
use cmake::Config;
fn main() {
+ println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
return;
}
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 12c5ce1..55f6b91 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -130,6 +130,10 @@
self.save_ctxt.span_from_span(span)
}
+ fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
+ self.save_ctxt.lookup_def_id(ref_id)
+ }
+
pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
let source_file = self.tcx.sess.local_crate_source_file.as_ref();
let crate_root = source_file.map(|source_file| {
@@ -223,13 +227,6 @@
}
}
- fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
- match self.save_ctxt.get_path_res(ref_id) {
- Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => None,
- def => Some(def.def_id()),
- }
- }
-
fn process_formals(&mut self, formals: &'l [ast::Param], qualname: &str) {
for arg in formals {
self.visit_pat(&arg.pat);
@@ -283,36 +280,32 @@
) {
debug!("process_method: {}:{}", id, ident);
- if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) {
- let sig_str = crate::make_signature(&sig.decl, &generics);
- if body.is_some() {
- self.nest_tables(
- id,
- |v| v.process_formals(&sig.decl.inputs, &method_data.qualname),
- );
+ let hir_id = self.tcx.hir().node_to_hir_id(id);
+ self.nest_tables(id, |v| {
+ if let Some(mut method_data) = v.save_ctxt.get_method_data(id, ident, span) {
+ v.process_formals(&sig.decl.inputs, &method_data.qualname);
+ v.process_generic_params(&generics, &method_data.qualname, id);
+
+ method_data.value = crate::make_signature(&sig.decl, &generics);
+ method_data.sig = sig::method_signature(id, ident, generics, sig, &v.save_ctxt);
+
+ v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, hir_id), method_data);
}
- self.process_generic_params(&generics, &method_data.qualname, id);
+ // walk arg and return types
+ for arg in &sig.decl.inputs {
+ v.visit_ty(&arg.ty);
+ }
- method_data.value = sig_str;
- method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt);
- let hir_id = self.tcx.hir().node_to_hir_id(id);
- self.dumper.dump_def(&access_from_vis!(self.save_ctxt, vis, hir_id), method_data);
- }
+ if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
+ v.visit_ty(ret_ty);
+ }
- // walk arg and return types
- for arg in &sig.decl.inputs {
- self.visit_ty(&arg.ty);
- }
-
- if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
- self.visit_ty(ret_ty);
- }
-
- // walk the fn body
- if let Some(body) = body {
- self.nest_tables(id, |v| v.visit_block(body));
- }
+ // walk the fn body
+ if let Some(body) = body {
+ v.visit_block(body);
+ }
+ });
}
fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
@@ -377,26 +370,31 @@
ty_params: &'l ast::Generics,
body: &'l ast::Block,
) {
- if let Some(fn_data) = self.save_ctxt.get_item_data(item) {
- down_cast_data!(fn_data, DefData, item.span);
- self.nest_tables(
- item.id,
- |v| v.process_formals(&decl.inputs, &fn_data.qualname),
- );
- self.process_generic_params(ty_params, &fn_data.qualname, item.id);
- let hir_id = self.tcx.hir().node_to_hir_id(item.id);
- self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), fn_data);
- }
+ let hir_id = self.tcx.hir().node_to_hir_id(item.id);
+ self.nest_tables(item.id, |v| {
+ if let Some(fn_data) = v.save_ctxt.get_item_data(item) {
+ down_cast_data!(fn_data, DefData, item.span);
+ v.process_formals(&decl.inputs, &fn_data.qualname);
+ v.process_generic_params(ty_params, &fn_data.qualname, item.id);
- for arg in &decl.inputs {
- self.visit_ty(&arg.ty);
- }
+ v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), fn_data);
+ }
- if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
- self.visit_ty(&ret_ty);
- }
+ for arg in &decl.inputs {
+ v.visit_ty(&arg.ty)
+ }
- self.nest_tables(item.id, |v| v.visit_block(&body));
+ if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
+ if let ast::TyKind::ImplTrait(..) = ret_ty.node {
+ // FIXME: Opaque type desugaring prevents us from easily
+ // processing trait bounds. See `visit_ty` for more details.
+ } else {
+ v.visit_ty(&ret_ty);
+ }
+ }
+
+ v.visit_block(&body);
+ });
}
fn process_static_or_const_item(
@@ -1113,11 +1111,7 @@
// FIXME: uses of the assoc type should ideally point to this
// 'def' and the name here should be a ref to the def in the
// trait.
- for bound in bounds.iter() {
- if let ast::GenericBound::Trait(trait_ref, _) = bound {
- self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
- }
- }
+ self.process_bounds(&bounds);
}
ast::ImplItemKind::Macro(_) => {}
}
@@ -1364,10 +1358,10 @@
self.visit_ty(&ty);
self.process_generic_params(ty_params, &qualname, item.id);
}
- OpaqueTy(ref _bounds, ref ty_params) => {
+ OpaqueTy(ref bounds, ref ty_params) => {
let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
- // FIXME do something with _bounds
+
let value = String::new();
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
@@ -1393,6 +1387,7 @@
);
}
+ self.process_bounds(bounds);
self.process_generic_params(ty_params, &qualname, item.id);
}
Mac(_) => (),
@@ -1449,6 +1444,18 @@
self.visit_ty(element);
self.nest_tables(length.id, |v| v.visit_expr(&length.value));
}
+ ast::TyKind::ImplTrait(id, ref bounds) => {
+ // FIXME: As of writing, the opaque type lowering introduces
+ // another DefPath scope/segment (used to declare the resulting
+ // opaque type item).
+ // However, the synthetic scope does *not* have associated
+ // typeck tables, which means we can't nest it and we fire an
+ // assertion when resolving the qualified type paths in trait
+ // bounds...
+ // This will panic if called on return type `impl Trait`, which
+ // we guard against in `process_fn`.
+ self.nest_tables(id, |v| v.process_bounds(bounds));
+ }
_ => visit::walk_ty(self, t),
}
}
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 4bc098d..055ccf6 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -312,7 +312,7 @@
let impl_id = self.next_impl_id();
let span = self.span_from_span(sub_span);
- let type_data = self.lookup_ref_id(typ.id);
+ let type_data = self.lookup_def_id(typ.id);
type_data.map(|type_data| {
Data::RelationData(Relation {
kind: RelationKind::Impl {
@@ -322,7 +322,7 @@
from: id_from_def_id(type_data),
to: trait_ref
.as_ref()
- .and_then(|t| self.lookup_ref_id(t.ref_id))
+ .and_then(|t| self.lookup_def_id(t.ref_id))
.map(id_from_def_id)
.unwrap_or_else(|| null_id()),
},
@@ -495,7 +495,7 @@
}
pub fn get_trait_ref_data(&self, trait_ref: &ast::TraitRef) -> Option<Ref> {
- self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| {
+ self.lookup_def_id(trait_ref.ref_id).and_then(|def_id| {
let span = trait_ref.path.span;
if generated_code(span) {
return None;
@@ -870,7 +870,7 @@
})
}
- fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
+ fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
match self.get_path_res(ref_id) {
Res::PrimTy(_) | Res::SelfTy(..) | Res::Err => None,
def => Some(def.def_id()),
diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs
index 6df9691..f9333e1 100644
--- a/src/librustc_tsan/build.rs
+++ b/src/librustc_tsan/build.rs
@@ -4,6 +4,7 @@
use cmake::Config;
fn main() {
+ println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
return;
}
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 20442ab..af1d240 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -25,17 +25,11 @@
unwind = { path = "../libunwind" }
hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
-[dependencies.backtrace]
+[dependencies.backtrace_rs]
+package = "backtrace"
version = "0.3.37"
-default-features = false # don't use coresymbolication on OSX
-features = [
- "rustc-dep-of-std", # enable build support for integrating into libstd
- "dbghelp", # backtrace/symbolize on MSVC
- "libbacktrace", # symbolize on most platforms
- "libunwind", # backtrace on most platforms
- "dladdr", # symbolize on platforms w/o libbacktrace
-]
-optional = true
+default-features = false # without the libstd `backtrace` feature, stub out everything
+features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
[dev-dependencies]
rand = "0.7"
@@ -65,6 +59,13 @@
[features]
default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]
+backtrace = [
+ "backtrace_rs/dbghelp", # backtrace/symbolize on MSVC
+ "backtrace_rs/libbacktrace", # symbolize on most platforms
+ "backtrace_rs/libunwind", # backtrace on most platforms
+ "backtrace_rs/dladdr", # symbolize on platforms w/o libbacktrace
+]
+
panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
compiler-builtins-c = ["alloc/compiler-builtins-c"]
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
index 5d46ef7..61c42a5 100644
--- a/src/libstd/backtrace.rs
+++ b/src/libstd/backtrace.rs
@@ -97,6 +97,7 @@
use crate::sync::Mutex;
use crate::sys_common::backtrace::{output_filename, lock};
use crate::vec::Vec;
+use backtrace_rs as backtrace;
use backtrace::BytesOrWideString;
/// A captured OS thread stack backtrace.
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index b14e02a..b5265fe 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -1956,7 +1956,8 @@
/// # Platform-specific behavior
///
/// This function currently corresponds to the `opendir` function on Unix
-/// and the `FindFirstFile` function on Windows.
+/// and the `FindFirstFile` function on Windows. Advancing the iterator
+/// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
/// Note that, this [may change in the future][changes].
///
/// [changes]: ../io/index.html#platform-specific-behavior
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index db4089c..28fb402 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -17,8 +17,7 @@
use crate::raw;
use crate::sys::stdio::panic_output;
use crate::sys_common::rwlock::RWLock;
-use crate::sys_common::thread_info;
-use crate::sys_common::util;
+use crate::sys_common::{thread_info, util, backtrace};
use crate::thread;
#[cfg(not(test))]
@@ -157,20 +156,18 @@
}
fn default_hook(info: &PanicInfo<'_>) {
- #[cfg(feature = "backtrace")]
- use crate::sys_common::{backtrace as backtrace_mod};
-
// If this is a double panic, make sure that we print a backtrace
// for this panic. Otherwise only print it if logging is enabled.
- #[cfg(feature = "backtrace")]
- let log_backtrace = {
+ let log_backtrace = if cfg!(feature = "backtrace") {
let panics = update_panic_count(0);
if panics >= 2 {
- Some(backtrace::PrintFmt::Full)
+ Some(backtrace_rs::PrintFmt::Full)
} else {
- backtrace_mod::log_enabled()
+ backtrace::log_enabled()
}
+ } else {
+ None
};
// The current implementation always returns `Some`.
@@ -190,14 +187,13 @@
let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
name, msg, location);
- #[cfg(feature = "backtrace")]
- {
+ if cfg!(feature = "backtrace") {
use crate::sync::atomic::{AtomicBool, Ordering};
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
if let Some(format) = log_backtrace {
- let _ = backtrace_mod::print(err, format);
+ let _ = backtrace::print(err, format);
} else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
environment variable to display a backtrace.");
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index c50025a..b8d57cf 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -422,7 +422,7 @@
/// // Execute `ls` in the current directory of the program.
/// list_dir.status().expect("process failed to execute");
///
-/// println!("");
+/// println!();
///
/// // Change `ls` to execute in the root directory.
/// list_dir.current_dir("/");
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 1a78abf..01711d4 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -7,10 +7,9 @@
use crate::borrow::Cow;
use crate::io::prelude::*;
use crate::path::{self, Path, PathBuf};
-use crate::sync::atomic::{self, Ordering};
use crate::sys::mutex::Mutex;
-use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt};
+use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
/// Max number of frames to print.
const MAX_NB_FRAMES: usize = 100;
@@ -74,14 +73,14 @@
bt_fmt.add_context()?;
let mut idx = 0;
let mut res = Ok(());
- backtrace::trace_unsynchronized(|frame| {
+ backtrace_rs::trace_unsynchronized(|frame| {
if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
return false;
}
let mut hit = false;
let mut stop = false;
- backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+ backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
hit = true;
if print_fmt == PrintFmt::Short {
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
@@ -130,6 +129,8 @@
// For now logging is turned off by default, and this function checks to see
// whether the magical environment variable is present to see if it's turned on.
pub fn log_enabled() -> Option<PrintFmt> {
+ use crate::sync::atomic::{self, Ordering};
+
// Setting environment variables for Fuchsia components isn't a standard
// or easily supported workflow. For now, always display backtraces.
if cfg!(target_os = "fuchsia") {
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 9190a3b..cba3eca 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -41,7 +41,6 @@
pub mod alloc;
pub mod at_exit_imp;
-#[cfg(feature = "backtrace")]
pub mod backtrace;
pub mod condvar;
pub mod io;
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 46ffa52..b27e9c5 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -877,9 +877,9 @@
// Now `last` holds the complete set of NT tokens that could
// end the sequence before SUFFIX. Check that every one works with `suffix`.
'each_last: for token in &last.tokens {
- if let TokenTree::MetaVarDecl(_, ref name, ref frag_spec) = *token {
+ if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token {
for next_token in &suffix_first.tokens {
- match is_in_follow(next_token, &frag_spec.as_str()) {
+ match is_in_follow(next_token, frag_spec.name) {
IsInFollow::Invalid(msg, help) => {
sess.span_diagnostic
.struct_span_err(next_token.span(), &msg)
@@ -948,7 +948,7 @@
fn token_can_be_followed_by_any(tok: "ed::TokenTree) -> bool {
if let quoted::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok {
- frag_can_be_followed_by_any(&frag_spec.as_str())
+ frag_can_be_followed_by_any(frag_spec.name)
} else {
// (Non NT's can always be followed by anthing in matchers.)
true
@@ -963,15 +963,15 @@
/// specifier which consumes at most one token tree can be followed by
/// a fragment specifier (indeed, these fragments can be followed by
/// ANYTHING without fear of future compatibility hazards).
-fn frag_can_be_followed_by_any(frag: &str) -> bool {
+fn frag_can_be_followed_by_any(frag: Symbol) -> bool {
match frag {
- "item" | // always terminated by `}` or `;`
- "block" | // exactly one token tree
- "ident" | // exactly one token tree
- "literal" | // exactly one token tree
- "meta" | // exactly one token tree
- "lifetime" | // exactly one token tree
- "tt" => // exactly one token tree
+ sym::item | // always terminated by `}` or `;`
+ sym::block | // exactly one token tree
+ sym::ident | // exactly one token tree
+ sym::literal | // exactly one token tree
+ sym::meta | // exactly one token tree
+ sym::lifetime | // exactly one token tree
+ sym::tt => // exactly one token tree
true,
_ =>
@@ -993,7 +993,7 @@
/// break macros that were relying on that binary operator as a
/// separator.
// when changing this do not forget to update doc/book/macros.md!
-fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
+fn is_in_follow(tok: "ed::TokenTree, frag: Symbol) -> IsInFollow {
use quoted::TokenTree;
if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok {
@@ -1002,17 +1002,17 @@
IsInFollow::Yes
} else {
match frag {
- "item" => {
+ sym::item => {
// since items *must* be followed by either a `;` or a `}`, we can
// accept anything after them
IsInFollow::Yes
}
- "block" => {
+ sym::block => {
// anything can follow block, the braces provide an easy boundary to
// maintain
IsInFollow::Yes
}
- "stmt" | "expr" => {
+ sym::stmt | sym::expr => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
match tok {
TokenTree::Token(token) => match token.kind {
@@ -1022,7 +1022,7 @@
_ => IsInFollow::No(TOKENS),
}
}
- "pat" => {
+ sym::pat => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
match tok {
TokenTree::Token(token) => match token.kind {
@@ -1033,7 +1033,7 @@
_ => IsInFollow::No(TOKENS),
}
}
- "path" | "ty" => {
+ sym::path | sym::ty => {
const TOKENS: &[&str] = &[
"`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`",
"`where`",
@@ -1061,20 +1061,20 @@
_ => IsInFollow::No(TOKENS),
}
}
- "ident" | "lifetime" => {
+ sym::ident | sym::lifetime => {
// being a single token, idents and lifetimes are harmless
IsInFollow::Yes
}
- "literal" => {
+ sym::literal => {
// literals may be of a single token, or two tokens (negative numbers)
IsInFollow::Yes
}
- "meta" | "tt" => {
+ sym::meta | sym::tt => {
// being either a single token or a delimited sequence, tt is
// harmless
IsInFollow::Yes
}
- "vis" => {
+ sym::vis => {
// Explicitly disallow `priv`, on the off chance it comes back.
const TOKENS: &[&str] = &["`,`", "an ident", "a type"];
match tok {
@@ -1099,7 +1099,7 @@
_ => IsInFollow::No(TOKENS),
}
}
- "" => IsInFollow::Yes, // kw::Invalid
+ kw::Invalid => IsInFollow::Yes,
_ => IsInFollow::Invalid(
format!("invalid fragment specifier `{}`", frag),
VALID_FRAGMENT_NAMES_MSG,
diff --git a/src/test/debuginfo/function-arg-initialization.rs b/src/test/debuginfo/function-arg-initialization.rs
index fef6253..8c86d2c 100644
--- a/src/test/debuginfo/function-arg-initialization.rs
+++ b/src/test/debuginfo/function-arg-initialization.rs
@@ -242,12 +242,12 @@
fn binding(a: i64, b: u64, c: f64) {
let x = 0; // #break
- println!("")
+ println!()
}
fn assignment(mut a: u64, b: u64, c: f64) {
a = b; // #break
- println!("")
+ println!()
}
fn function_call(x: u64, y: u64, z: f64) {
diff --git a/src/test/ui/coherence/conflicting-impl-with-err.rs b/src/test/ui/coherence/conflicting-impl-with-err.rs
new file mode 100644
index 0000000..3e0234b
--- /dev/null
+++ b/src/test/ui/coherence/conflicting-impl-with-err.rs
@@ -0,0 +1,16 @@
+struct ErrorKind;
+struct Error(ErrorKind);
+
+impl From<nope::Thing> for Error { //~ ERROR failed to resolve
+ fn from(_: nope::Thing) -> Self { //~ ERROR failed to resolve
+ unimplemented!()
+ }
+}
+
+impl From<ErrorKind> for Error {
+ fn from(_: ErrorKind) -> Self {
+ unimplemented!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/coherence/conflicting-impl-with-err.stderr b/src/test/ui/coherence/conflicting-impl-with-err.stderr
new file mode 100644
index 0000000..a8a5730
--- /dev/null
+++ b/src/test/ui/coherence/conflicting-impl-with-err.stderr
@@ -0,0 +1,15 @@
+error[E0433]: failed to resolve: use of undeclared type or module `nope`
+ --> $DIR/conflicting-impl-with-err.rs:4:11
+ |
+LL | impl From<nope::Thing> for Error {
+ | ^^^^ use of undeclared type or module `nope`
+
+error[E0433]: failed to resolve: use of undeclared type or module `nope`
+ --> $DIR/conflicting-impl-with-err.rs:5:16
+ |
+LL | fn from(_: nope::Thing) -> Self {
+ | ^^^^ use of undeclared type or module `nope`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs
index e01b0df..a93f9a1 100644
--- a/src/test/ui/collections-const-new.rs
+++ b/src/test/ui/collections-const-new.rs
@@ -1,15 +1,11 @@
-// run-pass
+// check-pass
-#![allow(dead_code)]
// Test several functions can be used for constants
// 1. Vec::new()
// 2. String::new()
-#![feature(const_vec_new)]
-#![feature(const_string_new)]
-
const MY_VEC: Vec<usize> = Vec::new();
const MY_STRING: String = String::new();
-pub fn main() {}
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs
new file mode 100644
index 0000000..9fa726f
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a{
+// error-pattern: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr
new file mode 100644
index 0000000..7d2087b
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr
@@ -0,0 +1,2 @@
+error: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`)
+
diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
index 5fb9253..8b17f68 100644
--- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
+++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
@@ -14,8 +14,9 @@
impl Foo<u32> for () {
const X: u32 = 42;
}
+
impl Foo<Vec<u32>> for String {
- const X: Vec<u32> = Vec::new(); //~ ERROR not yet stable as a const fn
+ const X: Vec<u32> = Vec::new();
}
impl Bar<u32, ()> for () {}
diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
index c56ebf6..5bc7b70 100644
--- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
+++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
@@ -4,13 +4,5 @@
LL | const F: u32 = (U::X, 42).1;
| ^^^^^^^^^^ constants cannot evaluate destructors
-error: `std::vec::Vec::<T>::new` is not yet stable as a const fn
- --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25
- |
-LL | const X: Vec<u32> = Vec::new();
- | ^^^^^^^^^^
- |
- = help: add `#![feature(const_vec_new)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
diff --git a/src/test/ui/consts/miri_unleashed/mutable_const.rs b/src/test/ui/consts/miri_unleashed/mutable_const.rs
new file mode 100644
index 0000000..b476e04
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/mutable_const.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
+
+#![feature(const_raw_ptr_deref)]
+#![deny(const_err)]
+
+use std::cell::UnsafeCell;
+
+// make sure we do not just intern this as mutable
+const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
+
+const MUTATING_BEHIND_RAW: () = {
+ // Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
+ unsafe {
+ *MUTABLE_BEHIND_RAW = 99 //~ WARN skipping const checks
+ //~^ ERROR any use of this value will cause an error
+ //~^^ tried to modify constant memory
+ }
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/miri_unleashed/mutable_const.stderr b/src/test/ui/consts/miri_unleashed/mutable_const.stderr
new file mode 100644
index 0000000..507d4823
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/mutable_const.stderr
@@ -0,0 +1,27 @@
+warning: skipping const checks
+ --> $DIR/mutable_const.rs:14:9
+ |
+LL | *MUTABLE_BEHIND_RAW = 99
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: any use of this value will cause an error
+ --> $DIR/mutable_const.rs:14:9
+ |
+LL | / const MUTATING_BEHIND_RAW: () = {
+LL | | // Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
+LL | | unsafe {
+LL | | *MUTABLE_BEHIND_RAW = 99
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^ tried to modify constant memory
+... |
+LL | | }
+LL | | };
+ | |__-
+ |
+note: lint level defined here
+ --> $DIR/mutable_const.rs:4:9
+ |
+LL | #![deny(const_err)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
index 82569e2..28cf353 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
@@ -6,7 +6,7 @@
thread 'rustc' panicked at 'assertion failed: `(left != right)`
left: `Const`,
- right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites may arbitrarily decide to change, too.', src/librustc_mir/interpret/intern.rs:LL:CC
+ right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites could observe that mutation.', src/librustc_mir/interpret/intern.rs:LL:CC
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: internal compiler error: unexpected panic
diff --git a/src/test/ui/drop/dropck_legal_cycles.rs b/src/test/ui/drop/dropck_legal_cycles.rs
index a4f4c26..fb13fd7 100644
--- a/src/test/ui/drop/dropck_legal_cycles.rs
+++ b/src/test/ui/drop/dropck_legal_cycles.rs
@@ -143,7 +143,7 @@
v[0].descend_into_self(&mut c);
assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 1: { v[0] -> v[1], v[1] -> v[0] };
// does not exercise `v` itself
@@ -158,7 +158,7 @@
v[0].descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 2: { v[0] -> v, v[1] -> v }
let v: V = Named::new("v");
@@ -171,7 +171,7 @@
v.descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 };
// does not exercise `h` itself
@@ -193,7 +193,7 @@
assert!(c.saw_prev_marked);
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h }
@@ -216,7 +216,7 @@
// break;
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] };
// does not exercise vd itself
@@ -232,7 +232,7 @@
vd[0].descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd }
let mut vd: VecDeque<VD> = VecDeque::new();
@@ -247,7 +247,7 @@
vd[0].descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm }
let mut vm: HashMap<usize, VM> = HashMap::new();
@@ -262,7 +262,7 @@
vm[&0].descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll }
let mut ll: LinkedList<LL> = LinkedList::new();
@@ -282,7 +282,7 @@
// break;
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh }
let mut bh: BinaryHeap<BH> = BinaryHeap::new();
@@ -302,7 +302,7 @@
// break;
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm }
let mut btm: BTreeMap<BTM, BTM> = BTreeMap::new();
@@ -323,7 +323,7 @@
// break;
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm }
let mut bts: BTreeSet<BTS> = BTreeSet::new();
@@ -343,7 +343,7 @@
// break;
}
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 }
let (rc0, rc1, rc2): (RCRC, RCRC, RCRC);
@@ -361,7 +361,7 @@
rc0.descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// We want to take the previous Rc case and generalize it to Arc.
//
@@ -395,7 +395,7 @@
arc0.descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks
let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW);
@@ -413,7 +413,7 @@
arc0.descend_into_self(&mut c);
assert!(c.saw_prev_marked);
- if PRINT { println!(""); }
+ if PRINT { println!(); }
// Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs
let (arc0, arc1, arc2): (ARCM, ARCM, ARCM);
diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs
index 43b1a04..0fbc796 100644
--- a/src/test/ui/for/for-c-in-str.rs
+++ b/src/test/ui/for/for-c-in-str.rs
@@ -6,6 +6,6 @@
//~| NOTE `&str` is not an iterator
//~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
//~| NOTE required by `std::iter::IntoIterator::into_iter`
- println!("");
+ println!();
}
}
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index 1d8cce5..7dcbdd0 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -1,4 +1,4 @@
-#![feature(box_patterns)]
+#![feature(box_patterns, stmt_expr_attributes)]
#![feature(or_patterns)]
//~^ WARN the feature `or_patterns` is incomplete
@@ -17,6 +17,10 @@
let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
}
+fn _no_lint_attr() {
+ let _x = #[allow(dead_code)] (1 + 2);
+}
+
// Don't lint in these cases (#64106).
fn or_patterns_no_lint() {
match Box::new(0) {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index 7d5e286..675dd4f 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -49,109 +49,109 @@
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:41:12
+ --> $DIR/issue-54538-unused-parens-lint.rs:45:12
|
LL | if let (0 | 1) = 0 {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:42:13
+ --> $DIR/issue-54538-unused-parens-lint.rs:46:13
|
LL | if let ((0 | 1),) = (0,) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:43:13
+ --> $DIR/issue-54538-unused-parens-lint.rs:47:13
|
LL | if let [(0 | 1)] = [0] {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:44:16
+ --> $DIR/issue-54538-unused-parens-lint.rs:48:16
|
LL | if let 0 | (1 | 2) = 0 {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:46:15
+ --> $DIR/issue-54538-unused-parens-lint.rs:50:15
|
LL | if let TS((0 | 1)) = TS(0) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:48:20
+ --> $DIR/issue-54538-unused-parens-lint.rs:52:20
|
LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:58:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:62:9
|
LL | (_) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:59:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:63:9
|
LL | (y) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:60:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:64:9
|
LL | (ref r) => {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:61:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:65:9
|
LL | (e @ 1...2) => {}
| ^^^^^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:67:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:71:9
|
LL | (e @ &(1...2)) => {}
| ^^^^^^^^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:68:10
+ --> $DIR/issue-54538-unused-parens-lint.rs:72:10
|
LL | &(_) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:79:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:83:9
|
LL | (_) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:80:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:84:9
|
LL | (y) => {}
| ^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:81:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:85:9
|
LL | (ref r) => {}
| ^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:86:9
|
LL | (e @ 1..=2) => {}
| ^^^^^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:88:9
+ --> $DIR/issue-54538-unused-parens-lint.rs:92:9
|
LL | (e @ &(1..=2)) => {}
| ^^^^^^^^^^^^^^ help: remove these parentheses
error: unnecessary parentheses around pattern
- --> $DIR/issue-54538-unused-parens-lint.rs:89:10
+ --> $DIR/issue-54538-unused-parens-lint.rs:93:10
|
LL | &(_) => {}
| ^^^ help: remove these parentheses
diff --git a/src/test/ui/save-analysis/issue-63663.rs b/src/test/ui/save-analysis/issue-63663.rs
new file mode 100644
index 0000000..92e8588
--- /dev/null
+++ b/src/test/ui/save-analysis/issue-63663.rs
@@ -0,0 +1,28 @@
+// check-pass
+// compile-flags: -Zsave-analysis
+
+pub trait Trait {
+ type Assoc;
+}
+
+pub struct A;
+
+trait Generic<T> {}
+impl<T> Generic<T> for () {}
+
+// Don't ICE when resolving type paths in return type `impl Trait`
+fn assoc_in_opaque_type_bounds<U: Trait>() -> impl Generic<U::Assoc> {}
+
+// Check that this doesn't ICE when processing associated const in formal
+// argument and return type of functions defined inside function/method scope.
+pub fn func() {
+ fn _inner1<U: Trait>(_: U::Assoc) {}
+ fn _inner2<U: Trait>() -> U::Assoc { unimplemented!() }
+
+ impl A {
+ fn _inner1<U: Trait>(self, _: U::Assoc) {}
+ fn _inner2<U: Trait>(self) -> U::Assoc { unimplemented!() }
+ }
+}
+
+fn main() {}
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c364479..63ae445 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -7,3 +7,5 @@
[dependencies]
toml = "0.5"
serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+reqwest = "0.9"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 9ffa939..c2d642b 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -1,12 +1,19 @@
+//! Build a dist manifest, hash and sign everything.
+//! This gets called by `promote-release`
+//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
+//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
+//! by rustbuild (in `src/bootstrap/dist.rs`).
+
use toml;
use serde::Serialize;
use std::collections::BTreeMap;
use std::env;
use std::fs;
-use std::io::{self, Read, Write};
+use std::io::{self, Read, Write, BufRead, BufReader};
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};
+use std::collections::HashMap;
static HOSTS: &[&str] = &[
"aarch64-unknown-linux-gnu",
@@ -146,6 +153,9 @@
"x86_64-pc-windows-gnu",
];
+static TOOLSTATE: &str =
+ "https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv";
+
#[derive(Serialize)]
#[serde(rename_all = "kebab-case")]
struct Manifest {
@@ -270,6 +280,7 @@
// Do not ask for a passphrase while manually testing
let mut passphrase = String::new();
if should_sign {
+ // `x.py` passes the passphrase via stdin.
t!(io::stdin().read_to_string(&mut passphrase));
}
@@ -353,6 +364,7 @@
self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
+ self.check_toolstate();
self.digest_and_sign();
let manifest = self.build_manifest();
self.write_channel_files(&self.rust_release, &manifest);
@@ -362,6 +374,37 @@
}
}
+ /// If a tool does not pass its tests, don't ship it.
+ /// Right now, we do this only for Miri.
+ fn check_toolstate(&mut self) {
+ // Get the toolstate for this rust revision.
+ let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash");
+ let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates");
+ let toolstates = BufReader::new(toolstates);
+ let toolstate = toolstates.lines()
+ .find_map(|line| {
+ let line = line.expect("failed to read toolstate lines");
+ let mut pieces = line.splitn(2, '\t');
+ let commit = pieces.next().expect("malformed toolstate line");
+ if commit != rev {
+ // Not the right commit.
+ return None;
+ }
+ // Return the 2nd piece, the JSON.
+ Some(pieces.next().expect("malformed toolstate line").to_owned())
+ })
+ .expect("failed to find toolstate for rust commit");
+ let toolstate: HashMap<String, String> =
+ serde_json::from_str(&toolstate).expect("toolstate is malformed JSON");
+ // Mark some tools as missing based on toolstate.
+ if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") {
+ println!("Miri tests are not passing, removing component");
+ self.miri_version = None;
+ self.miri_git_commit_hash = None;
+ }
+ }
+
+ /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
fn digest_and_sign(&mut self) {
for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
let filename = file.file_name().unwrap().to_str().unwrap();
@@ -532,19 +575,20 @@
.as_ref()
.cloned()
.map(|version| (version, true))
- .unwrap_or_default();
+ .unwrap_or_default(); // `is_present` defaults to `false` here.
- // miri needs to build std with xargo, which doesn't allow stable/beta:
- // <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
+ // Miri is nightly-only; never ship it for other trains.
if pkgname == "miri-preview" && self.rust_release != "nightly" {
- is_present = false; // ignore it
+ is_present = false; // Pretend the component is entirely missing.
}
let targets = targets.iter().map(|name| {
if is_present {
+ // The component generally exists, but it might still be missing for this target.
let filename = self.filename(pkgname, name);
let digest = match self.digests.remove(&filename) {
Some(digest) => digest,
+ // This component does not exist for this target -- skip it.
None => return (name.to_string(), Target::unavailable()),
};
let xz_filename = filename.replace(".tar.gz", ".tar.xz");
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 467b777..7c51de5 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -253,7 +253,7 @@
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message));
- println!("");
+ println!();
panic!()
}
@@ -265,7 +265,7 @@
if matches.opt_present("h") || matches.opt_present("help") {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", opts.usage(&message));
- println!("");
+ println!();
panic!()
}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index aff5546..baed27d 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2593,7 +2593,7 @@
" actual: {}",
codegen_units_to_str(&actual_item.codegen_units)
);
- println!("");
+ println!();
}
}
@@ -3526,7 +3526,7 @@
}
}
}
- println!("");
+ println!();
}
}
}
diff --git a/src/tools/miri b/src/tools/miri
index dd94c7c..d881387 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit dd94c7c5a32be2ee0adeeaf9d46f26f14925797c
+Subproject commit d88138723780d11ca2c09560111223dc20b9d5f3
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 2e2505b..4060b90 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -7,6 +7,8 @@
## It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts
## when a new commit lands on `master` (i.e., after it passed all checks on `auto`).
+from __future__ import print_function
+
import sys
import re
import os
@@ -20,21 +22,26 @@
import urllib.request as urllib2
# List of people to ping when the status of a tool or a book changed.
+# These should be collaborators of the rust-lang/rust repository (with at least
+# read privileges on it). CI will fail otherwise.
MAINTAINERS = {
- 'miri': '@oli-obk @RalfJung @eddyb',
- 'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995 @yaahc',
- 'rls': '@Xanewok',
- 'rustfmt': '@topecongiro',
- 'book': '@carols10cents @steveklabnik',
- 'nomicon': '@frewsxcv @Gankro',
- 'reference': '@steveklabnik @Havvy @matthewjasper @ehuss',
- 'rust-by-example': '@steveklabnik @marioidival @projektir',
- 'embedded-book': (
- '@adamgreig @andre-richter @jamesmunns @korken89 '
- '@ryankurte @thejpster @therealprof'
- ),
- 'edition-guide': '@ehuss @Centril @steveklabnik',
- 'rustc-guide': '@mark-i-m @spastorino @amanjeev'
+ 'miri': {'oli-obk', 'RalfJung', 'eddyb'},
+ 'clippy-driver': {
+ 'Manishearth', 'llogiq', 'mcarton', 'oli-obk', 'phansch', 'flip1995',
+ 'yaahc',
+ },
+ 'rls': {'Xanewok'},
+ 'rustfmt': {'topecongiro'},
+ 'book': {'carols10cents', 'steveklabnik'},
+ 'nomicon': {'frewsxcv', 'Gankra'},
+ 'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
+ 'rust-by-example': {'steveklabnik', 'marioidival'},
+ 'embedded-book': {
+ 'adamgreig', 'andre-richter', 'jamesmunns', 'korken89',
+ 'ryankurte', 'thejpster', 'therealprof',
+ },
+ 'edition-guide': {'ehuss', 'Centril', 'steveklabnik'},
+ 'rustc-guide': {'mark-i-m', 'spastorino', 'amanjeev'},
}
REPOS = {
@@ -52,6 +59,50 @@
}
+def validate_maintainers(repo, github_token):
+ '''Ensure all maintainers are assignable on a GitHub repo'''
+ next_link_re = re.compile(r'<([^>]+)>; rel="next"')
+
+ # Load the list of assignable people in the GitHub repo
+ assignable = []
+ url = 'https://api.github.com/repos/%s/collaborators?per_page=100' % repo
+ while url is not None:
+ response = urllib2.urlopen(urllib2.Request(url, headers={
+ 'Authorization': 'token ' + github_token,
+ # Properly load nested teams.
+ 'Accept': 'application/vnd.github.hellcat-preview+json',
+ }))
+ assignable.extend(user['login'] for user in json.load(response))
+ # Load the next page if available
+ url = None
+ link_header = response.headers.get('Link')
+ if link_header:
+ matches = next_link_re.match(link_header)
+ if matches is not None:
+ url = matches.group(1)
+
+ errors = False
+ for tool, maintainers in MAINTAINERS.items():
+ for maintainer in maintainers:
+ if maintainer not in assignable:
+ errors = True
+ print(
+ "error: %s maintainer @%s is not assignable in the %s repo"
+ % (tool, maintainer, repo),
+ )
+
+ if errors:
+ print()
+ print(" To be assignable, a person needs to be explicitly listed as a")
+ print(" collaborator in the repository settings. The simple way to")
+ print(" fix this is to ask someone with 'admin' privileges on the repo")
+ print(" to add the person or whole team as a collaborator with 'read'")
+ print(" privileges. Those privileges don't grant any extra permissions")
+ print(" so it's safe to apply them.")
+ print()
+ print("The build will fail due to this.")
+ exit(1)
+
def read_current_status(current_commit, path):
'''Reads build status of `current_commit` from content of `history/*.tsv`
'''
@@ -73,13 +124,12 @@
def issue(
tool,
status,
- maintainers,
+ assignees,
relevant_pr_number,
relevant_pr_user,
pr_reviewer,
):
# Open an issue about the toolstate failure.
- assignees = [x.strip() for x in maintainers.split('@') if x != '']
if status == 'test-fail':
status_description = 'has failing tests'
else:
@@ -100,7 +150,7 @@
REPOS.get(tool), relevant_pr_user, pr_reviewer
)),
'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number),
- 'assignees': assignees,
+ 'assignees': list(assignees),
'labels': ['T-compiler', 'I-nominated'],
})
print("Creating issue:\n{}".format(request))
@@ -150,18 +200,19 @@
old = status[os]
new = s.get(tool, old)
status[os] = new
+ maintainers = ' '.join('@'+name for name in MAINTAINERS[tool])
if new > old: # comparing the strings, but they are ordered appropriately!
# things got fixed or at least the status quo improved
changed = True
message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
- .format(tool, os, old, new, MAINTAINERS.get(tool))
+ .format(tool, os, old, new, maintainers)
elif new < old:
# tests or builds are failing and were not failing before
changed = True
title = '💔 {} on {}: {} → {}' \
.format(tool, os, old, new)
message += '{} (cc {}, @rust-lang/infra).\n' \
- .format(title, MAINTAINERS.get(tool))
+ .format(title, maintainers)
# Most tools only create issues for build failures.
# Other failures can be spurious.
if new == 'build-fail' or (tool == 'miri' and new == 'test-fail'):
@@ -200,6 +251,16 @@
if __name__ == '__main__':
+ repo = os.environ.get('TOOLSTATE_VALIDATE_MAINTAINERS_REPO')
+ if repo:
+ github_token = os.environ.get('TOOLSTATE_REPO_ACCESS_TOKEN')
+ if github_token:
+ validate_maintainers(repo, github_token)
+ else:
+ print('skipping toolstate maintainers validation since no GitHub token is present')
+ # When validating maintainers don't run the full script.
+ exit(0)
+
cur_commit = sys.argv[1]
cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
cur_commit_msg = sys.argv[2]
diff --git a/src/tools/rls b/src/tools/rls
index 412fb00..d9aa23a 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 412fb00b37afb6b7f7fa96a35f2315c7e640b916
+Subproject commit d9aa23a43ad29e3a10551a1425ef5d5baef28d70
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index d068e1c..930279c 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -62,7 +62,6 @@
serde = { version = "1.0.82", features = ['derive'] }
serde_json = { version = "1.0.31", features = ["raw_value"] }
smallvec = { version = "0.6", features = ['union', 'may_dangle'] }
-byteorder = { version = "1.2.7", features = ["i128"] }
[target.'cfg(not(windows))'.dependencies]