about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-03 20:56:05 +0000
committerbors <bors@rust-lang.org>2020-04-03 20:56:05 +0000
commit74bd074eefcf4915c73d1ab91bc90859664729e6 (patch)
tree4eb869837e228d81b08b2fb4db3ad1af00942039
parentf6fe99c798cb65280a9a56f442b371adcb7b8aa2 (diff)
parent4c41ea36cda77748b532cf6d989a8d5d2fcc872e (diff)
Auto merge of #70747 - Centril:rollup-2vx9bve, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #69860 (Use associated numeric consts in documentation)
 - #70576 (Update the description of the ticket to point at RFC 1721)
 - #70597 (Fix double-free and undefined behaviour in libstd::syn::unix::Thread::new)
 - #70640 (Hide `task_context` when lowering body)
 - #70641 (Remove duplicated code in trait selection)
 - #70707 (Remove unused graphviz emitter)
 - #70720 (Place TLS initializers with relocations in .tdata)
 - #70735 (Clean up E0502 explanation)
 - #70741 (Add test for #59023)

Failed merges:

r? @ghost
-rw-r--r--src/liballoc/slice.rs2
-rw-r--r--src/liballoc/str.rs2
-rw-r--r--src/libcore/cmp.rs2
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/intrinsics.rs12
-rw-r--r--src/libcore/iter/traits/iterator.rs8
-rw-r--r--src/libcore/num/f32.rs2
-rw-r--r--src/libcore/num/f64.rs2
-rw-r--r--src/libcore/num/mod.rs2
-rw-r--r--src/libcore/ops/range.rs10
-rw-r--r--src/libcore/ptr/const_ptr.rs4
-rw-r--r--src/libcore/ptr/mut_ptr.rs4
-rw-r--r--src/libcore/slice/mod.rs2
-rw-r--r--src/libcore/time.rs4
-rw-r--r--src/librustc_ast_lowering/item.rs2
-rw-r--r--src/librustc_codegen_llvm/consts.rs29
-rw-r--r--src/librustc_error_codes/error_codes/E0502.md3
-rw-r--r--src/librustc_infer/traits/mod.rs2
-rw-r--r--src/librustc_infer/traits/util.rs80
-rw-r--r--src/librustc_metadata/native_libs.rs9
-rw-r--r--src/librustc_mir/dataflow/graphviz.rs277
-rw-r--r--src/librustc_target/abi/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/util.rs297
-rw-r--r--src/libstd/f32.rs4
-rw-r--r--src/libstd/f64.rs4
-rw-r--r--src/libstd/sys/cloudabi/stack_overflow.rs8
-rw-r--r--src/libstd/sys/cloudabi/thread.rs15
-rw-r--r--src/libstd/sys/hermit/stack_overflow.rs8
-rw-r--r--src/libstd/sys/hermit/thread.rs19
-rw-r--r--src/libstd/sys/sgx/stack_overflow.rs8
-rw-r--r--src/libstd/sys/unix/thread.rs21
-rw-r--r--src/libstd/sys/vxworks/thread.rs21
-rw-r--r--src/libstd/sys/wasm/stack_overflow.rs8
-rw-r--r--src/libstd/sys/windows/thread.rs17
-rw-r--r--src/libstd/sys_common/thread.rs11
-rw-r--r--src/test/ui/async-await/issue-70594.rs12
-rw-r--r--src/test/ui/async-await/issue-70594.stderr44
-rw-r--r--src/test/ui/feature-gates/feature-gate-link_cfg.stderr2
-rw-r--r--src/test/ui/issues/issue-70673.rs12
-rw-r--r--src/test/ui/traits/impl_trait_as_trait_return_position.rs17
41 files changed, 283 insertions, 709 deletions
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index d8fc1faca3a..2ce5bc8ed2f 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -432,7 +432,7 @@ impl<T> [T] {
     ///
     /// ```should_panic
     /// // this will panic at runtime
-    /// b"0123456789abcdef".repeat(usize::max_value());
+    /// b"0123456789abcdef".repeat(usize::MAX);
     /// ```
     #[stable(feature = "repeat_generic_slice", since = "1.40.0")]
     pub fn repeat(&self, n: usize) -> Vec<T>
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 843a2f1f8e9..70860c09a2c 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -499,7 +499,7 @@ impl str {
     ///
     /// ```should_panic
     /// // this will panic at runtime
-    /// "0123456789abcdef".repeat(usize::max_value());
+    /// "0123456789abcdef".repeat(usize::MAX);
     /// ```
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 604be7d5f68..8c542136a7f 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -817,7 +817,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// When comparison is impossible:
     ///
     /// ```
-    /// let result = std::f64::NAN.partial_cmp(&1.0);
+    /// let result = f64::NAN.partial_cmp(&1.0);
     /// assert_eq!(result, None);
     /// ```
     #[must_use]
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index fe728d42c76..95411b525d0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -852,7 +852,7 @@ pub trait LowerHex {
 ///     }
 /// }
 ///
-/// let l = Length(i32::max_value());
+/// let l = Length(i32::MAX);
 ///
 /// assert_eq!(format!("l as hex is: {:X}", l), "l as hex is: 7FFFFFFF");
 ///
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 698c97999c4..d406b3ce6ef 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -43,7 +43,7 @@ use crate::intrinsics;
 ///
 /// assert_eq!(div_1(7, 0), 7);
 /// assert_eq!(div_1(9, 1), 4);
-/// assert_eq!(div_1(11, std::u32::MAX), 0);
+/// assert_eq!(div_1(11, u32::MAX), 0);
 /// ```
 #[inline]
 #[stable(feature = "unreachable", since = "1.27.0")]
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 7e9140faa64..4a11fb39389 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1739,11 +1739,11 @@ extern "rust-intrinsic" {
     pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs an exact division, resulting in undefined behavior where
-    /// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
+    /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
     pub fn exact_div<T: Copy>(x: T, y: T) -> T;
 
     /// Performs an unchecked division, resulting in undefined behavior
-    /// where y = 0 or x = `T::min_value()` and y = -1
+    /// where y = 0 or x = `T::MIN` and y = -1
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_div` method. For example,
@@ -1751,7 +1751,7 @@ extern "rust-intrinsic" {
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
     /// Returns the remainder of an unchecked division, resulting in
-    /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
+    /// undefined behavior where y = 0 or x = `T::MIN` and y = -1
     ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `checked_rem` method. For example,
@@ -1777,17 +1777,17 @@ extern "rust-intrinsic" {
     pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked addition, resulting in
-    /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
+    /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked subtraction, resulting in
-    /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
+    /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked multiplication, resulting in
-    /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
+    /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
     #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
     pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
 
diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index daa880e7cd5..c8829817e19 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -198,7 +198,7 @@ pub trait Iterator {
     /// // and the maximum possible lower bound
     /// let iter = 0..;
     ///
-    /// assert_eq!((usize::max_value(), None), iter.size_hint());
+    /// assert_eq!((usize::MAX, None), iter.size_hint());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -2920,7 +2920,7 @@ pub trait Iterator {
     /// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
     /// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));
     ///
-    /// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
+    /// assert_eq!([f64::NAN].iter().partial_cmp([1.].iter()), None);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn partial_cmp<I>(self, other: I) -> Option<Ordering>
@@ -3170,7 +3170,7 @@ pub trait Iterator {
     /// assert!(![1, 3, 2, 4].iter().is_sorted());
     /// assert!([0].iter().is_sorted());
     /// assert!(std::iter::empty::<i32>().is_sorted());
-    /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
+    /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
@@ -3197,7 +3197,7 @@ pub trait Iterator {
     /// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
     /// ```
     ///
     /// [`is_sorted`]: trait.Iterator.html#method.is_sorted
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 09f1eab2d4b..4ab82add32b 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -470,7 +470,7 @@ impl f32 {
     ///
     /// let value = -128.9_f32;
     /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
-    /// assert_eq!(rounded, std::i8::MIN);
+    /// assert_eq!(rounded, i8::MIN);
     /// ```
     ///
     /// # Safety
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 65ef7ba9ac7..20818a9b750 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -484,7 +484,7 @@ impl f64 {
     ///
     /// let value = -128.9_f32;
     /// let rounded = unsafe { value.to_int_unchecked::<i8>() };
-    /// assert_eq!(rounded, std::i8::MIN);
+    /// assert_eq!(rounded, i8::MIN);
     /// ```
     ///
     /// # Safety
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index c85064759ea..7ba4004d860 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -174,7 +174,7 @@ NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
 /// let zero = Wrapping(0u32);
 /// let one = Wrapping(1u32);
 ///
-/// assert_eq!(std::u32::MAX, (zero - one).0);
+/// assert_eq!(u32::MAX, (zero - one).0);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index adee8cea442..946a765e18f 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -139,10 +139,9 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
     /// ```
     /// #![feature(range_is_empty)]
     ///
-    /// use std::f32::NAN;
     /// assert!(!(3.0..5.0).is_empty());
-    /// assert!( (3.0..NAN).is_empty());
-    /// assert!( (NAN..5.0).is_empty());
+    /// assert!( (3.0..f32::NAN).is_empty());
+    /// assert!( (f32::NAN..5.0).is_empty());
     /// ```
     #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
     pub fn is_empty(&self) -> bool {
@@ -496,10 +495,9 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// ```
     /// #![feature(range_is_empty)]
     ///
-    /// use std::f32::NAN;
     /// assert!(!(3.0..=5.0).is_empty());
-    /// assert!( (3.0..=NAN).is_empty());
-    /// assert!( (NAN..=5.0).is_empty());
+    /// assert!( (3.0..=f32::NAN).is_empty());
+    /// assert!( (f32::NAN..=5.0).is_empty());
     /// ```
     ///
     /// This method returns `true` after iteration has finished:
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index a540016854d..52e224d2a02 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -659,8 +659,8 @@ impl<T: ?Sized> *const T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`. It is permissible for the implementation to *always*
-    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// `usize::MAX`. It is permissible for the implementation to *always*
+    /// return `usize::MAX`. Only your algorithm's performance can depend
     /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs
index 01d830ca186..9f85d781d69 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -847,8 +847,8 @@ impl<T: ?Sized> *mut T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`. It is permissible for the implementation to *always*
-    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// `usize::MAX`. It is permissible for the implementation to *always*
+    /// return `usize::MAX`. Only your algorithm's performance can depend
     /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 2140a7be9ef..9be52e2dfb0 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2588,7 +2588,7 @@ impl<T> [T] {
     /// assert!(![1, 3, 2, 4].is_sorted());
     /// assert!([0].is_sorted());
     /// assert!(empty.is_sorted());
-    /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
+    /// assert!(![0.0, 1.0, f32::NAN].is_sorted());
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 2ece2150e6b..924a64847a7 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -389,7 +389,7 @@ impl Duration {
     /// use std::time::Duration;
     ///
     /// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
-    /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(std::u64::MAX, 0)), None);
+    /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
     #[inline]
@@ -460,7 +460,7 @@ impl Duration {
     /// use std::time::Duration;
     ///
     /// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
-    /// assert_eq!(Duration::new(std::u64::MAX - 1, 0).checked_mul(2), None);
+    /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
     #[inline]
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index b319ee76c81..6005b607026 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -972,8 +972,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
+        let task_context = self.task_context.take();
         let (parameters, result) = f(self);
         let body_id = self.record_body(parameters, result);
+        self.task_context = task_context;
         self.generator_kind = prev_gen_kind;
         body_id
     }
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 2d5564abfb2..9fd22c8b07b 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -436,24 +436,21 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                 //
                 // We could remove this hack whenever we decide to drop macOS 10.10 support.
                 if self.tcx.sess.target.target.options.is_like_osx {
-                    assert_eq!(alloc.relocations().len(), 0);
-
-                    let is_zeroed = {
-                        // Treats undefined bytes as if they were defined with the byte value that
-                        // happens to be currently assigned in mir. This is valid since reading
-                        // undef bytes may yield arbitrary values.
-                        //
-                        // FIXME: ignore undef bytes even with representation `!= 0`.
-                        //
-                        // The `inspect` method is okay here because we checked relocations, and
-                        // because we are doing this access to inspect the final interpreter state
-                        // (not as part of the interpreter execution).
-                        alloc
+                    // The `inspect` method is okay here because we checked relocations, and
+                    // because we are doing this access to inspect the final interpreter state
+                    // (not as part of the interpreter execution).
+                    //
+                    // FIXME: This check requires that the (arbitrary) value of undefined bytes
+                    // happens to be zero. Instead, we should only check the value of defined bytes
+                    // and set all undefined bytes to zero if this allocation is headed for the
+                    // BSS.
+                    let all_bytes_are_zero = alloc.relocations().is_empty()
+                        && alloc
                             .inspect_with_undef_and_ptr_outside_interpreter(0..alloc.len())
                             .iter()
-                            .all(|b| *b == 0)
-                    };
-                    let sect_name = if is_zeroed {
+                            .all(|&byte| byte == 0);
+
+                    let sect_name = if all_bytes_are_zero {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0")
                     } else {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0")
diff --git a/src/librustc_error_codes/error_codes/E0502.md b/src/librustc_error_codes/error_codes/E0502.md
index f15c05d558d..b90c59f5807 100644
--- a/src/librustc_error_codes/error_codes/E0502.md
+++ b/src/librustc_error_codes/error_codes/E0502.md
@@ -1,5 +1,4 @@
-This error indicates that you are trying to borrow a variable as mutable when it
-has already been borrowed as immutable.
+A variable already borrowed as immutable was borrowed as mutable.
 
 Erroneous code example:
 
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 0c451998be4..758a0b39d43 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -6,7 +6,7 @@ mod engine;
 pub mod error_reporting;
 mod project;
 mod structural_impls;
-mod util;
+pub mod util;
 
 use rustc_hir as hir;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index 80a1e282809..4fa74f93ddc 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -2,9 +2,12 @@ use smallvec::smallvec;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::ty::outlives::Component;
-use rustc_middle::ty::{self, ToPolyTraitRef, TyCtxt};
+use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};
 
-fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
+pub fn anonymize_predicate<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    pred: &ty::Predicate<'tcx>,
+) -> ty::Predicate<'tcx> {
     match *pred {
         ty::Predicate::Trait(ref data, constness) => {
             ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
@@ -88,6 +91,21 @@ pub struct Elaborator<'tcx> {
     visited: PredicateSet<'tcx>,
 }
 
+pub fn elaborate_trait_ref<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+) -> Elaborator<'tcx> {
+    elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
+}
+
+pub fn elaborate_trait_refs<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
+) -> Elaborator<'tcx> {
+    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
+    elaborate_predicates(tcx, predicates)
+}
+
 pub fn elaborate_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     mut predicates: Vec<ty::Predicate<'tcx>>,
@@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
 }
 
 impl Elaborator<'tcx> {
+    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
+        FilterToTraits::new(self)
+    }
+
     fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
         let tcx = self.visited.tcx;
         match *predicate {
@@ -223,3 +245,57 @@ impl Iterator for Elaborator<'tcx> {
         }
     }
 }
+
+///////////////////////////////////////////////////////////////////////////
+// Supertrait iterator
+///////////////////////////////////////////////////////////////////////////
+
+pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
+
+pub fn supertraits<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+) -> Supertraits<'tcx> {
+    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
+}
+
+pub fn transitive_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
+) -> Supertraits<'tcx> {
+    elaborate_trait_refs(tcx, bounds).filter_to_traits()
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Other
+///////////////////////////////////////////////////////////////////////////
+
+/// A filter around an iterator of predicates that makes it yield up
+/// just trait references.
+pub struct FilterToTraits<I> {
+    base_iterator: I,
+}
+
+impl<I> FilterToTraits<I> {
+    fn new(base: I) -> FilterToTraits<I> {
+        FilterToTraits { base_iterator: base }
+    }
+}
+
+impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
+    type Item = ty::PolyTraitRef<'tcx>;
+
+    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
+        while let Some(pred) = self.base_iterator.next() {
+            if let ty::Predicate::Trait(data, _) = pred {
+                return Some(data.to_poly_trait_ref());
+            }
+        }
+        None
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, upper) = self.base_iterator.size_hint();
+        (0, upper)
+    }
+}
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index e952051eb9f..4b92a2205c2 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -162,8 +162,13 @@ impl Collector<'tcx> {
             }
         }
         if lib.cfg.is_some() && !self.tcx.features().link_cfg {
-            feature_err(&self.tcx.sess.parse_sess, sym::link_cfg, span.unwrap(), "is unstable")
-                .emit();
+            feature_err(
+                &self.tcx.sess.parse_sess,
+                sym::link_cfg,
+                span.unwrap(),
+                "kind=\"link_cfg\" is unstable",
+            )
+            .emit();
         }
         if lib.kind == cstore::NativeStaticNobundle && !self.tcx.features().static_nobundle {
             feature_err(
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
deleted file mode 100644
index e74d27bafb2..00000000000
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-//! Hook into libgraphviz for rendering dataflow graphs for MIR.
-
-use rustc_hir::def_id::DefId;
-use rustc_middle::mir::{BasicBlock, Body};
-
-use std::fs;
-use std::io;
-use std::marker::PhantomData;
-use std::path::Path;
-
-use crate::util::graphviz_safe_def_name;
-
-use super::DataflowBuilder;
-use super::DebugFormatted;
-use super::{BitDenotation, DataflowState};
-
-pub trait MirWithFlowState<'tcx> {
-    type BD: BitDenotation<'tcx>;
-    fn def_id(&self) -> DefId;
-    fn body(&self) -> &Body<'tcx>;
-    fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>;
-}
-
-impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
-where
-    BD: BitDenotation<'tcx>,
-{
-    type BD = BD;
-    fn def_id(&self) -> DefId {
-        self.def_id
-    }
-    fn body(&self) -> &Body<'tcx> {
-        self.flow_state.body()
-    }
-    fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> {
-        &self.flow_state.flow_state
-    }
-}
-
-struct Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-{
-    mbcx: &'a MWF,
-    phantom: PhantomData<&'tcx ()>,
-    render_idx: P,
-}
-
-pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
-    mbcx: &DataflowBuilder<'a, 'tcx, BD>,
-    path: &Path,
-    render_idx: P,
-) -> io::Result<()>
-where
-    BD: BitDenotation<'tcx>,
-    P: Fn(&BD, BD::Idx) -> DebugFormatted,
-{
-    let g = Graph { mbcx, phantom: PhantomData, render_idx };
-    let mut v = Vec::new();
-    dot::render(&g, &mut v)?;
-    debug!("print_borrowck_graph_to path: {} def_id: {:?}", path.display(), mbcx.def_id);
-    fs::write(path, v)
-}
-
-pub type Node = BasicBlock;
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct Edge {
-    source: BasicBlock,
-    index: usize,
-}
-
-fn outgoing(body: &Body<'_>, bb: BasicBlock) -> Vec<Edge> {
-    (0..body[bb].terminator().successors().count())
-        .map(|index| Edge { source: bb, index })
-        .collect()
-}
-
-impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-    P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
-{
-    type Node = Node;
-    type Edge = Edge;
-    fn graph_id(&self) -> dot::Id<'_> {
-        let name = graphviz_safe_def_name(self.mbcx.def_id());
-        dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
-    }
-
-    fn node_id(&self, n: &Node) -> dot::Id<'_> {
-        dot::Id::new(format!("bb_{}", n.index())).unwrap()
-    }
-
-    fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
-        // Node label is something like this:
-        // +---------+----------------------------------+------------------+------------------+
-        // | ENTRY   | MIR                              | GEN              | KILL             |
-        // +---------+----------------------------------+------------------+------------------+
-        // |         |  0: StorageLive(_7)              | bb3[2]: reserved | bb2[0]: reserved |
-        // |         |  1: StorageLive(_8)              | bb3[2]: active   | bb2[0]: active   |
-        // |         |  2: _8 = &mut _1                 |                  | bb4[2]: reserved |
-        // |         |                                  |                  | bb4[2]: active   |
-        // |         |                                  |                  | bb9[0]: reserved |
-        // |         |                                  |                  | bb9[0]: active   |
-        // |         |                                  |                  | bb10[0]: reserved|
-        // |         |                                  |                  | bb10[0]: active  |
-        // |         |                                  |                  | bb11[0]: reserved|
-        // |         |                                  |                  | bb11[0]: active  |
-        // +---------+----------------------------------+------------------+------------------+
-        // | [00-00] | _7 = const Foo::twiddle(move _8) | [0c-00]          | [f3-0f]          |
-        // +---------+----------------------------------+------------------+------------------+
-        let mut v = Vec::new();
-        self.node_label_internal(n, &mut v, *n, self.mbcx.body()).unwrap();
-        dot::LabelText::html(String::from_utf8(v).unwrap())
-    }
-
-    fn node_shape(&self, _n: &Node) -> Option<dot::LabelText<'_>> {
-        Some(dot::LabelText::label("none"))
-    }
-
-    fn edge_label(&'a self, e: &Edge) -> dot::LabelText<'a> {
-        let term = self.mbcx.body()[e.source].terminator();
-        let label = &term.kind.fmt_successor_labels()[e.index];
-        dot::LabelText::label(label.clone())
-    }
-}
-
-impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-    P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
-{
-    /// Generate the node label
-    fn node_label_internal<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        // Header rows
-        const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
-        const HDR_FMT: &str = "bgcolor=\"grey\"";
-        write!(w, "<table><tr><td rowspan=\"{}\">", HDRS.len())?;
-        write!(w, "{:?}", block.index())?;
-        write!(w, "</td></tr><tr>")?;
-        for hdr in &HDRS {
-            write!(w, "<td {}>{}</td>", HDR_FMT, hdr)?;
-        }
-        write!(w, "</tr>")?;
-
-        // Data row
-        self.node_label_verbose_row(n, w, block, body)?;
-        self.node_label_final_row(n, w, block, body)?;
-        write!(w, "</table>")?;
-
-        Ok(())
-    }
-
-    /// Builds the verbose row: full MIR data, and detailed gen/kill/entry sets.
-    fn node_label_verbose_row<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        let i = n.index();
-
-        macro_rules! dump_set_for {
-            ($set:ident, $interpret:ident) => {
-                write!(w, "<td>")?;
-
-                let flow = self.mbcx.flow_state();
-                let entry_interp =
-                    flow.$interpret(&flow.operator, flow.sets.$set(i), &self.render_idx);
-                for e in &entry_interp {
-                    write!(w, "{:?}<br/>", e)?;
-                }
-                write!(w, "</td>")?;
-            };
-        }
-
-        write!(w, "<tr>")?;
-        // Entry
-        dump_set_for!(entry_set_for, interpret_set);
-
-        // MIR statements
-        write!(w, "<td>")?;
-        {
-            let data = &body[block];
-            for (i, statement) in data.statements.iter().enumerate() {
-                write!(
-                    w,
-                    "{}<br align=\"left\"/>",
-                    dot::escape_html(&format!("{:3}: {:?}", i, statement))
-                )?;
-            }
-        }
-        write!(w, "</td>")?;
-
-        // Gen
-        dump_set_for!(gen_set_for, interpret_hybrid_set);
-
-        // Kill
-        dump_set_for!(kill_set_for, interpret_hybrid_set);
-
-        write!(w, "</tr>")?;
-
-        Ok(())
-    }
-
-    /// Builds the summary row: terminator, gen/kill/entry bit sets.
-    fn node_label_final_row<W: io::Write>(
-        &self,
-        n: &Node,
-        w: &mut W,
-        block: BasicBlock,
-        body: &Body<'_>,
-    ) -> io::Result<()> {
-        let i = n.index();
-
-        let flow = self.mbcx.flow_state();
-
-        write!(w, "<tr>")?;
-
-        // Entry
-        let set = flow.sets.entry_set_for(i);
-        write!(w, "<td>{:?}</td>", dot::escape_html(&set.to_string()))?;
-
-        // Terminator
-        write!(w, "<td>")?;
-        {
-            let data = &body[block];
-            let mut terminator_head = String::new();
-            data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
-            write!(w, "{}", dot::escape_html(&terminator_head))?;
-        }
-        write!(w, "</td>")?;
-
-        // Gen/Kill
-        let trans = flow.sets.trans_for(i);
-        write!(w, "<td>{:?}</td>", dot::escape_html(&format!("{:?}", trans.gen_set)))?;
-        write!(w, "<td>{:?}</td>", dot::escape_html(&format!("{:?}", trans.kill_set)))?;
-
-        write!(w, "</tr>")?;
-
-        Ok(())
-    }
-}
-
-impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
-where
-    MWF: MirWithFlowState<'tcx>,
-{
-    type Node = Node;
-    type Edge = Edge;
-    fn nodes(&self) -> dot::Nodes<'_, Node> {
-        self.mbcx.body().basic_blocks().indices().collect::<Vec<_>>().into()
-    }
-
-    fn edges(&self) -> dot::Edges<'_, Edge> {
-        let body = self.mbcx.body();
-
-        body.basic_blocks().indices().flat_map(|bb| outgoing(body, bb)).collect::<Vec<_>>().into()
-    }
-
-    fn source(&self, edge: &Edge) -> Node {
-        edge.source
-    }
-
-    fn target(&self, edge: &Edge) -> Node {
-        let body = self.mbcx.body();
-        *body[edge.source].terminator().successors().nth(edge.index).unwrap()
-    }
-}
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index f382ef984be..4c25363a657 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -577,7 +577,7 @@ pub struct Scalar {
     pub value: Primitive,
 
     /// Inclusive wrap-around range of valid values, that is, if
-    /// start > end, it represents `start..=max_value()`,
+    /// start > end, it represents `start..=MAX`,
     /// followed by `0..=end`.
     ///
     /// That is, for an i8 primitive, a range of `254..=2` means following
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index 6348673dab8..725c41c1e2c 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -5,270 +5,11 @@ use smallvec::SmallVec;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::outlives::Component;
 use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
 
 use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
-
-fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
-    match *pred {
-        ty::Predicate::Trait(ref data, constness) => {
-            ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
-        }
-
-        ty::Predicate::RegionOutlives(ref data) => {
-            ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::TypeOutlives(ref data) => {
-            ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::Projection(ref data) => {
-            ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data),
-
-        ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data),
-
-        ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
-        }
-
-        ty::Predicate::Subtype(ref data) => {
-            ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data))
-        }
-
-        ty::Predicate::ConstEvaluatable(def_id, substs) => {
-            ty::Predicate::ConstEvaluatable(def_id, substs)
-        }
-    }
-}
-
-struct PredicateSet<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    set: FxHashSet<ty::Predicate<'tcx>>,
-}
-
-impl PredicateSet<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>) -> Self {
-        Self { tcx, set: Default::default() }
-    }
-
-    fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
-        // We have to be careful here because we want
-        //
-        //    for<'a> Foo<&'a int>
-        //
-        // and
-        //
-        //    for<'b> Foo<&'b int>
-        //
-        // to be considered equivalent. So normalize all late-bound
-        // regions before we throw things into the underlying set.
-        self.set.insert(anonymize_predicate(self.tcx, pred))
-    }
-}
-
-impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'tcx> {
-    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
-        for pred in iter {
-            self.insert(pred.as_ref());
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// `Elaboration` iterator
-///////////////////////////////////////////////////////////////////////////
-
-/// "Elaboration" is the process of identifying all the predicates that
-/// are implied by a source predicate. Currently, this basically means
-/// walking the "supertraits" and other similar assumptions. For example,
-/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
-/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
-/// `T: Foo`, then we know that `T: 'static`.
-pub struct Elaborator<'tcx> {
-    stack: Vec<ty::Predicate<'tcx>>,
-    visited: PredicateSet<'tcx>,
-}
-
-pub fn elaborate_trait_ref<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Elaborator<'tcx> {
-    elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
-}
-
-pub fn elaborate_trait_refs<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Elaborator<'tcx> {
-    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
-    elaborate_predicates(tcx, predicates)
-}
-
-pub fn elaborate_predicates<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mut predicates: Vec<ty::Predicate<'tcx>>,
-) -> Elaborator<'tcx> {
-    let mut visited = PredicateSet::new(tcx);
-    predicates.retain(|pred| visited.insert(pred));
-    Elaborator { stack: predicates, visited }
-}
-
-impl Elaborator<'tcx> {
-    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
-        FilterToTraits::new(self)
-    }
-
-    fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
-        let tcx = self.visited.tcx;
-        match *predicate {
-            ty::Predicate::Trait(ref data, _) => {
-                // Get predicates declared on the trait.
-                let predicates = tcx.super_predicates_of(data.def_id());
-
-                let predicates = predicates
-                    .predicates
-                    .iter()
-                    .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()));
-                debug!("super_predicates: data={:?} predicates={:?}", data, predicates.clone());
-
-                // Only keep those bounds that we haven't already seen.
-                // This is necessary to prevent infinite recursion in some
-                // cases. One common case is when people define
-                // `trait Sized: Sized { }` rather than `trait Sized { }`.
-                let visited = &mut self.visited;
-                let predicates = predicates.filter(|pred| visited.insert(pred));
-
-                self.stack.extend(predicates);
-            }
-            ty::Predicate::WellFormed(..) => {
-                // Currently, we do not elaborate WF predicates,
-                // although we easily could.
-            }
-            ty::Predicate::ObjectSafe(..) => {
-                // Currently, we do not elaborate object-safe
-                // predicates.
-            }
-            ty::Predicate::Subtype(..) => {
-                // Currently, we do not "elaborate" predicates like `X <: Y`,
-                // though conceivably we might.
-            }
-            ty::Predicate::Projection(..) => {
-                // Nothing to elaborate in a projection predicate.
-            }
-            ty::Predicate::ClosureKind(..) => {
-                // Nothing to elaborate when waiting for a closure's kind to be inferred.
-            }
-            ty::Predicate::ConstEvaluatable(..) => {
-                // Currently, we do not elaborate const-evaluatable
-                // predicates.
-            }
-            ty::Predicate::RegionOutlives(..) => {
-                // Nothing to elaborate from `'a: 'b`.
-            }
-            ty::Predicate::TypeOutlives(ref data) => {
-                // We know that `T: 'a` for some type `T`. We can
-                // often elaborate this. For example, if we know that
-                // `[U]: 'a`, that implies that `U: 'a`. Similarly, if
-                // we know `&'a U: 'b`, then we know that `'a: 'b` and
-                // `U: 'b`.
-                //
-                // We can basically ignore bound regions here. So for
-                // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to
-                // `'a: 'b`.
-
-                // Ignore `for<'a> T: 'a` -- we might in the future
-                // consider this as evidence that `T: 'static`, but
-                // I'm a bit wary of such constructions and so for now
-                // I want to be conservative. --nmatsakis
-                let ty_max = data.skip_binder().0;
-                let r_min = data.skip_binder().1;
-                if r_min.is_late_bound() {
-                    return;
-                }
-
-                let visited = &mut self.visited;
-                let mut components = smallvec![];
-                tcx.push_outlives_components(ty_max, &mut components);
-                self.stack.extend(
-                    components
-                        .into_iter()
-                        .filter_map(|component| match component {
-                            Component::Region(r) => {
-                                if r.is_late_bound() {
-                                    None
-                                } else {
-                                    Some(ty::Predicate::RegionOutlives(ty::Binder::dummy(
-                                        ty::OutlivesPredicate(r, r_min),
-                                    )))
-                                }
-                            }
-
-                            Component::Param(p) => {
-                                let ty = tcx.mk_ty_param(p.index, p.name);
-                                Some(ty::Predicate::TypeOutlives(ty::Binder::dummy(
-                                    ty::OutlivesPredicate(ty, r_min),
-                                )))
-                            }
-
-                            Component::UnresolvedInferenceVariable(_) => None,
-
-                            Component::Projection(_) | Component::EscapingProjection(_) => {
-                                // We can probably do more here. This
-                                // corresponds to a case like `<T as
-                                // Foo<'a>>::U: 'b`.
-                                None
-                            }
-                        })
-                        .filter(|p| visited.insert(p)),
-                );
-            }
-        }
-    }
-}
-
-impl Iterator for Elaborator<'tcx> {
-    type Item = ty::Predicate<'tcx>;
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.stack.len(), None)
-    }
-
-    fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
-        // Extract next item from top-most stack frame, if any.
-        if let Some(pred) = self.stack.pop() {
-            self.elaborate(&pred);
-            Some(pred)
-        } else {
-            None
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Supertrait iterator
-///////////////////////////////////////////////////////////////////////////
-
-pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
-
-pub fn supertraits<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Supertraits<'tcx> {
-    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
-}
-
-pub fn transitive_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Supertraits<'tcx> {
-    elaborate_trait_refs(tcx, bounds).filter_to_traits()
-}
+pub use rustc_infer::traits::util::*;
 
 ///////////////////////////////////////////////////////////////////////////
 // `TraitAliasExpander` iterator
@@ -450,40 +191,6 @@ impl Iterator for SupertraitDefIds<'tcx> {
 // Other
 ///////////////////////////////////////////////////////////////////////////
 
-/// A filter around an iterator of predicates that makes it yield up
-/// just trait references.
-pub struct FilterToTraits<I> {
-    base_iterator: I,
-}
-
-impl<I> FilterToTraits<I> {
-    fn new(base: I) -> FilterToTraits<I> {
-        FilterToTraits { base_iterator: base }
-    }
-}
-
-impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
-    type Item = ty::PolyTraitRef<'tcx>;
-
-    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
-        while let Some(pred) = self.base_iterator.next() {
-            if let ty::Predicate::Trait(data, _) = pred {
-                return Some(data.to_poly_trait_ref());
-            }
-        }
-        None
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (_, upper) = self.base_iterator.size_hint();
-        (0, upper)
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Other
-///////////////////////////////////////////////////////////////////////////
-
 /// Instantiate all bound parameters of the impl with the given substs,
 /// returning the resulting trait ref and all obligations that arise.
 /// The obligations are closed under normalization.
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 20425aea8d5..ac8f305ae91 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -284,7 +284,7 @@ impl f32 {
     /// assert_eq!(a.rem_euclid(-b), 3.0);
     /// assert_eq!((-a).rem_euclid(-b), 1.0);
     /// // limitation due to round-off error
-    /// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0);
+    /// assert!((-f32::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
@@ -962,7 +962,7 @@ impl f32 {
     /// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0);
     /// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0);
     /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
-    /// assert!((std::f32::NAN).clamp(-2.0, 1.0).is_nan());
+    /// assert!((f32::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index a1128a589a6..798738e50a7 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -280,7 +280,7 @@ impl f64 {
     /// assert_eq!(a.rem_euclid(-b), 3.0);
     /// assert_eq!((-a).rem_euclid(-b), 1.0);
     /// // limitation due to round-off error
-    /// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0);
+    /// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
@@ -928,7 +928,7 @@ impl f64 {
     /// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0);
     /// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0);
     /// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
-    /// assert!((std::f64::NAN).clamp(-2.0, 1.0).is_nan());
+    /// assert!((f64::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
diff --git a/src/libstd/sys/cloudabi/stack_overflow.rs b/src/libstd/sys/cloudabi/stack_overflow.rs
index e97831b2c28..9339b143731 100644
--- a/src/libstd/sys/cloudabi/stack_overflow.rs
+++ b/src/libstd/sys/cloudabi/stack_overflow.rs
@@ -1,13 +1,5 @@
 #![cfg_attr(test, allow(dead_code))]
 
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 3afcae7ae75..a15dc8653e8 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -5,7 +5,6 @@ use crate::mem;
 use crate::ptr;
 use crate::sys::cloudabi::abi;
 use crate::sys::time::checked_dur2intervals;
-use crate::sys_common::thread::*;
 use crate::time::Duration;
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
@@ -22,7 +21,7 @@ unsafe impl Sync for Thread {}
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -30,19 +29,25 @@ impl Thread {
         let stack_size = cmp::max(stack, min_stack_size(&attr));
         assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/hermit/stack_overflow.rs b/src/libstd/sys/hermit/stack_overflow.rs
index 65a1b17acce..121fe42011d 100644
--- a/src/libstd/sys/hermit/stack_overflow.rs
+++ b/src/libstd/sys/hermit/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[inline]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs
index c3c29c93826..c7bea168f34 100644
--- a/src/libstd/sys/hermit/thread.rs
+++ b/src/libstd/sys/hermit/thread.rs
@@ -8,8 +8,6 @@ use crate::sys::hermit::abi;
 use crate::time::Duration;
 use core::u32;
 
-use crate::sys_common::thread::*;
-
 pub type Tid = abi::Tid;
 
 /// Priority of a task
@@ -49,26 +47,29 @@ impl Thread {
         p: Box<dyn FnOnce()>,
         core_id: isize,
     ) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut tid: Tid = u32::MAX;
         let ret = abi::spawn(
             &mut tid as *mut Tid,
             thread_start,
-            &*p as *const _ as *const u8 as usize,
+            p as usize,
             Priority::into(NORMAL_PRIO),
             core_id,
         );
 
-        return if ret == 0 {
-            mem::forget(p); // ownership passed to pthread_create
-            Ok(Thread { tid: tid })
-        } else {
+        return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
+        } else {
+            Ok(Thread { tid: tid })
         };
 
         extern "C" fn thread_start(main: usize) {
             unsafe {
-                start_thread(main as *mut u8);
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
         }
     }
diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs
index a2d13d11849..b96652a8330 100644
--- a/src/libstd/sys/sgx/stack_overflow.rs
+++ b/src/libstd/sys/sgx/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 #[cfg_attr(test, allow(dead_code))]
 pub unsafe fn init() {}
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 674d4c71138..aab5a92a7ad 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 #[cfg(not(target_os = "l4re"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
 #[cfg(target_os = "l4re")]
@@ -43,7 +41,7 @@ unsafe fn pthread_attr_setstacksize(
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -65,19 +63,28 @@ impl Thread {
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index e0d104b5f3e..4d0196e4b4d 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -3,11 +3,9 @@ use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::ptr;
-use crate::sys::os;
+use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-use crate::sys_common::thread::*;
-
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0x40000; // 256K
 
 pub struct Thread {
@@ -31,7 +29,7 @@ unsafe fn pthread_attr_setstacksize(
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -53,19 +51,28 @@ impl Thread {
             }
         };
 
-        let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _);
+        let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
 
         return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::from_raw_os_error(ret))
         } else {
-            mem::forget(p); // ownership passed to pthread_create
             Ok(Thread { id: native })
         };
 
         extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             ptr::null_mut()
         }
diff --git a/src/libstd/sys/wasm/stack_overflow.rs b/src/libstd/sys/wasm/stack_overflow.rs
index cbf62b6e5b7..32555394cd5 100644
--- a/src/libstd/sys/wasm/stack_overflow.rs
+++ b/src/libstd/sys/wasm/stack_overflow.rs
@@ -1,11 +1,3 @@
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        Handler
-    }
-}
-
 pub unsafe fn init() {}
 
 pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index c828243a59b..38839ea5e90 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -1,10 +1,9 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::mem;
 use crate::ptr;
 use crate::sys::c;
 use crate::sys::handle::Handle;
-use crate::sys_common::thread::*;
+use crate::sys::stack_overflow;
 use crate::time::Duration;
 
 use libc::c_void;
@@ -20,7 +19,7 @@ pub struct Thread {
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
+        let p = Box::into_raw(box p);
 
         // FIXME On UNIX, we guard against stack sizes that are too small but
         // that's because pthreads enforces that stacks are at least
@@ -34,21 +33,27 @@ impl Thread {
             ptr::null_mut(),
             stack_size,
             thread_start,
-            &*p as *const _ as *mut _,
+            p as *mut _,
             c::STACK_SIZE_PARAM_IS_A_RESERVATION,
             ptr::null_mut(),
         );
 
         return if ret as usize == 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            drop(Box::from_raw(p));
             Err(io::Error::last_os_error())
         } else {
-            mem::forget(p); // ownership passed to CreateThread
             Ok(Thread { handle: Handle::new(ret) })
         };
 
         extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
             unsafe {
-                start_thread(main as *mut u8);
+                // Next, set up our stack overflow handler which may get triggered if we run
+                // out of stack.
+                let _handler = stack_overflow::Handler::new();
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
             0
         }
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
index 6ab0d5cbe9c..f3a8bef8f71 100644
--- a/src/libstd/sys_common/thread.rs
+++ b/src/libstd/sys_common/thread.rs
@@ -1,18 +1,7 @@
 use crate::env;
 use crate::sync::atomic::{self, Ordering};
-use crate::sys::stack_overflow;
 use crate::sys::thread as imp;
 
-#[allow(dead_code)]
-pub unsafe fn start_thread(main: *mut u8) {
-    // Next, set up our stack overflow handler which may get triggered if we run
-    // out of stack.
-    let _handler = stack_overflow::Handler::new();
-
-    // Finally, let's run some code.
-    Box::from_raw(main as *mut Box<dyn FnOnce()>)()
-}
-
 pub fn min_stack() -> usize {
     static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
     match MIN.load(Ordering::SeqCst) {
diff --git a/src/test/ui/async-await/issue-70594.rs b/src/test/ui/async-await/issue-70594.rs
new file mode 100644
index 00000000000..e78231a6851
--- /dev/null
+++ b/src/test/ui/async-await/issue-70594.rs
@@ -0,0 +1,12 @@
+// edition:2018
+
+async fn fun() {
+    [1; ().await];
+    //~^ error: `await` is only allowed inside `async` functions and blocks
+    //~| error: `.await` is not allowed in a `const`
+    //~| error: `loop` is not allowed in a `const`
+    //~| error: `.await` is not allowed in a `const`
+    //~| error: the trait bound `(): std::future::Future` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
new file mode 100644
index 00000000000..d2fa7e58f6a
--- /dev/null
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -0,0 +1,44 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL | async fn fun() {
+   |          --- this is not `async`
+LL |     [1; ().await];
+   |         ^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0744]: `.await` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+
+error[E0658]: `loop` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+   |
+   = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information
+   = help: add `#![feature(const_loop)]` to the crate attributes to enable
+
+error[E0744]: `.await` is not allowed in a `const`
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^
+
+error[E0277]: the trait bound `(): std::future::Future` is not satisfied
+  --> $DIR/issue-70594.rs:4:9
+   |
+LL |     [1; ().await];
+   |         ^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
+   | 
+  ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
+   |
+LL |     F: Future,
+   |        ------ required by this bound in `std::future::poll_with_context`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0658, E0728, E0744.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
index 10b151ffa75..41a7dfc3f37 100644
--- a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
+++ b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
@@ -1,4 +1,4 @@
-error[E0658]: is unstable
+error[E0658]: kind="link_cfg" is unstable
   --> $DIR/feature-gate-link_cfg.rs:1:1
    |
 LL | #[link(name = "foo", cfg(foo))]
diff --git a/src/test/ui/issues/issue-70673.rs b/src/test/ui/issues/issue-70673.rs
new file mode 100644
index 00000000000..3561f401277
--- /dev/null
+++ b/src/test/ui/issues/issue-70673.rs
@@ -0,0 +1,12 @@
+// Regression test for https://github.com/rust-lang/rust/issues/70673.
+
+// run-pass
+
+#![feature(thread_local)]
+
+#[thread_local]
+static A: &u8 = &42;
+
+fn main() {
+    dbg!(*A);
+}
diff --git a/src/test/ui/traits/impl_trait_as_trait_return_position.rs b/src/test/ui/traits/impl_trait_as_trait_return_position.rs
new file mode 100644
index 00000000000..c3325fd80ca
--- /dev/null
+++ b/src/test/ui/traits/impl_trait_as_trait_return_position.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait A {
+    type Foo;
+}
+
+impl<T> A for T {
+    type Foo = ();
+}
+
+fn foo() -> impl std::borrow::Borrow<<u8 as A>::Foo> {
+    ()
+}
+
+fn main() {
+    foo();
+}