diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 9be73cf3c6d16..e684ccfeeb7ed 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1636,6 +1636,9 @@ impl<'tcx> ObligationCause<'tcx> {
                 TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => {
                     Error0644("closure/generator type that references itself")
                 }
+                TypeError::IntrinsicCast => {
+                    Error0308("cannot coerce intrinsics to function pointers")
+                }
                 _ => Error0308("mismatched types"),
             },
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index e240e0df8b948..17c9e520bcea2 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2402,6 +2402,12 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_generic_adt(def_id, ty)
     }
 
+    #[inline]
+    pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem)  -> Ty<'tcx> {
+        let def_id = self.require_lang_item(item, None);
+        self.mk_generic_adt(def_id, ty)
+    }
+
     #[inline]
     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index c70006b68d69a..fe8f94ab1d314 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -46,6 +46,8 @@ pub enum TypeError<'tcx> {
     ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
 
     ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
+
+    IntrinsicCast,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
@@ -179,6 +181,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             ConstMismatch(ref values) => {
                 write!(f, "expected `{}`, found `{}`", values.expected, values.found)
             }
+            IntrinsicCast => {
+                write!(f, "cannot coerce intrinsics to function pointers")
+            }
         }
     }
 }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 649a5244728ba..ec7cf1a13c596 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -748,6 +748,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             Sorts(ref x) => return tcx.lift(x).map(Sorts),
             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
             ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
+            IntrinsicCast => IntrinsicCast,
         })
     }
 }
@@ -1338,6 +1339,7 @@ EnumTypeFoldableImpl! {
         (ty::error::TypeError::Sorts)(x),
         (ty::error::TypeError::ExistentialMismatch)(x),
         (ty::error::TypeError::ConstMismatch)(x),
+        (ty::error::TypeError::IntrinsicCast),
     }
 }
 
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 255af3122e70c..3bed5d81dc514 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -30,10 +30,8 @@ pub struct AnnotateSnippetEmitterWriter {
 impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
-        let primary_span = db.span.clone();
         let children = db.children.clone();
-        // FIXME(#59346): Collect suggestions (see emitter.rs)
-        let suggestions: &[_] = &[];
+        let (primary_span, suggestions) = self.primary_span_formatted(&db);
 
         // FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index a0ce761cfa277..a298f9958f2d1 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -191,16 +191,25 @@ pub trait Emitter {
     fn should_show_explain(&self) -> bool {
         true
     }
-}
 
-impl Emitter for EmitterWriter {
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+    /// Formats the substitutions of the primary_span
+    ///
+    /// The are a lot of conditions to this method, but in short:
+    ///
+    /// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
+    ///   we format the `help` suggestion depending on the content of the
+    ///   substitutions. In that case, we return the modified span only.
+    ///
+    /// * If the current `Diagnostic` has multiple suggestions,
+    ///   we return the original `primary_span` and the original suggestions.
+    fn primary_span_formatted<'a>(
+        &mut self,
+        db: &'a DiagnosticBuilder<'_>
+    ) -> (MultiSpan, &'a [CodeSuggestion]) {
         let mut primary_span = db.span.clone();
-        let mut children = db.children.clone();
-        let mut suggestions: &[_] = &[];
-
         if let Some((sugg, rest)) = db.suggestions.split_first() {
             if rest.is_empty() &&
+               // ^ if there is only one suggestion
                // don't display multi-suggestions as labels
                sugg.substitutions.len() == 1 &&
                // don't display multipart suggestions as labels
@@ -216,21 +225,34 @@ impl Emitter for EmitterWriter {
             {
                 let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
                 let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
-                    // This substitution is only removal or we explicitly don't want to show the
-                    // code inline, don't show it
+                    // This substitution is only removal OR we explicitly don't want to show the
+                    // code inline (`hide_inline`). Therefore, we don't show the substitution.
                     format!("help: {}", sugg.msg)
                 } else {
+                    // Show the default suggestion text with the substitution
                     format!("help: {}: `{}`", sugg.msg, substitution)
                 };
                 primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
+
+                // We return only the modified primary_span
+                (primary_span, &[])
             } else {
                 // if there are multiple suggestions, print them all in full
                 // to be consistent. We could try to figure out if we can
                 // make one (or the first one) inline, but that would give
                 // undue importance to a semi-random suggestion
-                suggestions = &db.suggestions;
+                (primary_span, &db.suggestions)
             }
+        } else {
+            (primary_span, &db.suggestions)
         }
+    }
+}
+
+impl Emitter for EmitterWriter {
+    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+        let mut children = db.children.clone();
+        let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
 
         self.fix_multispans_in_std_macros(&mut primary_span,
                                           &mut children,
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f261fdc268b5b..e4b186736e2a1 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -405,13 +405,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
 
                 let arg = self.eval_operand(arg, source_info)?;
+                let oflo_check = self.tcx.sess.overflow_checks();
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
                     match op {
                         UnOp::Neg => {
-                            // Need to do overflow check here: For actual CTFE, MIR
-                            // generation emits code that does this before calling the op.
-                            if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
+                            // We check overflow in debug mode already
+                            // so should only check in release mode.
+                            if !oflo_check
+                            && prim.layout.ty.is_signed()
+                            && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
                                 throw_panic!(OverflowNeg)
                             }
                         }
@@ -485,7 +488,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         Scalar::from_bool(overflow).into(),
                     )
                 } else {
-                    if overflow {
+                    // We check overflow in debug mode already
+                    // so should only check in release mode.
+                    if !self.tcx.sess.overflow_checks() && overflow {
                         let err = err_panic!(Overflow(op)).into();
                         let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index efc37cc04b212..7427ae9ce8de3 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -112,19 +112,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             self.diverges.set(pats_diverge);
-            let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+            let arm_ty = if source_if && if_no_else && i != 0 && self.if_fallback_coercion(
+                expr.span,
+                &arms[0].body,
+                &mut coercion,
+            ) {
+                tcx.types.err
+            } else {
+                // Only call this if this is not an `if` expr with an expected type and no `else`
+                // clause to avoid duplicated type errors. (#60254)
+                self.check_expr_with_expectation(&arm.body, expected)
+            };
             all_arms_diverge &= self.diverges.get();
-
-            let span = expr.span;
-
             if source_if {
                 let then_expr = &arms[0].body;
                 match (i, if_no_else) {
-                    (0, _) => coercion.coerce(self, &self.misc(span), &arm.body, arm_ty),
-                    (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
+                    (0, _) => coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty),
+                    (_, true) => {} // Handled above to avoid duplicated type errors (#60254).
                     (_, _) => {
                         let then_ty = prior_arm_ty.unwrap();
-                        let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
+                        let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty);
                         coercion.coerce(self, &cause, &arm.body, arm_ty);
                     }
                 }
@@ -139,7 +146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // The reason for the first arm to fail is not that the match arms diverge,
                     // but rather that there's a prior obligation that doesn't hold.
                     0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
-                    _ => (span, ObligationCauseCode::MatchExpressionArm {
+                    _ => (expr.span, ObligationCauseCode::MatchExpressionArm {
                         arm_span,
                         source: match_src,
                         prior_arms: other_arms.clone(),
@@ -180,16 +187,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Handle the fallback arm of a desugared if(-let) like a missing else.
+    ///
+    /// Returns `true` if there was an error forcing the coercion to the `()` type.
     fn if_fallback_coercion(
         &self,
         span: Span,
         then_expr: &'tcx hir::Expr,
         coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm>,
-    ) {
+    ) -> bool {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
         let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
+        let mut error = false;
         coercion.coerce_forced_unit(self, &cause, &mut |err| {
             if let Some((span, msg)) = &ret_reason {
                 err.span_label(*span, msg.as_str());
@@ -200,7 +210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             err.note("`if` expressions without `else` evaluate to `()`");
             err.help("consider adding an `else` block that evaluates to the expected type");
+            error = true;
         }, ret_reason.is_none());
+        error
     }
 
     fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 55e7a10f1aaa4..c216cc92b1e58 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -40,6 +40,7 @@ use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut};
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::adjustment::AllowTwoPhase;
 use rustc::ty::cast::{CastKind, CastTy};
+use rustc::ty::error::TypeError;
 use rustc::middle::lang_items;
 use syntax::ast;
 use syntax_pos::Span;
@@ -461,6 +462,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                                              self.expr_ty,
                                              fcx.tcx.mk_fn_ptr(f),
                                              AllowTwoPhase::No);
+                    if let Err(TypeError::IntrinsicCast) = res {
+                        return Err(CastError::IllegalCast);
+                    }
                     if res.is_err() {
                         return Err(CastError::NonScalar);
                     }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 61b9c2a15ba16..f2e1a6e29d6fc 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -70,6 +70,7 @@ use std::ops::Deref;
 use syntax::feature_gate;
 use syntax::symbol::sym;
 use syntax_pos;
+use rustc_target::spec::abi::Abi;
 
 struct Coerce<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -689,6 +690,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         match b.sty {
             ty::FnPtr(_) => {
                 let a_sig = a.fn_sig(self.tcx);
+                // Intrinsics are not coercible to function pointers
+                if a_sig.abi() == Abi::RustIntrinsic ||
+                   a_sig.abi() == Abi::PlatformIntrinsic {
+                   return Err(TypeError::IntrinsicCast);
+                }
                 let InferOk { value: a_sig, mut obligations } =
                     self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig);
 
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index a53fb12367d0e..fbaa9904d8303 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -12,7 +12,7 @@ use crate::check::fatally_break_rust;
 use crate::check::report_unexpected_variant_res;
 use crate::check::Needs;
 use crate::check::TupleArgumentsFlag::DontTupleArguments;
-use crate::check::method::SelfSource;
+use crate::check::method::{probe, SelfSource, MethodError};
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
@@ -29,6 +29,7 @@ use rustc::hir::def::{CtorKind, Res, DefKind};
 use rustc::hir::ptr::P;
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc::middle::lang_items;
 use rustc::mir::interpret::GlobalId;
 use rustc::ty;
 use rustc::ty::adjustment::{
@@ -775,35 +776,80 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
 
-        let method = match self.lookup_method(rcvr_t,
-                                              segment,
-                                              span,
-                                              expr,
-                                              rcvr) {
+        let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
             Ok(method) => {
                 self.write_method_call(expr.hir_id, method);
                 Ok(method)
             }
             Err(error) => {
                 if segment.ident.name != kw::Invalid {
-                    self.report_method_error(span,
-                                             rcvr_t,
-                                             segment.ident,
-                                             SelfSource::MethodCall(rcvr),
-                                             error,
-                                             Some(args));
+                    self.report_extended_method_error(segment, span, args, rcvr_t, error);
                 }
                 Err(())
             }
         };
 
         // Call the generic checker.
-        self.check_method_argument_types(span,
-                                         expr.span,
-                                         method,
-                                         &args[1..],
-                                         DontTupleArguments,
-                                         expected)
+        self.check_method_argument_types(
+            span,
+            expr.span,
+            method,
+            &args[1..],
+            DontTupleArguments,
+            expected,
+        )
+    }
+
+    fn report_extended_method_error(
+        &self,
+        segment: &hir::PathSegment,
+        span: Span,
+        args: &'tcx [hir::Expr],
+        rcvr_t: Ty<'tcx>,
+        error: MethodError<'tcx>
+    ) {
+        let rcvr = &args[0];
+        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
+            if let Ok(pick) = self.lookup_probe(
+                span,
+                segment.ident,
+                new_rcvr_t,
+                rcvr,
+                probe::ProbeScope::AllTraits,
+            ) {
+                err.span_label(
+                    pick.item.ident.span,
+                    &format!("the method is available for `{}` here", new_rcvr_t),
+                );
+            }
+        };
+
+        if let Some(mut err) = self.report_method_error(
+            span,
+            rcvr_t,
+            segment.ident,
+            SelfSource::MethodCall(rcvr),
+            error,
+            Some(args),
+        ) {
+            if let ty::Adt(..) = rcvr_t.sty {
+                // Try alternative arbitrary self types that could fulfill this call.
+                // FIXME: probe for all types that *could* be arbitrary self-types, not
+                // just this whitelist.
+                let box_rcvr_t = self.tcx.mk_box(rcvr_t);
+                try_alt_rcvr(&mut err, box_rcvr_t);
+                let pin_rcvr_t = self.tcx.mk_lang_item(
+                    rcvr_t,
+                    lang_items::PinTypeLangItem,
+                );
+                try_alt_rcvr(&mut err, pin_rcvr_t);
+                let arc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Arc);
+                try_alt_rcvr(&mut err, arc_rcvr_t);
+                let rc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Rc);
+                try_alt_rcvr(&mut err, rc_rcvr_t);
+            }
+            err.emit();
+        }
     }
 
     fn check_expr_cast(
@@ -1466,8 +1512,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let struct_variant_def = def.non_enum_variant();
             let field_names = self.available_field_names(struct_variant_def);
             if !field_names.is_empty() {
-                err.note(&format!("available fields are: {}",
-                                    self.name_series_display(field_names)));
+                err.note(&format!(
+                    "available fields are: {}",
+                    self.name_series_display(field_names),
+                ));
             }
         }
     }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index a7e4f8e5c6289..1509c0f8a2196 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ok(result.callee)
     }
 
-    fn lookup_probe(
+    pub fn lookup_probe(
         &self,
         span: Span,
         method_name: ast::Ident,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 440e7e5d0e314..72e6f59715960 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -69,12 +69,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         source: SelfSource<'b>,
         error: MethodError<'tcx>,
         args: Option<&'tcx [hir::Expr]>,
-    ) {
+    ) -> Option<DiagnosticBuilder<'_>> {
         let orig_span = span;
         let mut span = span;
         // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
-            return;
+            return None;
         }
 
         let print_disambiguation_help = |
@@ -314,7 +314,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             _ => {}
                         }
                         err.emit();
-                        return;
+                        return None;
                     } else {
                         span = item_name.span;
                         let mut err = struct_span_err!(
@@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
 
-                err.emit();
+                return Some(err);
             }
 
             MethodError::Ambiguity(sources) => {
@@ -573,6 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 bug!("no return type expectations but got BadReturnType")
             }
         }
+        None
     }
 
     fn suggest_use_candidates(&self,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index cd041e80e7c9e..16903304a1427 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3580,7 +3580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     SelfSource::QPath(qself),
                     error,
                     None,
-                );
+                ).map(|mut e| e.emit());
             }
             result
         });
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index a5f685a159b39..ecbcc2a4b496f 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -5,6 +5,7 @@
 
 #![feature(rustc_attrs)]
 #![allow(exceeding_bitshifts)]
+
 #![deny(const_err)]
 
 fn black_box<T>(_: T) {
@@ -21,7 +22,7 @@ fn main() {
     let d = 42u8 - (42u8 + 1);
     //~^ ERROR const_err
     let _e = [5u8][1];
-    //~^ ERROR const_err
+    //~^ ERROR index out of bounds
     black_box(a);
     black_box(b);
     black_box(c);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 659c3afc618a9..1d84d44dc27b3 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,35 +1,35 @@
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:15:13
+  --> $DIR/const-err2.rs:16:13
    |
 LL |     let a = -std::i8::MIN;
    |             ^^^^^^^^^^^^^ attempt to negate with overflow
    |
 note: lint level defined here
-  --> $DIR/const-err2.rs:8:9
+  --> $DIR/const-err2.rs:9:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:17:13
+  --> $DIR/const-err2.rs:18:13
    |
 LL |     let b = 200u8 + 200u8 + 200u8;
    |             ^^^^^^^^^^^^^ attempt to add with overflow
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:19:13
+  --> $DIR/const-err2.rs:20:13
    |
 LL |     let c = 200u8 * 4;
    |             ^^^^^^^^^ attempt to multiply with overflow
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:21:13
+  --> $DIR/const-err2.rs:22:13
    |
 LL |     let d = 42u8 - (42u8 + 1);
    |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
 
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:23:14
+  --> $DIR/const-err2.rs:24:14
    |
 LL |     let _e = [5u8][1];
    |              ^^^^^^^^
diff --git a/src/test/ui/consts/const-err3.rs b/src/test/ui/consts/const-err3.rs
new file mode 100644
index 0000000000000..a9cf04cda7a5a
--- /dev/null
+++ b/src/test/ui/consts/const-err3.rs
@@ -0,0 +1,30 @@
+// needed because negating int::MIN will behave differently between
+// optimized compilation and unoptimized compilation and thus would
+// lead to different lints being emitted
+// compile-flags: -C overflow-checks=on -O
+
+#![feature(rustc_attrs)]
+#![allow(exceeding_bitshifts)]
+
+#![deny(const_err)]
+
+fn black_box<T>(_: T) {
+    unimplemented!()
+}
+
+fn main() {
+    let a = -std::i8::MIN;
+    //~^ ERROR const_err
+    let b = 200u8 + 200u8 + 200u8;
+    //~^ ERROR const_err
+    let c = 200u8 * 4;
+    //~^ ERROR const_err
+    let d = 42u8 - (42u8 + 1);
+    //~^ ERROR const_err
+    let _e = [5u8][1];
+    //~^ ERROR const_err
+    black_box(a);
+    black_box(b);
+    black_box(c);
+    black_box(d);
+}
diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr
new file mode 100644
index 0000000000000..0602707be7040
--- /dev/null
+++ b/src/test/ui/consts/const-err3.stderr
@@ -0,0 +1,38 @@
+error: attempt to negate with overflow
+  --> $DIR/const-err3.rs:16:13
+   |
+LL |     let a = -std::i8::MIN;
+   |             ^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/const-err3.rs:9:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to add with overflow
+  --> $DIR/const-err3.rs:18:13
+   |
+LL |     let b = 200u8 + 200u8 + 200u8;
+   |             ^^^^^^^^^^^^^
+
+error: attempt to multiply with overflow
+  --> $DIR/const-err3.rs:20:13
+   |
+LL |     let c = 200u8 * 4;
+   |             ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/const-err3.rs:22:13
+   |
+LL |     let d = 42u8 - (42u8 + 1);
+   |             ^^^^^^^^^^^^^^^^^
+
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-err3.rs:24:14
+   |
+LL |     let _e = [5u8][1];
+   |              ^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index cd989731452b3..45941398f4b66 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -5,7 +5,7 @@
 fn main() {
     println!("{}", 0u32 - 1);
     let _x = 0u32 - 1;
-    //~^ ERROR this expression will panic at runtime [const_err]
+    //~^ ERROR const_err
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs
new file mode 100644
index 0000000000000..7adb394144bdd
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.rs
@@ -0,0 +1,22 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+fn main() {
+    println!("{}", 0u32 - 1);
+    //~^ ERROR attempt to subtract with overflow
+    let _x = 0u32 - 1;
+    //~^ ERROR attempt to subtract with overflow
+    println!("{}", 1/(1-1));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(1-1);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+    println!("{}", 1/(false as u32));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(false as u32);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+}
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr
new file mode 100644
index 0000000000000..2819e6e8fdbe0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr
@@ -0,0 +1,68 @@
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:6:20
+   |
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/promoted_errors2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:8:14
+   |
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/consts/issue-64059-2.rs b/src/test/ui/consts/issue-64059-2.rs
new file mode 100644
index 0000000000000..38911c3dcf692
--- /dev/null
+++ b/src/test/ui/consts/issue-64059-2.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on -O
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
new file mode 100644
index 0000000000000..c4c895fef66cf
--- /dev/null
+++ b/src/test/ui/consts/issue-64059.rs
@@ -0,0 +1,5 @@
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}
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 15892de83854c..826371be35f45 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
@@ -3,7 +3,6 @@ fn foo(bar: usize) -> usize {
         return 3;
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo2(bar: usize) -> usize {
@@ -11,7 +10,6 @@ fn foo2(bar: usize) -> usize {
         return 3;
     };
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
     x
 }
 
@@ -20,7 +18,6 @@ fn foo3(bar: usize) -> usize {
         3
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo_let(bar: usize) -> usize {
@@ -28,7 +25,6 @@ fn foo_let(bar: usize) -> usize {
         return 3;
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo2_let(bar: usize) -> usize {
@@ -36,7 +32,6 @@ fn foo2_let(bar: usize) -> usize {
         return 3;
     };
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
     x
 }
 
@@ -45,7 +40,6 @@ fn foo3_let(bar: usize) -> usize {
         3
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 // 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 06600b1cb9aea..b49c2aa6319df 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,14 +1,3 @@
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:2:5
-   |
-LL | /     if bar % 5 == 0 {
-LL | |         return 3;
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
   --> $DIR/if-without-else-as-fn-expr.rs:2:5
    |
@@ -24,20 +13,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:10:20
-   |
-LL |       let x: usize = if bar % 5 == 0 {
-   |  ____________________^
-LL | |         return 3;
-LL | |     };
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:10:20
+  --> $DIR/if-without-else-as-fn-expr.rs:9:20
    |
 LL |       let x: usize = if bar % 5 == 0 {
    |  _________-__________^
@@ -52,19 +29,8 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:19:5
-   |
-LL | /     if bar % 5 == 0 {
-LL | |         3
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:19:5
+  --> $DIR/if-without-else-as-fn-expr.rs:17:5
    |
 LL |   fn foo3(bar: usize) -> usize {
    |                          ----- expected `usize` because of this return type
@@ -78,19 +44,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:27:5
-   |
-LL | /     if let 0 = 1 {
-LL | |         return 3;
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:27:5
+  --> $DIR/if-without-else-as-fn-expr.rs:24:5
    |
 LL |   fn foo_let(bar: usize) -> usize {
    |                             ----- expected `usize` because of this return type
@@ -104,20 +59,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:35:20
-   |
-LL |       let x: usize = if let 0 = 1 {
-   |  ____________________^
-LL | |         return 3;
-LL | |     };
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:35:20
+  --> $DIR/if-without-else-as-fn-expr.rs:31:20
    |
 LL |       let x: usize = if let 0 = 1 {
    |  _________-__________^
@@ -132,19 +75,8 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:44:5
-   |
-LL | /     if let 0 = 1 {
-LL | |         3
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:44:5
+  --> $DIR/if-without-else-as-fn-expr.rs:39:5
    |
 LL |   fn foo3_let(bar: usize) -> usize {
    |                              ----- expected `usize` because of this return type
@@ -158,7 +90,6 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error: aborting due to 12 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0308, E0317.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index d980d7cccadd5..002b60f9f258d 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -49,6 +49,14 @@ LL | use foo::Bar;
 error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:32:43
    |
+LL |         fn method(&self) {}
+   |            ------
+   |            |
+   |            the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+...
 LL |     std::rc::Rc::new(&mut Box::new(&'a')).method();
    |                                           ^^^^^^
    |
diff --git a/src/test/ui/issues/issue-50577.rs b/src/test/ui/issues/issue-50577.rs
index bf892a8daa27f..f0f1dc6c28667 100644
--- a/src/test/ui/issues/issue-50577.rs
+++ b/src/test/ui/issues/issue-50577.rs
@@ -2,6 +2,5 @@ fn main() {
     enum Foo {
         Drop = assert_eq!(1, 1)
         //~^ ERROR if may be missing an else clause
-        //~| ERROR mismatched types [E0308]
     }
 }
diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr
index 413c8c5c80b52..0c3ba2ea4f94d 100644
--- a/src/test/ui/issues/issue-50577.stderr
+++ b/src/test/ui/issues/issue-50577.stderr
@@ -1,13 +1,3 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-50577.rs:3:16
-   |
-LL |         Drop = assert_eq!(1, 1)
-   |                ^^^^^^^^^^^^^^^^ expected isize, found ()
-   |
-   = note: expected type `isize`
-              found type `()`
-   = 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
   --> $DIR/issue-50577.rs:3:16
    |
@@ -23,7 +13,6 @@ LL |         Drop = assert_eq!(1, 1)
    = help: consider adding an `else` block that evaluates to the expected type
    = 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: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0308, E0317.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/issues/issue-8460-const2.rs b/src/test/ui/issues/issue-8460-const2.rs
new file mode 100644
index 0000000000000..c3f53e3298b2b
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.rs
@@ -0,0 +1,59 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+use std::{isize, i8, i16, i32, i64};
+use std::thread;
+
+fn main() {
+    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+}
diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr
new file mode 100644
index 0000000000000..b688ec1367794
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.stderr
@@ -0,0 +1,188 @@
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:9:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-8460-const2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:11:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:13:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:15:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:17:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:34:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:36:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:38:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:40:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:42:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 30 previous errors
+
diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs
new file mode 100644
index 0000000000000..09baa059e5567
--- /dev/null
+++ b/src/test/ui/reify-intrinsic.rs
@@ -0,0 +1,15 @@
+// check-fail
+
+#![feature(intrinsics)]
+
+fn a() {
+    let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
+    //~^ ERROR cannot coerce
+}
+
+fn b() {
+    let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
+    //~^ ERROR casting
+}
+
+fn main() {}
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
new file mode 100644
index 0000000000000..4a1bd77cf7ee9
--- /dev/null
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -0,0 +1,22 @@
+error[E0308]: cannot coerce intrinsics to function pointers
+  --> $DIR/reify-intrinsic.rs:6:64
+   |
+LL |     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
+   |                                                                ^^^^^^^^^^^^^^^^^^^
+   |                                                                |
+   |                                                                cannot coerce intrinsics to function pointers
+   |                                                                help: use parentheses to call this function: `std::mem::transmute(...)`
+   |
+   = note: expected type `unsafe extern "rust-intrinsic" fn(isize) -> usize`
+              found type `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
+
+error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
+  --> $DIR/reify-intrinsic.rs:11:13
+   |
+LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0606.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-method.rs
new file mode 100644
index 0000000000000..0f7deeacad292
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-method.rs
@@ -0,0 +1,9 @@
+struct A;
+
+impl A {
+    fn foo(self: Box<Self>) {}
+}
+
+fn main() {
+    A.foo(); //~ ERROR E0599
+}
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
new file mode 100644
index 0000000000000..06dad7caa6735
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `foo` found for type `A` in the current scope
+  --> $DIR/point-at-arbitrary-self-type-method.rs:8:7
+   |
+LL | struct A;
+   | --------- method `foo` not found for this
+...
+LL |     fn foo(self: Box<Self>) {}
+   |        --- the method is available for `std::boxed::Box<A>` here
+...
+LL |     A.foo();
+   |       ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs
new file mode 100644
index 0000000000000..53d992771186f
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs
@@ -0,0 +1,10 @@
+trait B { fn foo(self: Box<Self>); }
+struct A;
+
+impl B for A {
+    fn foo(self: Box<Self>) {}
+}
+
+fn main() {
+    A.foo() //~ ERROR E0599
+}
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
new file mode 100644
index 0000000000000..90cd3b8074580
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
@@ -0,0 +1,18 @@
+error[E0599]: no method named `foo` found for type `A` in the current scope
+  --> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7
+   |
+LL | trait B { fn foo(self: Box<Self>); }
+   |              --- the method is available for `std::boxed::Box<A>` here
+LL | struct A;
+   | --------- method `foo` not found for this
+...
+LL |     A.foo()
+   |       ^^^
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `foo`, perhaps you need to implement it:
+           candidate #1: `B`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index de699a69fa8bc..ce2919c8e7741 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -17,6 +17,13 @@ error[E0599]: no method named `b` found for type `S` in the current scope
 LL | struct S;
    | --------- method `b` not found for this
 ...
+LL |         fn b(&self) { }
+   |            -
+   |            |
+   |            the method is available for `std::boxed::Box<S>` here
+   |            the method is available for `std::sync::Arc<S>` here
+   |            the method is available for `std::rc::Rc<S>` here
+...
 LL |     S.b();
    |       ^
    |
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index bde49ff391c8c..467b7771c152e 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -335,7 +335,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         runtool: matches.opt_str("runtool"),
         host_rustcflags: matches.opt_str("host-rustcflags"),
         target_rustcflags: matches.opt_str("target-rustcflags"),
-        target: target,
+        target,
         host: opt_str2(matches.opt_str("host")),
         cdb,
         gdb,
@@ -345,7 +345,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         lldb_native_rust,
         llvm_version: matches.opt_str("llvm-version"),
         system_llvm: matches.opt_present("system-llvm"),
-        android_cross_path: android_cross_path,
+        android_cross_path,
         adb_path: opt_str2(matches.opt_str("adb-path")),
         adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")),
         adb_device_status: opt_str2(matches.opt_str("target")).contains("android")