about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/liballoc/tests/lib.rs1
-rw-r--r--src/liballoc/tests/vec.rs15
-rw-r--r--src/liballoc/vec.rs7
-rw-r--r--src/libcore/convert/num.rs28
-rw-r--r--src/libcore/fmt/num.rs4
-rw-r--r--src/libcore/iter/traits/accum.rs16
-rw-r--r--src/libcore/macros/mod.rs2
-rw-r--r--src/libcore/marker.rs8
-rw-r--r--src/libcore/num/bignum.rs4
-rw-r--r--src/libcore/num/mod.rs3
-rw-r--r--src/librustc/infer/error_reporting/mod.rs20
-rw-r--r--src/librustc/traits/error_reporting.rs6
-rw-r--r--src/librustc/ty/instance.rs27
-rw-r--r--src/librustc/ty/layout.rs2
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/consts.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs2
-rw-r--r--src/librustc_data_structures/flock.rs121
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs2
-rw-r--r--src/librustc_mir/interpret/traits.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs5
-rw-r--r--src/librustc_passes/entry.rs2
-rw-r--r--src/librustc_target/spec/wasm32_base.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs4
-rw-r--r--src/librustc_typeck/impl_wf_check.rs5
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs32
-rw-r--r--src/librustdoc/test.rs148
-rw-r--r--src/libstd/f32.rs2
-rw-r--r--src/libstd/f64.rs2
-rw-r--r--src/libsyntax/feature_gate/check.rs4
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.stderr128
-rw-r--r--src/test/rustdoc/playground-syntax-error.rs21
-rw-r--r--src/test/ui/async-await/issue-66387-if-without-else.rs2
-rw-r--r--src/test/ui/async-await/issue-66387-if-without-else.stderr2
-rw-r--r--src/test/ui/bad/bad-expr-path.rs2
-rw-r--r--src/test/ui/bad/bad-expr-path.stderr2
-rw-r--r--src/test/ui/bad/bad-expr-path2.rs2
-rw-r--r--src/test/ui/bad/bad-expr-path2.stderr2
-rw-r--r--src/test/ui/bad/bad-main.rs2
-rw-r--r--src/test/ui/bad/bad-main.stderr2
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.rs23
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.stderr8
-rw-r--r--src/test/ui/consts/control-flow/issue-50577.if_match.stderr2
-rw-r--r--src/test/ui/consts/control-flow/issue-50577.rs2
-rw-r--r--src/test/ui/consts/control-flow/issue-50577.stock.stderr2
-rw-r--r--src/test/ui/error-codes/E0138.stderr2
-rw-r--r--src/test/ui/extern/extern-main-fn.rs2
-rw-r--r--src/test/ui/extern/extern-main-fn.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-start.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-start.stderr2
-rw-r--r--src/test/ui/if-else-type-mismatch.rs16
-rw-r--r--src/test/ui/if-else-type-mismatch.stderr28
-rw-r--r--src/test/ui/if/if-branch-types.rs2
-rw-r--r--src/test/ui/if/if-branch-types.stderr2
-rw-r--r--src/test/ui/if/if-let-arm-types.rs4
-rw-r--r--src/test/ui/if/if-let-arm-types.stderr4
-rw-r--r--src/test/ui/if/if-without-else-as-fn-expr.rs12
-rw-r--r--src/test/ui/if/if-without-else-as-fn-expr.stderr12
-rw-r--r--src/test/ui/if/if-without-else-result.rs2
-rw-r--r--src/test/ui/if/if-without-else-result.stderr2
-rw-r--r--src/test/ui/issues/issue-11319.rs2
-rw-r--r--src/test/ui/issues/issue-11319.stderr2
-rw-r--r--src/test/ui/issues/issue-17728.nll.stderr2
-rw-r--r--src/test/ui/issues/issue-17728.rs2
-rw-r--r--src/test/ui/issues/issue-17728.stderr2
-rw-r--r--src/test/ui/issues/issue-19991.rs4
-rw-r--r--src/test/ui/issues/issue-19991.stderr2
-rw-r--r--src/test/ui/issues/issue-24036.rs2
-rw-r--r--src/test/ui/issues/issue-24036.stderr2
-rw-r--r--src/test/ui/issues/issue-4201.rs2
-rw-r--r--src/test/ui/issues/issue-4201.stderr2
-rw-r--r--src/test/ui/issues/issue-8460.rs4
-rw-r--r--src/test/ui/issues/issue-9575.rs2
-rw-r--r--src/test/ui/issues/issue-9575.stderr2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr.rs2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr.stderr2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.rs2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.stderr2
-rw-r--r--src/test/ui/main-wrong-type.rs2
-rw-r--r--src/test/ui/main-wrong-type.stderr2
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.rs2
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.stderr2
-rw-r--r--src/test/ui/match/match-type-err-first-arm.rs6
-rw-r--r--src/test/ui/match/match-type-err-first-arm.stderr6
-rw-r--r--src/test/ui/mir/issue-67639-normalization-ice.rs34
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs2
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr4
-rw-r--r--src/test/ui/regions/region-invariant-static-error-reporting.stderr4
-rw-r--r--src/test/ui/str/str-array-assignment.rs2
-rw-r--r--src/test/ui/str/str-array-assignment.stderr2
-rw-r--r--src/test/ui/suggestions/opaque-type-error.rs2
-rw-r--r--src/test/ui/suggestions/opaque-type-error.stderr4
-rw-r--r--src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs2
-rw-r--r--src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr2
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr2
m---------src/tools/clippy16
m---------src/tools/rls0
101 files changed, 455 insertions, 471 deletions
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index 3fdee8bbfdf..c1ae67a1a33 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -11,6 +11,7 @@
 #![feature(associated_type_bounds)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(binary_heap_drain_sorted)]
+#![feature(vec_remove_item)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 19acc70c73c..2a9bfefc713 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -132,6 +132,21 @@ fn test_extend_ref() {
 }
 
 #[test]
+fn test_remove_item() {
+    let mut v = vec![1, 2, 3];
+    v.remove_item(&1);
+
+    assert_eq!(v.len(), 2);
+    assert_eq!(v, [2, 3]);
+
+    let mut w = vec![1, 2, 3];
+    w.remove_item(&4);
+
+    assert_eq!(w.len(), 3);
+    w.remove_item(&4);
+}
+
+#[test]
 fn test_slice_from_mut() {
     let mut values = vec![1, 2, 3, 4, 5];
     {
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 93a51ccb207..a27a13847d6 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1688,7 +1688,9 @@ impl<T: PartialEq> Vec<T> {
     pub fn dedup(&mut self) {
         self.dedup_by(|a, b| a == b)
     }
+}
 
+impl<T> Vec<T> {
     /// Removes the first instance of `item` from the vector if the item exists.
     ///
     /// # Examples
@@ -1702,7 +1704,10 @@ impl<T: PartialEq> Vec<T> {
     /// assert_eq!(vec, vec![2, 3, 1]);
     /// ```
     #[unstable(feature = "vec_remove_item", reason = "recently added", issue = "40062")]
-    pub fn remove_item(&mut self, item: &T) -> Option<T> {
+    pub fn remove_item<V>(&mut self, item: &V) -> Option<T>
+    where
+        T: PartialEq<V>,
+    {
         let pos = self.iter().position(|x| *x == *item)?;
         Some(self.remove(pos))
     }
diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs
index 596da6f786b..752199c94b8 100644
--- a/src/libcore/convert/num.rs
+++ b/src/libcore/convert/num.rs
@@ -47,8 +47,8 @@ macro_rules! impl_from {
         #[doc = $doc]
         impl From<$Small> for $Large {
             #[inline]
-            fn from(small: $Small) -> $Large {
-                small as $Large
+            fn from(small: $Small) -> Self {
+                small as Self
             }
         }
     };
@@ -177,7 +177,7 @@ macro_rules! try_from_unbounded {
             /// is outside of the range of the target type.
             #[inline]
             fn try_from(value: $source) -> Result<Self, Self::Error> {
-                Ok(value as $target)
+                Ok(value as Self)
             }
         }
     )*}
@@ -194,9 +194,9 @@ macro_rules! try_from_lower_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
                 if u >= 0 {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 } else {
                     Err(TryFromIntError(()))
                 }
@@ -216,11 +216,11 @@ macro_rules! try_from_upper_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
-                if u > (<$target>::max_value() as $source) {
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
+                if u > (Self::max_value() as $source) {
                     Err(TryFromIntError(()))
                 } else {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 }
             }
         }
@@ -238,13 +238,13 @@ macro_rules! try_from_both_bounded {
             /// number type. This returns an error if the source value
             /// is outside of the range of the target type.
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
-                let min = <$target>::min_value() as $source;
-                let max = <$target>::max_value() as $source;
+            fn try_from(u: $source) -> Result<Self, Self::Error> {
+                let min = Self::min_value() as $source;
+                let max = Self::max_value() as $source;
                 if u < min || u > max {
                     Err(TryFromIntError(()))
                 } else {
-                    Ok(u as $target)
+                    Ok(u as Self)
                 }
             }
         }
@@ -385,10 +385,10 @@ macro_rules! nzint_impl_from {
         #[doc = $doc]
         impl From<$Small> for $Large {
             #[inline]
-            fn from(small: $Small) -> $Large {
+            fn from(small: $Small) -> Self {
                 // SAFETY: input type guarantees the value is non-zero
                 unsafe {
-                    <$Large>::new_unchecked(small.get().into())
+                    Self::new_unchecked(small.get().into())
                 }
             }
         }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 7b20677ffb5..d562639a658 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -24,8 +24,8 @@ trait Int:
 
 macro_rules! doit {
     ($($t:ident)*) => ($(impl Int for $t {
-        fn zero() -> $t { 0 }
-        fn from_u8(u: u8) -> $t { u as $t }
+        fn zero() -> Self { 0 }
+        fn from_u8(u: u8) -> Self { u as Self }
         fn to_u8(&self) -> u8 { *self as u8 }
         fn to_u16(&self) -> u16 { *self as u16 }
         fn to_u32(&self) -> u32 { *self as u32 }
diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs
index 65af671ddf2..55f30794af6 100644
--- a/src/libcore/iter/traits/accum.rs
+++ b/src/libcore/iter/traits/accum.rs
@@ -44,28 +44,28 @@ macro_rules! integer_sum_product {
     (@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
         #[$attr]
         impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold($zero, Add::add)
             }
         }
 
         #[$attr]
         impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold($one, Mul::mul)
             }
         }
 
         #[$attr]
         impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold($zero, Add::add)
             }
         }
 
         #[$attr]
         impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold($one, Mul::mul)
             }
         }
@@ -84,28 +84,28 @@ macro_rules! float_sum_product {
     ($($a:ident)*) => ($(
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
-            fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
-            fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold(1.0, Mul::mul)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
-            fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
-            fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
+            fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold(1.0, Mul::mul)
             }
         }
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
index 0eb9e194236..76e58f0cc62 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -551,7 +551,7 @@ macro_rules! unreachable {
 
 /// Indicates unimplemented code by panicking with a message of "not implemented".
 ///
-/// This allows the your code to type-check, which is useful if you are prototyping or
+/// This allows your code to type-check, which is useful if you are prototyping or
 /// implementing a trait that requires multiple methods which you don't plan of using all of.
 ///
 /// The difference between `unimplemented!` and [`todo!`](macro.todo.html) is that while `todo!`
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3b98bc1c272..b4b595f330e 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -505,15 +505,15 @@ macro_rules! impls {
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl<T: ?Sized> Clone for $t<T> {
-            fn clone(&self) -> $t<T> {
-                $t
+            fn clone(&self) -> Self {
+                Self
             }
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl<T: ?Sized> Default for $t<T> {
-            fn default() -> $t<T> {
-                $t
+            fn default() -> Self {
+                Self
             }
         }
 
diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs
index 39cc381b64c..6f16b93d048 100644
--- a/src/libcore/num/bignum.rs
+++ b/src/libcore/num/bignum.rs
@@ -455,8 +455,8 @@ macro_rules! define_bignum {
         }
 
         impl crate::clone::Clone for $name {
-            fn clone(&self) -> $name {
-                $name { size: self.size, base: self.base }
+            fn clone(&self) -> Self {
+                Self { size: self.size, base: self.base }
             }
         }
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 605ab98219f..b6b4a46e0b8 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2001,6 +2001,9 @@ $EndFeature, "
             #[inline]
             #[rustc_inherit_overflow_checks]
             pub const fn abs(self) -> Self {
+                // Note that the #[inline] above means that the overflow
+                // semantics of the subtraction depend on the crate we're being
+                // inlined into.
                 if self.is_negative() {
                     -self
                 } else {
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index e161ecfa7fa..90f546113c1 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -662,7 +662,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             },
             ObligationCauseCode::IfExpression(box IfExpressionCause { then, outer, semicolon }) => {
                 err.span_label(then, "expected because of this");
-                outer.map(|sp| err.span_label(sp, "if and else have incompatible types"));
+                outer.map(|sp| err.span_label(sp, "`if` and `else` have incompatible types"));
                 if let Some(sp) = semicolon {
                     err.span_suggestion_short(
                         sp,
@@ -1884,13 +1884,13 @@ impl<'tcx> ObligationCause<'tcx> {
                     hir::MatchSource::TryDesugar => {
                         "try expression alternatives have incompatible types"
                     }
-                    _ => "match arms have incompatible types",
+                    _ => "`match` arms have incompatible types",
                 })
             }
-            IfExpression { .. } => Error0308("if and else have incompatible types"),
-            IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
-            MainFunctionType => Error0580("main function has wrong type"),
-            StartFunctionType => Error0308("start function has wrong type"),
+            IfExpression { .. } => Error0308("`if` and `else` have incompatible types"),
+            IfExpressionWithNoElse => Error0317("`if` may be missing an `else` clause"),
+            MainFunctionType => Error0580("`main` function has wrong type"),
+            StartFunctionType => Error0308("`#[start]` function has wrong type"),
             IntrinsicType => Error0308("intrinsic has wrong type"),
             MethodReceiver => Error0308("mismatched `self` parameter type"),
 
@@ -1918,12 +1918,12 @@ impl<'tcx> ObligationCause<'tcx> {
             ExprAssignable => "expression is assignable",
             MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
                 hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
-                _ => "match arms have compatible types",
+                _ => "`match` arms have compatible types",
             },
-            IfExpression { .. } => "if and else have incompatible types",
-            IfExpressionWithNoElse => "if missing an else returns ()",
+            IfExpression { .. } => "`if` and `else` have incompatible types",
+            IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
             MainFunctionType => "`main` function has the correct type",
-            StartFunctionType => "`start` function has the correct type",
+            StartFunctionType => "`#[start]` function has the correct type",
             IntrinsicType => "intrinsic has the correct type",
             MethodReceiver => "method receiver has the correct type",
             _ => "types are compatible",
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 238371ee774..b5030f3efe9 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -9,6 +9,7 @@ use super::{
 use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode;
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
+use crate::mir::interpret::ErrorHandled;
 use crate::session::DiagnosticMessageId;
 use crate::ty::error::ExpectedFound;
 use crate::ty::fast_reject;
@@ -1084,6 +1085,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
             // already reported in the query
             ConstEvalFailure(err) => {
+                if let ErrorHandled::TooGeneric = err {
+                    // Silence this error, as it can be produced during intermediate steps
+                    // when a constant is not yet able to be evaluated (but will be later).
+                    return;
+                }
                 self.tcx.sess.delay_span_bug(
                     span,
                     &format!("constant in type had an ignored error: {:?}", err),
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 423fc274ade..0db49183d10 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -62,10 +62,35 @@ pub enum InstanceDef<'tcx> {
 }
 
 impl<'tcx> Instance<'tcx> {
-    pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    /// Returns the `Ty` corresponding to this `Instance`,
+    /// with generic substitutions applied and lifetimes erased.
+    ///
+    /// This method can only be called when the 'substs' for this Instance
+    /// are fully monomorphic (no `ty::Param`'s are present).
+    /// This is usually the case (e.g. during codegen).
+    /// However, during constant evaluation, we may want
+    /// to try to resolve a `Instance` using generic parameters
+    /// (e.g. when we are attempting to to do const-propagation).
+    /// In this case, `Instance.ty_env` should be used to provide
+    /// the `ParamEnv` for our generic context.
+    pub fn monomorphic_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         let ty = tcx.type_of(self.def.def_id());
+        // There shouldn't be any params - if there are, then
+        // Instance.ty_env should have been used to provide the proper
+        // ParamEnv
+        if self.substs.has_param_types() {
+            bug!("Instance.ty called for type {:?} with params in substs: {:?}", ty, self.substs);
+        }
         tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty)
     }
+
+    /// Like `Instance.ty`, but allows a `ParamEnv` to be specified for use during
+    /// normalization. This method is only really useful during constant evaluation,
+    /// where we are dealing with potentially generic types.
+    pub fn ty_env(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
+        let ty = tcx.type_of(self.def.def_id());
+        tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
+    }
 }
 
 impl<'tcx> InstanceDef<'tcx> {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 663de36e839..4b7304e7c1e 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -2301,7 +2301,7 @@ impl<'tcx> ty::Instance<'tcx> {
     // or should go through `FnAbi` instead, to avoid losing any
     // adjustments `FnAbi::of_instance` might be performing.
     fn fn_sig_for_fn_abi(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        let ty = self.ty(tcx);
+        let ty = self.monomorphic_ty(tcx);
         match ty.kind {
             ty::FnDef(..) |
             // Shims currently have type FnPtr. Not sure this should remain.
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 7be179a2098..78dd6fc8ffe 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -36,7 +36,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
     }
 
     let sym = tcx.symbol_name(instance).name.as_str();
-    debug!("get_fn({:?}: {:?}) => {}", instance, instance.ty(cx.tcx()), sym);
+    debug!("get_fn({:?}: {:?}) => {}", instance, instance.monomorphic_ty(cx.tcx()), sym);
 
     let fn_abi = FnAbi::of_instance(cx, instance, &[]);
 
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 88850e19d8f..38090cb26bc 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -205,7 +205,7 @@ impl CodegenCx<'ll, 'tcx> {
             def_id
         );
 
-        let ty = instance.ty(self.tcx);
+        let ty = instance.monomorphic_ty(self.tcx);
         let sym = self.tcx.symbol_name(instance).name;
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
@@ -362,7 +362,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
             };
 
             let instance = Instance::mono(self.tcx, def_id);
-            let ty = instance.ty(self.tcx);
+            let ty = instance.monomorphic_ty(self.tcx);
             let llty = self.layout_of(ty).llvm_type(self);
             let g = if val_llty == llty {
                 g
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index c2ce35f9197..8d8e86de4d4 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -2287,7 +2287,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     };
 
     let is_local_to_unit = is_node_local_to_unit(cx, def_id);
-    let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
+    let variable_type = Instance::mono(cx.tcx, def_id).monomorphic_ty(cx.tcx);
     let type_metadata = type_metadata(cx, variable_type, span);
     let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
     let linkage_name = if no_mangle {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index fea769dbba6..8ea50a972ec 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -89,7 +89,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         span: Span,
     ) {
         let tcx = self.tcx;
-        let callee_ty = instance.ty(tcx);
+        let callee_ty = instance.monomorphic_ty(tcx);
 
         let (def_id, substs) = match callee_ty.kind {
             ty::FnDef(def_id, substs) => (def_id, substs),
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index c7b5c5e3db6..97393e69e99 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -22,7 +22,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         symbol_name: &str,
     ) {
         let instance = Instance::mono(self.tcx, def_id);
-        let ty = instance.ty(self.tcx);
+        let ty = instance.monomorphic_ty(self.tcx);
         let llty = self.layout_of(ty).llvm_type(self);
 
         let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs
index 01f25a054f0..e3282c5d276 100644
--- a/src/librustc_data_structures/flock.rs
+++ b/src/librustc_data_structures/flock.rs
@@ -13,96 +13,9 @@ use std::path::Path;
 cfg_if! {
     if #[cfg(unix)] {
         use std::ffi::{CString, OsStr};
+        use std::mem;
         use std::os::unix::prelude::*;
 
-        #[cfg(any(target_os = "linux", target_os = "android"))]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_pid: libc::pid_t,
-
-                // not actually here, but brings in line with freebsd
-                pub l_sysid: libc::c_int,
-            }
-        }
-
-        #[cfg(target_os = "freebsd")]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_pid: libc::pid_t,
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-                pub l_sysid: libc::c_int,
-            }
-        }
-
-        #[cfg(any(target_os = "dragonfly",
-                  target_os = "netbsd",
-                  target_os = "openbsd"))]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_pid: libc::pid_t,
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-
-                // not actually here, but brings in line with freebsd
-                pub l_sysid: libc::c_int,
-            }
-        }
-
-        #[cfg(target_os = "haiku")]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_pid: libc::pid_t,
-
-                // not actually here, but brings in line with freebsd
-                pub l_sysid: libc::c_int,
-            }
-        }
-
-        #[cfg(any(target_os = "macos", target_os = "ios"))]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_pid: libc::pid_t,
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-
-                // not actually here, but brings in line with freebsd
-                pub l_sysid: libc::c_int,
-            }
-        }
-
-        #[cfg(target_os = "solaris")]
-        mod os {
-            #[repr(C)]
-            pub struct flock {
-                pub l_type: libc::c_short,
-                pub l_whence: libc::c_short,
-                pub l_start: libc::off_t,
-                pub l_len: libc::off_t,
-                pub l_sysid: libc::c_int,
-                pub l_pid: libc::pid_t,
-            }
-        }
-
         #[derive(Debug)]
         pub struct Lock {
             fd: libc::c_int,
@@ -132,19 +45,17 @@ cfg_if! {
                 }
 
                 let lock_type = if exclusive {
-                    libc::F_WRLCK as libc::c_short
+                    libc::F_WRLCK
                 } else {
-                    libc::F_RDLCK as libc::c_short
+                    libc::F_RDLCK
                 };
 
-                let flock = os::flock {
-                    l_start: 0,
-                    l_len: 0,
-                    l_pid: 0,
-                    l_whence: libc::SEEK_SET as libc::c_short,
-                    l_type: lock_type,
-                    l_sysid: 0,
-                };
+                let mut flock: libc::flock = unsafe { mem::zeroed() };
+                flock.l_type = lock_type as libc::c_short;
+                flock.l_whence = libc::SEEK_SET as libc::c_short;
+                flock.l_start = 0;
+                flock.l_len = 0;
+
                 let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK };
                 let ret = unsafe {
                     libc::fcntl(fd, cmd, &flock)
@@ -161,14 +72,12 @@ cfg_if! {
 
         impl Drop for Lock {
             fn drop(&mut self) {
-                let flock = os::flock {
-                    l_start: 0,
-                    l_len: 0,
-                    l_pid: 0,
-                    l_whence: libc::SEEK_SET as libc::c_short,
-                    l_type: libc::F_UNLCK as libc::c_short,
-                    l_sysid: 0,
-                };
+                let mut flock: libc::flock = unsafe { mem::zeroed() };
+                flock.l_type = libc::F_UNLCK as libc::c_short;
+                flock.l_whence = libc::SEEK_SET as libc::c_short;
+                flock.l_start = 0;
+                flock.l_len = 0;
+
                 unsafe {
                     libc::fcntl(self.fd, libc::F_SETLK, &flock);
                     libc::close(self.fd);
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 671dea6ae71..dbeb75b60c2 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -221,7 +221,7 @@ pub fn const_eval_validated_provider<'tcx>(
     // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
     // Catch such calls and evaluate them instead of trying to load a constant's MIR.
     if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
-        let ty = key.value.instance.ty(tcx);
+        let ty = key.value.instance.ty_env(tcx, key.param_env);
         let substs = match ty.kind {
             ty::FnDef(_, substs) => substs,
             _ => bug!("intrinsic with type {:?}", ty),
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 032062d6360..a28bb539fd0 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -204,7 +204,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // ABI check
         {
             let callee_abi = {
-                let instance_ty = instance.ty(*self.tcx);
+                let instance_ty = instance.ty_env(*self.tcx, self.param_env);
                 match instance_ty.kind {
                     ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(),
                     ty::Closure(..) => Abi::RustCall,
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index d6fd48cc89f..efbbca53485 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -140,7 +140,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // to determine the type.
         let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?;
         trace!("Found drop fn: {:?}", drop_instance);
-        let fn_sig = drop_instance.ty(*self.tcx).fn_sig(*self.tcx);
+        let fn_sig = drop_instance.ty_env(*self.tcx, self.param_env).fn_sig(*self.tcx);
         let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig);
         // The drop function takes `*mut T` where `T` is the type being dropped, so get that.
         let args = fn_sig.inputs();
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 519511f20f9..0943be9d95c 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -358,7 +358,7 @@ fn collect_items_rec<'tcx>(
             // Sanity check whether this ended up being collected accidentally
             debug_assert!(should_monomorphize_locally(tcx, &instance));
 
-            let ty = instance.ty(tcx);
+            let ty = instance.monomorphic_ty(tcx);
             visit_drop_use(tcx, ty, true, &mut neighbors);
 
             recursion_depth_reset = None;
@@ -1002,7 +1002,8 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
                             def_id_to_string(self.tcx, def_id)
                         );
 
-                        let ty = Instance::new(def_id, InternalSubsts::empty()).ty(self.tcx);
+                        let ty =
+                            Instance::new(def_id, InternalSubsts::empty()).monomorphic_ty(self.tcx);
                         visit_drop_use(self.tcx, ty, true, self.output);
                     }
                 }
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index 0817cb00605..91b787b7c99 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -134,7 +134,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
                 ctxt.start_fn = Some((item.hir_id, item.span));
             } else {
                 struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
-                    .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
+                    .span_label(ctxt.start_fn.unwrap().1, "previous `#[start]` function here")
                     .span_label(item.span, "multiple `start` functions")
                     .emit();
             }
diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs
index 77f5ff09244..47e80e8db19 100644
--- a/src/librustc_target/spec/wasm32_base.rs
+++ b/src/librustc_target/spec/wasm32_base.rs
@@ -81,7 +81,7 @@ pub fn options() -> TargetOptions {
         dynamic_linking: true,
         only_cdylib: true,
 
-        // This means we'll just embed a `start` function in the wasm module
+        // This means we'll just embed a `#[start]` function in the wasm module
         executables: true,
 
         // relatively self-explanatory!
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 58e0bec1842..bd84547d45f 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -299,7 +299,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // LL ||         10u32
             //    ||         ^^^^^ expected `i32`, found `u32`
             // LL ||     };
-            //    ||_____- if and else have incompatible types
+            //    ||_____- `if` and `else` have incompatible types
             // ```
             Some(span)
         } else {
@@ -341,7 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // by not pointing at the entire expression:
                 // ```
                 // 2 |       let x = if true {
-                //   |               ------- if and else have incompatible types
+                //   |               ------- `if` and `else` have incompatible types
                 // 3 |           3
                 //   |           - expected because of this
                 // 4 |       } else {
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index d099a739ac4..b22d7c68cf9 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -98,7 +98,10 @@ fn enforce_impl_params_are_constrained(
         // (#36836)
         tcx.sess.delay_span_bug(
             tcx.def_span(impl_def_id),
-            "potentially unconstrained type parameters weren't evaluated",
+            &format!(
+                "potentially unconstrained type parameters weren't evaluated: {:?}",
+                impl_self_ty,
+            ),
         );
         return;
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 7958c5ca2b6..025257b801f 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2153,7 +2153,7 @@ fn stability_tags(item: &clean::Item) -> String {
     }
 
     if let Some(stab) = item.stability.as_ref().filter(|s| s.level == stability::Unstable) {
-        if stab.feature.as_ref().map(|s| &**s) == Some("rustc_private") {
+        if stab.feature.as_deref() == Some("rustc_private") {
             tags += &tag_html("internal", "Internal");
         } else {
             tags += &tag_html("unstable", "Experimental");
@@ -2206,7 +2206,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
     }
 
     if let Some(stab) = item.stability.as_ref().filter(|stab| stab.level == stability::Unstable) {
-        let is_rustc_private = stab.feature.as_ref().map(|s| &**s) == Some("rustc_private");
+        let is_rustc_private = stab.feature.as_deref() == Some("rustc_private");
 
         let mut message = if is_rustc_private {
             "<span class='emoji'>⚙️</span> This is an internal compiler API."
@@ -2215,7 +2215,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
         }
         .to_owned();
 
-        if let Some(feature) = stab.feature.as_ref() {
+        if let Some(feature) = stab.feature.as_deref() {
             let mut feature = format!("<code>{}</code>", Escape(&feature));
             if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
                 feature.push_str(&format!(
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index b568d034d89..a4ca9010f2e 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,6 +1,7 @@
-use errors::Applicability;
+use errors::{emitter::Emitter, Applicability, Diagnostic, Handler};
+use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_parse::lexer::StringReader as Lexer;
-use rustc_span::source_map::FilePathMapping;
+use rustc_span::source_map::{FilePathMapping, SourceMap};
 use rustc_span::{FileName, InnerSpan};
 use syntax::sess::ParseSess;
 use syntax::token;
@@ -27,7 +28,13 @@ struct SyntaxChecker<'a, 'tcx> {
 
 impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
     fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
-        let sess = ParseSess::new(FilePathMapping::empty());
+        let buffered_messages = Lrc::new(Lock::new(vec![]));
+
+        let emitter = BufferEmitter { messages: Lrc::clone(&buffered_messages) };
+
+        let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+        let handler = Handler::with_emitter(false, None, Box::new(emitter));
+        let sess = ParseSess::with_span_handler(handler, cm);
         let source_file = sess.source_map().new_source_file(
             FileName::Custom(String::from("doctest")),
             dox[code_block.code].to_owned(),
@@ -93,6 +100,11 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                 diag
             };
 
+            // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
+            for message in buffered_messages.borrow().iter() {
+                diag.note(&message);
+            }
+
             diag.emit();
         }
     }
@@ -110,6 +122,20 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
     }
 }
 
+struct BufferEmitter {
+    messages: Lrc<Lock<Vec<String>>>,
+}
+
+impl Emitter for BufferEmitter {
+    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+        self.messages.borrow_mut().push(format!("error from rustc: {}", diag.message[0].0));
+    }
+
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
+}
+
 enum CodeBlockInvalid {
     SyntaxError,
     Empty,
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 010c27bbbc1..d94e940a7f7 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -203,17 +203,7 @@ fn run_test(
     opts: &TestOptions,
     edition: Edition,
 ) -> Result<(), TestFailure> {
-    let (test, line_offset) = match panic::catch_unwind(|| {
-        make_test(test, Some(cratename), as_test_harness, opts, edition)
-    }) {
-        Ok((test, line_offset)) => (test, line_offset),
-        Err(cause) if cause.is::<errors::FatalErrorMarker>() => {
-            // If the parser used by `make_test` panicked due to a fatal error, pass the test code
-            // through unchanged. The error will be reported during compilation.
-            (test.to_owned(), 0)
-        }
-        Err(cause) => panic::resume_unwind(cause),
-    };
+    let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts, edition);
 
     // FIXME(#44940): if doctests ever support path remapping, then this filename
     // needs to be the result of `SourceMap::span_to_unmapped_path`.
@@ -363,11 +353,6 @@ fn run_test(
 
 /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of
 /// lines before the test code begins.
-///
-/// # Panics
-///
-/// This function uses the compiler's parser internally. The parser will panic if it encounters a
-/// fatal error while parsing the test.
 pub fn make_test(
     s: &str,
     cratename: Option<&str>,
@@ -402,83 +387,94 @@ pub fn make_test(
 
     // Uses libsyntax to parse the doctest and find if there's a main fn and the extern
     // crate already is included.
-    let (already_has_main, already_has_extern_crate, found_macro) = with_globals(edition, || {
-        use errors::emitter::EmitterWriter;
-        use errors::Handler;
-        use rustc_parse::maybe_new_parser_from_source_str;
-        use rustc_span::source_map::FilePathMapping;
-        use syntax::sess::ParseSess;
-
-        let filename = FileName::anon_source_code(s);
-        let source = crates + &everything_else;
-
-        // Any errors in parsing should also appear when the doctest is compiled for real, so just
-        // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
-        let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
-        // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
-        let handler = Handler::with_emitter(false, None, box emitter);
-        let sess = ParseSess::with_span_handler(handler, cm);
-
-        let mut found_main = false;
-        let mut found_extern_crate = cratename.is_none();
-        let mut found_macro = false;
-
-        let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
-            Ok(p) => p,
-            Err(errs) => {
-                for mut err in errs {
-                    err.cancel();
+    let result = rustc_driver::catch_fatal_errors(|| {
+        with_globals(edition, || {
+            use errors::emitter::EmitterWriter;
+            use errors::Handler;
+            use rustc_parse::maybe_new_parser_from_source_str;
+            use rustc_span::source_map::FilePathMapping;
+            use syntax::sess::ParseSess;
+
+            let filename = FileName::anon_source_code(s);
+            let source = crates + &everything_else;
+
+            // Any errors in parsing should also appear when the doctest is compiled for real, so just
+            // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
+            let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+            let emitter =
+                EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
+            // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
+            let handler = Handler::with_emitter(false, None, box emitter);
+            let sess = ParseSess::with_span_handler(handler, cm);
+
+            let mut found_main = false;
+            let mut found_extern_crate = cratename.is_none();
+            let mut found_macro = false;
+
+            let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
+                Ok(p) => p,
+                Err(errs) => {
+                    for mut err in errs {
+                        err.cancel();
+                    }
+
+                    return (found_main, found_extern_crate, found_macro);
                 }
+            };
+
+            loop {
+                match parser.parse_item() {
+                    Ok(Some(item)) => {
+                        if !found_main {
+                            if let ast::ItemKind::Fn(..) = item.kind {
+                                if item.ident.name == sym::main {
+                                    found_main = true;
+                                }
+                            }
+                        }
 
-                return (found_main, found_extern_crate, found_macro);
-            }
-        };
+                        if !found_extern_crate {
+                            if let ast::ItemKind::ExternCrate(original) = item.kind {
+                                // This code will never be reached if `cratename` is none because
+                                // `found_extern_crate` is initialized to `true` if it is none.
+                                let cratename = cratename.unwrap();
 
-        loop {
-            match parser.parse_item() {
-                Ok(Some(item)) => {
-                    if !found_main {
-                        if let ast::ItemKind::Fn(..) = item.kind {
-                            if item.ident.name == sym::main {
-                                found_main = true;
+                                match original {
+                                    Some(name) => found_extern_crate = name.as_str() == cratename,
+                                    None => found_extern_crate = item.ident.as_str() == cratename,
+                                }
                             }
                         }
-                    }
-
-                    if !found_extern_crate {
-                        if let ast::ItemKind::ExternCrate(original) = item.kind {
-                            // This code will never be reached if `cratename` is none because
-                            // `found_extern_crate` is initialized to `true` if it is none.
-                            let cratename = cratename.unwrap();
 
-                            match original {
-                                Some(name) => found_extern_crate = name.as_str() == cratename,
-                                None => found_extern_crate = item.ident.as_str() == cratename,
+                        if !found_macro {
+                            if let ast::ItemKind::Mac(..) = item.kind {
+                                found_macro = true;
                             }
                         }
-                    }
 
-                    if !found_macro {
-                        if let ast::ItemKind::Mac(..) = item.kind {
-                            found_macro = true;
+                        if found_main && found_extern_crate {
+                            break;
                         }
                     }
-
-                    if found_main && found_extern_crate {
+                    Ok(None) => break,
+                    Err(mut e) => {
+                        e.cancel();
                         break;
                     }
                 }
-                Ok(None) => break,
-                Err(mut e) => {
-                    e.cancel();
-                    break;
-                }
             }
-        }
 
-        (found_main, found_extern_crate, found_macro)
+            (found_main, found_extern_crate, found_macro)
+        })
     });
+    let (already_has_main, already_has_extern_crate, found_macro) = match result {
+        Ok(result) => result,
+        Err(ErrorReported) => {
+            // If the parser panicked due to a fatal error, pass the test code through unchanged.
+            // The error will be reported during compilation.
+            return (s.to_owned(), 0);
+        }
+    };
 
     // If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
     // see it. In that case, run the old text-based scan to see if they at least have a main
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 54e0caeddaa..267d7013b1e 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -376,7 +376,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sqrt(self) -> f32 {
-        if self < 0.0 { NAN } else { unsafe { intrinsics::sqrtf32(self) } }
+        unsafe { intrinsics::sqrtf32(self) }
     }
 
     /// Returns `e^(self)`, (the exponential function).
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index aa32e5fb998..61ce7b29e26 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -342,7 +342,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sqrt(self) -> f64 {
-        if self < 0.0 { NAN } else { unsafe { intrinsics::sqrtf64(self) } }
+        unsafe { intrinsics::sqrtf64(self) }
     }
 
     /// Returns `e^(self)`, (the exponential function).
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 50712058874..0e94a722777 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -387,8 +387,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                         &self,
                         start,
                         i.span,
-                        "a `#[start]` function is an experimental \
-                                       feature whose signature may change \
+                        "`#[start]` functions are experimental \
+                                       and their signature may change \
                                        over time"
                     );
                 }
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index fe5442163ea..32cc20755ec 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -1,21 +1,3 @@
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
-  | ^
-
-error: unknown start of token: \
- --> <doctest>:1:43
-  |
-1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
-  |                                           ^
-
-error: unknown start of token: \
- --> <doctest>:1:60
-  |
-1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
-  |                                                            ^
-
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:3:5
    |
@@ -25,33 +7,14 @@ LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->si
 LL | | /// ```
    | |_______^
    |
+   = note: error from rustc: unknown start of token: \
+   = note: error from rustc: unknown start of token: \
+   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
-error: unknown start of token: `
- --> <doctest>:3:30
-  |
-3 |    |     ^^^^^^ did you mean `baz::foobar`?
-  |                              ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-3 |    |     ^^^^^^ did you mean 'baz::foobar`?
-  |                              ^
-
-error: unknown start of token: `
- --> <doctest>:3:42
-  |
-3 |    |     ^^^^^^ did you mean `baz::foobar`?
-  |                                          ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-3 |    |     ^^^^^^ did you mean `baz::foobar'?
-  |                                          ^
-
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:9:5
    |
@@ -63,17 +26,13 @@ LL | | ///    |     ^^^^^^ did you mean `baz::foobar`?
 LL | | /// ```
    | |_______^
    |
+   = note: error from rustc: unknown start of token: `
+   = note: error from rustc: unknown start of token: `
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \_
-  | ^
-
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:21:5
    |
@@ -83,17 +42,12 @@ LL | | /// \_
 LL | | /// ```
    | |_______^
    |
+   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \_
-  | ^
-
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:35:5
    |
@@ -102,12 +56,8 @@ LL |   /// ```rust
 LL | | /// \_
 LL | | /// ```
    | |_______^
-
-error: unknown start of token: \
- --> <doctest>:2:5
-  |
-2 |     \_
-  |     ^
+   |
+   = note: error from rustc: unknown start of token: \
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:45:9
@@ -116,51 +66,18 @@ LL |   ///     code with bad syntax
    |  _________^
 LL | | ///     \_
    | |__________^
-
-error: unknown start of token: `
- --> <doctest>:1:1
-  |
-1 | ```
-  | ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-1 | '``
-  | ^
-
-error: unknown start of token: `
- --> <doctest>:1:2
-  |
-1 | ```
-  |  ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-1 | `'`
-  |  ^
-
-error: unknown start of token: `
- --> <doctest>:1:3
-  |
-1 | ```
-  |   ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-1 | ``'
-  |   ^
+   |
+   = note: error from rustc: unknown start of token: \
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:60:9
    |
 LL | ///     ```
    |         ^^^
-
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \_
-  | ^
+   |
+   = note: error from rustc: unknown start of token: `
+   = note: error from rustc: unknown start of token: `
+   = note: error from rustc: unknown start of token: `
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:64:5
@@ -170,12 +87,8 @@ LL |   /// ```edition2018
 LL | | /// \_
 LL | | /// ```
    | |_______^
-
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \_
-  | ^
+   |
+   = note: error from rustc: unknown start of token: \
 
 warning: doc comment contains an invalid Rust code block
   --> $DIR/invalid-syntax.rs:70:1
@@ -186,6 +99,7 @@ LL | | #[doc = "```"]
    | |______________^
    |
    = help: mark blocks that do not contain Rust code as text: ```text
+   = note: error from rustc: unknown start of token: \
 
 warning: Rust code block is empty
   --> $DIR/invalid-syntax.rs:76:5
@@ -210,15 +124,11 @@ help: mark blocks that do not contain Rust code as text
 LL | /// ```text
    |     ^^^^^^^
 
-error: unknown start of token: \
- --> <doctest>:1:1
-  |
-1 | \____/
-  | ^
-
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:92:9
    |
 LL | ///     \____/
    |         ^^^^^^
+   |
+   = note: error from rustc: unknown start of token: \
 
diff --git a/src/test/rustdoc/playground-syntax-error.rs b/src/test/rustdoc/playground-syntax-error.rs
new file mode 100644
index 00000000000..8918ae874f8
--- /dev/null
+++ b/src/test/rustdoc/playground-syntax-error.rs
@@ -0,0 +1,21 @@
+#![crate_name = "foo"]
+#![doc(html_playground_url = "https://play.rust-lang.org/")]
+
+/// bar docs
+///
+/// ```edition2015
+/// use std::future::Future;
+/// use std::pin::Pin;
+/// fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
+///     Box::pin(async move {
+///         if n > 0 {
+///             foo_recursive(n - 1).await;
+///         }
+///     })
+/// }
+/// ```
+pub fn bar() {}
+
+// @has foo/fn.bar.html
+// @has - '//a[@class="test-arrow"]' "Run"
+// @has - '//*[@class="docblock"]' 'foo_recursive'
diff --git a/src/test/ui/async-await/issue-66387-if-without-else.rs b/src/test/ui/async-await/issue-66387-if-without-else.rs
index aa5a8db6121..3ab8220b4af 100644
--- a/src/test/ui/async-await/issue-66387-if-without-else.rs
+++ b/src/test/ui/async-await/issue-66387-if-without-else.rs
@@ -1,6 +1,6 @@
 // edition:2018
 async fn f() -> i32 {
-    if true { //~ ERROR if may be missing an else clause
+    if true { //~ ERROR `if` may be missing an `else` clause
         return 0;
     }
     // An `if` block without `else` causes the type table not to have a type for this expr.
diff --git a/src/test/ui/async-await/issue-66387-if-without-else.stderr b/src/test/ui/async-await/issue-66387-if-without-else.stderr
index 42e44472aca..e8e2a48983c 100644
--- a/src/test/ui/async-await/issue-66387-if-without-else.stderr
+++ b/src/test/ui/async-await/issue-66387-if-without-else.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/issue-66387-if-without-else.rs:3:5
    |
 LL | /     if true {
diff --git a/src/test/ui/bad/bad-expr-path.rs b/src/test/ui/bad/bad-expr-path.rs
index 99ba93253d1..31fc9cf2cb5 100644
--- a/src/test/ui/bad/bad-expr-path.rs
+++ b/src/test/ui/bad/bad-expr-path.rs
@@ -1,6 +1,6 @@
 mod m1 {}
 
-fn main(arguments: Vec<String>) { //~ ERROR main function has wrong type
+fn main(arguments: Vec<String>) { //~ ERROR `main` function has wrong type
     log(debug, m1::arguments);
     //~^ ERROR cannot find function `log` in this scope
     //~| ERROR cannot find value `debug` in this scope
diff --git a/src/test/ui/bad/bad-expr-path.stderr b/src/test/ui/bad/bad-expr-path.stderr
index faba9911f86..56bb6e2be88 100644
--- a/src/test/ui/bad/bad-expr-path.stderr
+++ b/src/test/ui/bad/bad-expr-path.stderr
@@ -16,7 +16,7 @@ error[E0425]: cannot find value `arguments` in module `m1`
 LL |     log(debug, m1::arguments);
    |                    ^^^^^^^^^ not found in `m1`
 
-error[E0580]: main function has wrong type
+error[E0580]: `main` function has wrong type
   --> $DIR/bad-expr-path.rs:3:1
    |
 LL | fn main(arguments: Vec<String>) {
diff --git a/src/test/ui/bad/bad-expr-path2.rs b/src/test/ui/bad/bad-expr-path2.rs
index 43bd2908042..eb88edb9071 100644
--- a/src/test/ui/bad/bad-expr-path2.rs
+++ b/src/test/ui/bad/bad-expr-path2.rs
@@ -2,7 +2,7 @@ mod m1 {
     pub mod arguments {}
 }
 
-fn main(arguments: Vec<String>) { //~ ERROR main function has wrong type
+fn main(arguments: Vec<String>) { //~ ERROR `main` function has wrong type
     log(debug, m1::arguments);
     //~^ ERROR cannot find function `log` in this scope
     //~| ERROR cannot find value `debug` in this scope
diff --git a/src/test/ui/bad/bad-expr-path2.stderr b/src/test/ui/bad/bad-expr-path2.stderr
index 53b6d35e8f3..e217c45b267 100644
--- a/src/test/ui/bad/bad-expr-path2.stderr
+++ b/src/test/ui/bad/bad-expr-path2.stderr
@@ -16,7 +16,7 @@ error[E0423]: expected value, found module `m1::arguments`
 LL |     log(debug, m1::arguments);
    |                ^^^^^^^^^^^^^ not a value
 
-error[E0580]: main function has wrong type
+error[E0580]: `main` function has wrong type
   --> $DIR/bad-expr-path2.rs:5:1
    |
 LL | fn main(arguments: Vec<String>) {
diff --git a/src/test/ui/bad/bad-main.rs b/src/test/ui/bad/bad-main.rs
index c9e2f02f071..75115996142 100644
--- a/src/test/ui/bad/bad-main.rs
+++ b/src/test/ui/bad/bad-main.rs
@@ -1 +1 @@
-fn main(x: isize) { } //~ ERROR: main function has wrong type [E0580]
+fn main(x: isize) { } //~ ERROR: `main` function has wrong type [E0580]
diff --git a/src/test/ui/bad/bad-main.stderr b/src/test/ui/bad/bad-main.stderr
index 1e57c2488e9..675b66d0578 100644
--- a/src/test/ui/bad/bad-main.stderr
+++ b/src/test/ui/bad/bad-main.stderr
@@ -1,4 +1,4 @@
-error[E0580]: main function has wrong type
+error[E0580]: `main` function has wrong type
   --> $DIR/bad-main.rs:1:1
    |
 LL | fn main(x: isize) { }
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
new file mode 100644
index 00000000000..f3be7b56db5
--- /dev/null
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+#[allow(dead_code)]
+struct ArithArrayLen<const N: usize>([u32; 0 + N]); // ok
+
+#[derive(PartialEq, Eq)]
+struct Config {
+    arr_size: usize,
+}
+
+struct B<const CFG: Config> {
+    arr: [u8; CFG.arr_size], // ok
+}
+
+const C: Config = Config { arr_size: 5 };
+
+fn main() {
+    let b = B::<C> { arr: [1, 2, 3, 4, 5] };
+    assert_eq!(b.arr.len(), 5);
+}
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr
new file mode 100644
index 00000000000..274f9769702
--- /dev/null
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/array-size-in-generic-struct-param.rs:3:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr
index 79572c41702..6771224e6cf 100644
--- a/src/test/ui/consts/control-flow/issue-50577.if_match.stderr
+++ b/src/test/ui/consts/control-flow/issue-50577.if_match.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/issue-50577.rs:7:16
    |
 LL |         Drop = assert_eq!(1, 1)
diff --git a/src/test/ui/consts/control-flow/issue-50577.rs b/src/test/ui/consts/control-flow/issue-50577.rs
index 7906ec4dc68..9600f8b6aee 100644
--- a/src/test/ui/consts/control-flow/issue-50577.rs
+++ b/src/test/ui/consts/control-flow/issue-50577.rs
@@ -5,7 +5,7 @@
 fn main() {
     enum Foo {
         Drop = assert_eq!(1, 1)
-        //[stock,if_match]~^ ERROR if may be missing an else clause
+        //[stock,if_match]~^ ERROR `if` may be missing an `else` clause
         //[stock]~^^ ERROR `match` is not allowed in a `const`
         //[stock]~| ERROR `match` is not allowed in a `const`
         //[stock]~| ERROR `if` is not allowed in a `const`
diff --git a/src/test/ui/consts/control-flow/issue-50577.stock.stderr b/src/test/ui/consts/control-flow/issue-50577.stock.stderr
index 13b50954292..7d637f5aa96 100644
--- a/src/test/ui/consts/control-flow/issue-50577.stock.stderr
+++ b/src/test/ui/consts/control-flow/issue-50577.stock.stderr
@@ -28,7 +28,7 @@ LL |         Drop = assert_eq!(1, 1)
    = help: add `#![feature(const_if_match)]` to the crate attributes to enable
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/issue-50577.rs:7:16
    |
 LL |         Drop = assert_eq!(1, 1)
diff --git a/src/test/ui/error-codes/E0138.stderr b/src/test/ui/error-codes/E0138.stderr
index 445053a4a89..2dc6976fe0e 100644
--- a/src/test/ui/error-codes/E0138.stderr
+++ b/src/test/ui/error-codes/E0138.stderr
@@ -2,7 +2,7 @@ error[E0138]: multiple `start` functions
   --> $DIR/E0138.rs:7:1
    |
 LL | fn foo(argc: isize, argv: *const *const u8) -> isize { 0 }
-   | ---------------------------------------------------------- previous `start` function here
+   | ---------------------------------------------------------- previous `#[start]` function here
 ...
 LL | fn f(argc: isize, argv: *const *const u8) -> isize { 0 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `start` functions
diff --git a/src/test/ui/extern/extern-main-fn.rs b/src/test/ui/extern/extern-main-fn.rs
index dacebfbecf5..ddf2e136f03 100644
--- a/src/test/ui/extern/extern-main-fn.rs
+++ b/src/test/ui/extern/extern-main-fn.rs
@@ -1 +1 @@
-extern fn main() {} //~ ERROR: main function has wrong type [E0580]
+extern fn main() {} //~ ERROR: `main` function has wrong type [E0580]
diff --git a/src/test/ui/extern/extern-main-fn.stderr b/src/test/ui/extern/extern-main-fn.stderr
index 6f6983d4283..9c994985a3e 100644
--- a/src/test/ui/extern/extern-main-fn.stderr
+++ b/src/test/ui/extern/extern-main-fn.stderr
@@ -1,4 +1,4 @@
-error[E0580]: main function has wrong type
+error[E0580]: `main` function has wrong type
   --> $DIR/extern-main-fn.rs:1:1
    |
 LL | extern fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-start.rs b/src/test/ui/feature-gates/feature-gate-start.rs
index 0bd4c7c85b7..e617f1c4759 100644
--- a/src/test/ui/feature-gates/feature-gate-start.rs
+++ b/src/test/ui/feature-gates/feature-gate-start.rs
@@ -1,3 +1,3 @@
 #[start]
 fn foo(_: isize, _: *const *const u8) -> isize { 0 }
-//~^ ERROR a `#[start]` function is an experimental feature
+//~^ ERROR `#[start]` functions are experimental
diff --git a/src/test/ui/feature-gates/feature-gate-start.stderr b/src/test/ui/feature-gates/feature-gate-start.stderr
index c769ef8ee92..f42e42ea039 100644
--- a/src/test/ui/feature-gates/feature-gate-start.stderr
+++ b/src/test/ui/feature-gates/feature-gate-start.stderr
@@ -1,4 +1,4 @@
-error[E0658]: a `#[start]` function is an experimental feature whose signature may change over time
+error[E0658]: `#[start]` functions are experimental and their signature may change over time
   --> $DIR/feature-gate-start.rs:2:1
    |
 LL | fn foo(_: isize, _: *const *const u8) -> isize { 0 }
diff --git a/src/test/ui/if-else-type-mismatch.rs b/src/test/ui/if-else-type-mismatch.rs
index 583c3d0b765..1a0a36df2ad 100644
--- a/src/test/ui/if-else-type-mismatch.rs
+++ b/src/test/ui/if-else-type-mismatch.rs
@@ -4,43 +4,43 @@ fn main() {
     } else {
         2u32
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true { 42i32 } else { 42u32 };
-    //~^ ERROR if and else have incompatible types
+    //~^ ERROR `if` and `else` have incompatible types
     let _ = if true {
         3u32;
     } else {
         4u32
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true {
         5u32
     } else {
         6u32;
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true {
         7i32;
     } else {
         8u32
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true {
         9i32
     } else {
         10u32;
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true {
 
     } else {
         11u32
     };
-    //~^^ ERROR if and else have incompatible types
+    //~^^ ERROR `if` and `else` have incompatible types
     let _ = if true {
         12i32
     } else {
 
     };
-    //~^^^ ERROR if and else have incompatible types
+    //~^^^ ERROR `if` and `else` have incompatible types
 }
diff --git a/src/test/ui/if-else-type-mismatch.stderr b/src/test/ui/if-else-type-mismatch.stderr
index 14e8f87393b..9fa190d6c9d 100644
--- a/src/test/ui/if-else-type-mismatch.stderr
+++ b/src/test/ui/if-else-type-mismatch.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:5:9
    |
 LL |       let _ = if true {
@@ -9,9 +9,9 @@ LL | |     } else {
 LL | |         2u32
    | |         ^^^^ expected `i32`, found `u32`
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:8:38
    |
 LL |     let _ = if true { 42i32 } else { 42u32 };
@@ -19,7 +19,7 @@ LL |     let _ = if true { 42i32 } else { 42u32 };
    |                       |
    |                       expected because of this
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:13:9
    |
 LL |       let _ = if true {
@@ -33,9 +33,9 @@ LL | |     } else {
 LL | |         4u32
    | |         ^^^^ expected `()`, found `u32`
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:19:9
    |
 LL |       let _ = if true {
@@ -49,9 +49,9 @@ LL | |         6u32;
    | |         |   help: consider removing this semicolon
    | |         expected `u32`, found `()`
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:25:9
    |
 LL |       let _ = if true {
@@ -62,9 +62,9 @@ LL | |     } else {
 LL | |         8u32
    | |         ^^^^ expected `()`, found `u32`
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:31:9
    |
 LL |       let _ = if true {
@@ -75,9 +75,9 @@ LL | |     } else {
 LL | |         10u32;
    | |         ^^^^^^ expected `i32`, found `()`
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:37:9
    |
 LL |       let _ = if true {
@@ -88,11 +88,11 @@ LL | |     } else {
 LL |           11u32
    |           ^^^^^ expected `()`, found `u32`
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-else-type-mismatch.rs:42:12
    |
 LL |       let _ = if true {
-   |               ------- if and else have incompatible types
+   |               ------- `if` and `else` have incompatible types
 LL |           12i32
    |           ----- expected because of this
 LL |       } else {
diff --git a/src/test/ui/if/if-branch-types.rs b/src/test/ui/if/if-branch-types.rs
index 5c693194a76..c125ba30606 100644
--- a/src/test/ui/if/if-branch-types.rs
+++ b/src/test/ui/if/if-branch-types.rs
@@ -1,5 +1,5 @@
 fn main() {
     let x = if true { 10i32 } else { 10u32 };
-    //~^ ERROR if and else have incompatible types
+    //~^ ERROR `if` and `else` have incompatible types
     //~| expected `i32`, found `u32`
 }
diff --git a/src/test/ui/if/if-branch-types.stderr b/src/test/ui/if/if-branch-types.stderr
index b5eacf5860f..14f02163a83 100644
--- a/src/test/ui/if/if-branch-types.stderr
+++ b/src/test/ui/if/if-branch-types.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-branch-types.rs:2:38
    |
 LL |     let x = if true { 10i32 } else { 10u32 };
diff --git a/src/test/ui/if/if-let-arm-types.rs b/src/test/ui/if/if-let-arm-types.rs
index cae4f0974c6..1e8260a017d 100644
--- a/src/test/ui/if/if-let-arm-types.rs
+++ b/src/test/ui/if/if-let-arm-types.rs
@@ -1,11 +1,11 @@
 fn main() {
     if let Some(b) = None {
-        //~^ NOTE if and else have incompatible types
+        //~^ NOTE `if` and `else` have incompatible types
         ()
         //~^ NOTE expected because of this
     } else {
         1
     };
-    //~^^ ERROR: if and else have incompatible types
+    //~^^ ERROR: `if` and `else` have incompatible types
     //~| NOTE expected `()`, found integer
 }
diff --git a/src/test/ui/if/if-let-arm-types.stderr b/src/test/ui/if/if-let-arm-types.stderr
index da93dfc9995..b40a0f479d3 100644
--- a/src/test/ui/if/if-let-arm-types.stderr
+++ b/src/test/ui/if/if-let-arm-types.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/if-let-arm-types.rs:7:9
    |
 LL | /     if let Some(b) = None {
@@ -10,7 +10,7 @@ LL | |     } else {
 LL | |         1
    | |         ^ expected `()`, found integer
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/if/if-without-else-as-fn-expr.rs
index 826371be35f..19fbfb27ba6 100644
--- a/src/test/ui/if/if-without-else-as-fn-expr.rs
+++ b/src/test/ui/if/if-without-else-as-fn-expr.rs
@@ -2,14 +2,14 @@ fn foo(bar: usize) -> usize {
     if bar % 5 == 0 {
         return 3;
     }
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
 }
 
 fn foo2(bar: usize) -> usize {
     let x: usize = if bar % 5 == 0 {
         return 3;
     };
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
     x
 }
 
@@ -17,21 +17,21 @@ fn foo3(bar: usize) -> usize {
     if bar % 5 == 0 {
         3
     }
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
 }
 
 fn foo_let(bar: usize) -> usize {
     if let 0 = 1 {
         return 3;
     }
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
 }
 
 fn foo2_let(bar: usize) -> usize {
     let x: usize = if let 0 = 1 {
         return 3;
     };
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
     x
 }
 
@@ -39,7 +39,7 @@ fn foo3_let(bar: usize) -> usize {
     if let 0 = 1 {
         3
     }
-    //~^^^ ERROR if may be missing an else clause
+    //~^^^ ERROR `if` may be missing an `else` clause
 }
 
 // FIXME(60254): deduplicate first error in favor of second.
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/if/if-without-else-as-fn-expr.stderr
index 9c7e7002360..4daf27493c1 100644
--- a/src/test/ui/if/if-without-else-as-fn-expr.stderr
+++ b/src/test/ui/if/if-without-else-as-fn-expr.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:2:5
    |
 LL |   fn foo(bar: usize) -> usize {
@@ -11,7 +11,7 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:9:20
    |
 LL |       let x: usize = if bar % 5 == 0 {
@@ -25,7 +25,7 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:17:5
    |
 LL |   fn foo3(bar: usize) -> usize {
@@ -38,7 +38,7 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:24:5
    |
 LL |   fn foo_let(bar: usize) -> usize {
@@ -51,7 +51,7 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:31:20
    |
 LL |       let x: usize = if let 0 = 1 {
@@ -65,7 +65,7 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-as-fn-expr.rs:39:5
    |
 LL |   fn foo3_let(bar: usize) -> usize {
diff --git a/src/test/ui/if/if-without-else-result.rs b/src/test/ui/if/if-without-else-result.rs
index e5fb7b26321..cf84a99e53f 100644
--- a/src/test/ui/if/if-without-else-result.rs
+++ b/src/test/ui/if/if-without-else-result.rs
@@ -1,6 +1,6 @@
 fn main() {
     let a = if true { true };
-    //~^ ERROR if may be missing an else clause [E0317]
+    //~^ ERROR `if` may be missing an `else` clause [E0317]
     //~| expected `()`, found `bool`
     println!("{}", a);
 }
diff --git a/src/test/ui/if/if-without-else-result.stderr b/src/test/ui/if/if-without-else-result.stderr
index 66a8185774e..821635d3768 100644
--- a/src/test/ui/if/if-without-else-result.stderr
+++ b/src/test/ui/if/if-without-else-result.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/if-without-else-result.rs:2:13
    |
 LL |     let a = if true { true };
diff --git a/src/test/ui/issues/issue-11319.rs b/src/test/ui/issues/issue-11319.rs
index 8c2bafe63bd..ab69ab250ff 100644
--- a/src/test/ui/issues/issue-11319.rs
+++ b/src/test/ui/issues/issue-11319.rs
@@ -6,7 +6,7 @@ fn main() {
         Some(2) => true,
         //~^ NOTE this is found to be of type `bool`
         None    => (),
-        //~^ ERROR match arms have incompatible types
+        //~^ ERROR `match` arms have incompatible types
         //~| NOTE expected `bool`, found `()`
         _       => true
     }
diff --git a/src/test/ui/issues/issue-11319.stderr b/src/test/ui/issues/issue-11319.stderr
index 7663a32883c..fc44205e81e 100644
--- a/src/test/ui/issues/issue-11319.stderr
+++ b/src/test/ui/issues/issue-11319.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-11319.rs:8:20
    |
 LL | /     match Some(10) {
diff --git a/src/test/ui/issues/issue-17728.nll.stderr b/src/test/ui/issues/issue-17728.nll.stderr
index ef193ad85bf..d515cf451c4 100644
--- a/src/test/ui/issues/issue-17728.nll.stderr
+++ b/src/test/ui/issues/issue-17728.nll.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-17728.rs:109:14
    |
 LL | /     match to_parse {
diff --git a/src/test/ui/issues/issue-17728.rs b/src/test/ui/issues/issue-17728.rs
index 15cea1d609d..bec52d87d29 100644
--- a/src/test/ui/issues/issue-17728.rs
+++ b/src/test/ui/issues/issue-17728.rs
@@ -108,7 +108,7 @@ fn str_to_direction(to_parse: &str) -> RoomDirection {
         "down" => RoomDirection::Down,
         _ => None
     }
-        //~^^ ERROR match arms have incompatible types
+        //~^^ ERROR `match` arms have incompatible types
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-17728.stderr b/src/test/ui/issues/issue-17728.stderr
index 527168dbe6c..2f9ae63aa41 100644
--- a/src/test/ui/issues/issue-17728.stderr
+++ b/src/test/ui/issues/issue-17728.stderr
@@ -9,7 +9,7 @@ LL |     fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&R
 LL |             Some(entry) => Ok(entry),
    |                            ^^^^^^^^^ ...but data from `room` is returned here
 
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-17728.rs:109:14
    |
 LL | /     match to_parse {
diff --git a/src/test/ui/issues/issue-19991.rs b/src/test/ui/issues/issue-19991.rs
index 62d5a6de760..0f3f83001d3 100644
--- a/src/test/ui/issues/issue-19991.rs
+++ b/src/test/ui/issues/issue-19991.rs
@@ -1,8 +1,8 @@
 // Test if the sugared if-let construct correctly prints "missing an else clause" when an else
-// clause does not exist, instead of the unsympathetic "match arms have incompatible types"
+// clause does not exist, instead of the unsympathetic "`match` arms have incompatible types"
 
 fn main() {
-    if let Some(homura) = Some("madoka") { //~  ERROR missing an else clause
+    if let Some(homura) = Some("madoka") { //~  ERROR missing an `else` clause
                                            //~| expected `()`, found integer
         765
     };
diff --git a/src/test/ui/issues/issue-19991.stderr b/src/test/ui/issues/issue-19991.stderr
index b78f4a6d293..6e92be87a02 100644
--- a/src/test/ui/issues/issue-19991.stderr
+++ b/src/test/ui/issues/issue-19991.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/issue-19991.rs:5:5
    |
 LL | /     if let Some(homura) = Some("madoka") {
diff --git a/src/test/ui/issues/issue-24036.rs b/src/test/ui/issues/issue-24036.rs
index 2f501b941b5..bd82f95c9ef 100644
--- a/src/test/ui/issues/issue-24036.rs
+++ b/src/test/ui/issues/issue-24036.rs
@@ -10,7 +10,7 @@ fn closure_from_match() {
         2 => |c| c - 1,
         _ => |c| c - 1
     };
-    //~^^^ ERROR match arms have incompatible types
+    //~^^^ ERROR `match` arms have incompatible types
 }
 
 fn main() { }
diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr
index 04817f2596a..b0e729a59eb 100644
--- a/src/test/ui/issues/issue-24036.stderr
+++ b/src/test/ui/issues/issue-24036.stderr
@@ -9,7 +9,7 @@ LL |     x = |c| c + 1;
    = note: no two closures, even if identical, have the same type
    = help: consider boxing your closure and/or using it as a trait object
 
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-24036.rs:10:14
    |
 LL |       let x = match 1usize {
diff --git a/src/test/ui/issues/issue-4201.rs b/src/test/ui/issues/issue-4201.rs
index 2d655e4b7e7..1f292229fd6 100644
--- a/src/test/ui/issues/issue-4201.rs
+++ b/src/test/ui/issues/issue-4201.rs
@@ -2,7 +2,7 @@ fn main() {
     let a = if true {
         0
     } else if false {
-//~^ ERROR if may be missing an else clause
+//~^ ERROR `if` may be missing an `else` clause
 //~| expected `()`, found integer
         1
     };
diff --git a/src/test/ui/issues/issue-4201.stderr b/src/test/ui/issues/issue-4201.stderr
index aacc426783d..bc638ddf55b 100644
--- a/src/test/ui/issues/issue-4201.stderr
+++ b/src/test/ui/issues/issue-4201.stderr
@@ -1,4 +1,4 @@
-error[E0317]: if may be missing an else clause
+error[E0317]: `if` may be missing an `else` clause
   --> $DIR/issue-4201.rs:4:12
    |
 LL |       } else if false {
diff --git a/src/test/ui/issues/issue-8460.rs b/src/test/ui/issues/issue-8460.rs
index b7fc564a9b5..3fd576a8d35 100644
--- a/src/test/ui/issues/issue-8460.rs
+++ b/src/test/ui/issues/issue-8460.rs
@@ -11,8 +11,8 @@ trait Int {
 }
 macro_rules! doit {
     ($($t:ident)*) => ($(impl Int for $t {
-        fn zero() -> $t { 0 }
-        fn one() -> $t { 1 }
+        fn zero() -> Self { 0 }
+        fn one() -> Self { 1 }
     })*)
 }
 doit! { i8 i16 i32 i64 isize }
diff --git a/src/test/ui/issues/issue-9575.rs b/src/test/ui/issues/issue-9575.rs
index bac4ac1d208..06b252990b6 100644
--- a/src/test/ui/issues/issue-9575.rs
+++ b/src/test/ui/issues/issue-9575.rs
@@ -2,6 +2,6 @@
 
 #[start]
 fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize {
-    //~^ start function has wrong type
+    //~^ `#[start]` function has wrong type
    0
 }
diff --git a/src/test/ui/issues/issue-9575.stderr b/src/test/ui/issues/issue-9575.stderr
index 3e3678a23f7..5b8ce84a071 100644
--- a/src/test/ui/issues/issue-9575.stderr
+++ b/src/test/ui/issues/issue-9575.stderr
@@ -1,4 +1,4 @@
-error[E0308]: start function has wrong type
+error[E0308]: `#[start]` function has wrong type
   --> $DIR/issue-9575.rs:4:1
    |
 LL | fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize {
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs
index 6bf1fd41d77..bc7b787cd65 100644
--- a/src/test/ui/lub-glb/old-lub-glb-hr.rs
+++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs
@@ -13,7 +13,7 @@ fn foo(
 ) {
     let z = match 22 {
         0 => x,
-        _ => y, //~ ERROR match arms have incompatible types
+        _ => y, //~ ERROR `match` arms have incompatible types
     };
 }
 
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr
index 1dce9df96df..6d5d5117469 100644
--- a/src/test/ui/lub-glb/old-lub-glb-hr.stderr
+++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/old-lub-glb-hr.rs:16:14
    |
 LL |       let z = match 22 {
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs
index f303c07e6d7..63bbae59991 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.rs
+++ b/src/test/ui/lub-glb/old-lub-glb-object.rs
@@ -9,7 +9,7 @@ fn foo(
 ) {
     let z = match 22 {
         0 => x,
-        _ => y, //~ ERROR match arms have incompatible types
+        _ => y, //~ ERROR `match` arms have incompatible types
     };
 }
 
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr
index 18de7a40ee1..65c797f6b19 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.stderr
+++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/old-lub-glb-object.rs:12:14
    |
 LL |       let z = match 22 {
diff --git a/src/test/ui/main-wrong-type.rs b/src/test/ui/main-wrong-type.rs
index dac4d4ac9aa..31deba72af4 100644
--- a/src/test/ui/main-wrong-type.rs
+++ b/src/test/ui/main-wrong-type.rs
@@ -4,5 +4,5 @@ struct S {
 }
 
 fn main(foo: S) {
-//~^ ERROR: main function has wrong type [E0580]
+//~^ ERROR: `main` function has wrong type [E0580]
 }
diff --git a/src/test/ui/main-wrong-type.stderr b/src/test/ui/main-wrong-type.stderr
index e75d4d7acfd..43efaf884e3 100644
--- a/src/test/ui/main-wrong-type.stderr
+++ b/src/test/ui/main-wrong-type.stderr
@@ -1,4 +1,4 @@
-error[E0580]: main function has wrong type
+error[E0580]: `main` function has wrong type
   --> $DIR/main-wrong-type.rs:6:1
    |
 LL | fn main(foo: S) {
diff --git a/src/test/ui/match/match-arm-resolving-to-never.rs b/src/test/ui/match/match-arm-resolving-to-never.rs
index 8f54023305e..6ef249c0524 100644
--- a/src/test/ui/match/match-arm-resolving-to-never.rs
+++ b/src/test/ui/match/match-arm-resolving-to-never.rs
@@ -14,6 +14,6 @@ fn main() {
         E::C => 3,
         E::D => 4,
         E::E => unimplemented!(""),
-        E::F => "", //~ ERROR match arms have incompatible types
+        E::F => "", //~ ERROR `match` arms have incompatible types
     };
 }
diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr
index 4482d5c6a79..3a723de9f6b 100644
--- a/src/test/ui/match/match-arm-resolving-to-never.stderr
+++ b/src/test/ui/match/match-arm-resolving-to-never.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/match-arm-resolving-to-never.rs:17:17
    |
 LL | /     match E::F {
diff --git a/src/test/ui/match/match-type-err-first-arm.rs b/src/test/ui/match/match-type-err-first-arm.rs
index d73c7e8402f..e9027eb2489 100644
--- a/src/test/ui/match/match-type-err-first-arm.rs
+++ b/src/test/ui/match/match-type-err-first-arm.rs
@@ -16,7 +16,7 @@ fn test_func2(n: i32) -> i32 {
     let x = match n { //~ NOTE `match` arms have incompatible types
         12 => 'b', //~ NOTE this is found to be of type `char`
         _ => 42,
-        //~^ ERROR match arms have incompatible types
+        //~^ ERROR `match` arms have incompatible types
         //~| NOTE expected `char`, found integer
     };
     x
@@ -32,7 +32,7 @@ fn test_func3(n: i32) -> i32 {
         6 => 'b',
         //~^ NOTE this and all prior arms are found to be of type `char`
         _ => 42,
-        //~^ ERROR match arms have incompatible types
+        //~^ ERROR `match` arms have incompatible types
         //~| NOTE expected `char`, found integer
     };
     x
@@ -44,7 +44,7 @@ fn test_func4() {
             x //~ NOTE this is found to be of type `u32`
         },
         None => {}
-        //~^ ERROR match arms have incompatible types
+        //~^ ERROR `match` arms have incompatible types
         //~| NOTE expected `u32`, found `()`
     };
 }
diff --git a/src/test/ui/match/match-type-err-first-arm.stderr b/src/test/ui/match/match-type-err-first-arm.stderr
index 1b3d8c61c86..fd489afa84d 100644
--- a/src/test/ui/match/match-type-err-first-arm.stderr
+++ b/src/test/ui/match/match-type-err-first-arm.stderr
@@ -7,7 +7,7 @@ LL |     match n {
 LL |         12 => 'b',
    |               ^^^ expected `i32`, found `char`
 
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/match-type-err-first-arm.rs:18:14
    |
 LL |       let x = match n {
@@ -21,7 +21,7 @@ LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
 
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/match-type-err-first-arm.rs:34:14
    |
 LL |       let x = match n {
@@ -40,7 +40,7 @@ LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
 
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/match-type-err-first-arm.rs:46:17
    |
 LL | /     match Some(0u32) {
diff --git a/src/test/ui/mir/issue-67639-normalization-ice.rs b/src/test/ui/mir/issue-67639-normalization-ice.rs
new file mode 100644
index 00000000000..21851a72525
--- /dev/null
+++ b/src/test/ui/mir/issue-67639-normalization-ice.rs
@@ -0,0 +1,34 @@
+// compile-flags: -Z mir-opt-level=3
+// build-pass
+
+// This used to ICE in const-prop due
+// to an empty ParamEnv being used during normalization
+// of a generic type
+
+
+fn main() {
+    join_all::<u32>();
+}
+
+trait Foo {
+    type Item;
+}
+
+impl Foo for u32 {
+    type Item = u8;
+}
+
+trait Bar {
+    type Item2;
+}
+
+impl Bar for u8 {
+    type Item2 = u64;
+}
+
+fn join_all<I>()
+where I: Foo,
+    I::Item: Bar
+{
+    Vec::<<I::Item as Bar>::Item2>::new(); // ICE occurs processing this line
+}
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
index 58109be447e..a80e5df1a26 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
@@ -29,7 +29,7 @@ fn qux() -> impl std::fmt::Display {
         0i32
     } else {
         1u32
-        //~^ ERROR if and else have incompatible types
+        //~^ ERROR `if` and `else` have incompatible types
     }
 }
 
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
index d5ea2ba39a9..27b86007451 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -34,7 +34,7 @@ LL |     } else {
 LL |         1u32
    |         ^^^^ expected `i32`, found `u32`
 
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9
    |
 LL | /     if false {
@@ -45,7 +45,7 @@ LL | |         1u32
    | |         ^^^^ expected `i32`, found `u32`
 LL | |
 LL | |     }
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:39:14
diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.stderr
index 381bad4210f..750cc3566e0 100644
--- a/src/test/ui/regions/region-invariant-static-error-reporting.stderr
+++ b/src/test/ui/regions/region-invariant-static-error-reporting.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/region-invariant-static-error-reporting.rs:17:9
    |
 LL |       let bad = if x.is_some() {
@@ -9,7 +9,7 @@ LL | |     } else {
 LL | |         mk_static()
    | |         ^^^^^^^^^^^ lifetime mismatch
 LL | |     };
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
    |
    = note: expected struct `Invariant<'a>`
               found struct `Invariant<'static>`
diff --git a/src/test/ui/str/str-array-assignment.rs b/src/test/ui/str/str-array-assignment.rs
index 4a78ed53ae1..323eefb381a 100644
--- a/src/test/ui/str/str-array-assignment.rs
+++ b/src/test/ui/str/str-array-assignment.rs
@@ -1,7 +1,7 @@
 fn main() {
   let s = "abc";
   let t = if true { s[..2] } else { s };
-  //~^ ERROR if and else have incompatible types
+  //~^ ERROR `if` and `else` have incompatible types
   let u: &str = if true { s[..2] } else { s };
   //~^ ERROR mismatched types
   let v = s[..2];
diff --git a/src/test/ui/str/str-array-assignment.stderr b/src/test/ui/str/str-array-assignment.stderr
index a133c69eeef..cc767de3845 100644
--- a/src/test/ui/str/str-array-assignment.stderr
+++ b/src/test/ui/str/str-array-assignment.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/str-array-assignment.rs:3:37
    |
 LL |   let t = if true { s[..2] } else { s };
diff --git a/src/test/ui/suggestions/opaque-type-error.rs b/src/test/ui/suggestions/opaque-type-error.rs
index 979bb60d48c..5e114740314 100644
--- a/src/test/ui/suggestions/opaque-type-error.rs
+++ b/src/test/ui/suggestions/opaque-type-error.rs
@@ -17,7 +17,7 @@ async fn thing() -> Result<(), ()> {
     if true {
         thing_one()
     } else {
-        thing_two() //~ ERROR if and else have incompatible types
+        thing_two() //~ ERROR `if` and `else` have incompatible types
     }.await
 }
 
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
index e7bf84a4113..1465b9e49ef 100644
--- a/src/test/ui/suggestions/opaque-type-error.stderr
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -1,4 +1,4 @@
-error[E0308]: if and else have incompatible types
+error[E0308]: `if` and `else` have incompatible types
   --> $DIR/opaque-type-error.rs:20:9
    |
 LL | /     if true {
@@ -8,7 +8,7 @@ LL | |     } else {
 LL | |         thing_two()
    | |         ^^^^^^^^^^^ expected opaque type, found a different opaque type
 LL | |     }.await
-   | |_____- if and else have incompatible types
+   | |_____- `if` and `else` have incompatible types
    |
    = note:     expected type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
            found opaque type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs
index e23c0d0a40a..c39ab954473 100644
--- a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs
+++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs
@@ -20,7 +20,7 @@ fn main() {
         // However, in #67273, we would delay the unification of this arm with the above
         // because we used the hitherto accumulated coercion as opposed to the "initial" type.
         2 => i = 1,
-        //~^ ERROR match arms have incompatible types
+        //~^ ERROR `match` arms have incompatible types
 
         _ => (),
     }
diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr
index 3547285542a..a431fe89c23 100644
--- a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr
+++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs:22:14
    |
 LL | /     match i {
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
index d5799ccc834..594fad41385 100644
--- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -1,4 +1,4 @@
-error[E0308]: match arms have incompatible types
+error[E0308]: `match` arms have incompatible types
   --> $DIR/wf-unsafe-trait-obj-match.rs:23:17
    |
 LL | /     match opt() {
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject d9e38f57c125c5ac50397ec8a006fe49f17cd96
+Subproject 732825dcff6d1f115225305ce5e0c9c9d876a0f
diff --git a/src/tools/rls b/src/tools/rls
-Subproject fed7a31cd93bbd3c8a9f38871838b59b5dce2a3
+Subproject 7c0489c5ff4f5c594e65a3b22efd9ce373deab9