about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-21 11:22:17 +0000
committerbors <bors@rust-lang.org>2020-10-21 11:22:17 +0000
commit19356453cbfb734bc60a1853c10e3095d05e0342 (patch)
tree7b4db815ca111d129ecda5f620695fff51563a2e
parentf965120ad3dbe7d4d6b90a16cc7028eb6363b983 (diff)
parentde24210ebf40b5700908d0a6613f82afe1995b52 (diff)
Auto merge of #78178 - JohnTitor:rollup-dslazzj, r=JohnTitor
Rollup of 7 pull requests

Successful merges:

 - #77726 (Add Pin::static_ref, static_mut.)
 - #78002 (Tweak "object unsafe" errors)
 - #78056 (BTreeMap: split off most code of remove and split_off)
 - #78063 (Improve wording of "cannot multiply" type error)
 - #78094 (rustdoc: Show the correct source filename in page titles, without `.html`)
 - #78101 (fix static_ptr_ty for foreign statics)
 - #78118 (Inline const followups)

Failed merges:

r? `@ghost`
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs39
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs9
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs8
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs76
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_mir/src/transform/check_unsafety.rs3
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs111
-rw-r--r--compiler/rustc_typeck/src/check/op.rs2
-rw-r--r--library/alloc/src/collections/btree/map.rs223
-rw-r--r--library/alloc/src/collections/btree/mod.rs2
-rw-r--r--library/alloc/src/collections/btree/remove.rs132
-rw-r--r--library/alloc/src/collections/btree/split.rs104
-rw-r--r--library/core/src/ops/arith.rs4
-rw-r--r--library/core/src/pin.rs28
-rw-r--r--src/librustdoc/html/sources.rs13
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir10
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff8
-rw-r--r--src/test/ui/associated-consts/associated-const-in-trait.stderr14
-rw-r--r--src/test/ui/associated-item/issue-48027.stderr14
-rw-r--r--src/test/ui/binop/binop-mul-bool.rs2
-rw-r--r--src/test/ui/binop/binop-mul-bool.stderr2
-rw-r--r--src/test/ui/binop/binop-mul-i32-f32.rs5
-rw-r--r--src/test/ui/binop/binop-mul-i32-f32.stderr11
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr13
-rw-r--r--src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr3
-rw-r--r--src/test/ui/error-codes/E0033-teach.stderr16
-rw-r--r--src/test/ui/error-codes/E0033.stderr16
-rw-r--r--src/test/ui/error-codes/E0038.stderr14
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr66
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr32
-rw-r--r--src/test/ui/inline-const/const-expr-macro.rs12
-rw-r--r--src/test/ui/issues/issue-18959.stderr14
-rw-r--r--src/test/ui/issues/issue-19380.stderr16
-rw-r--r--src/test/ui/issues/issue-19538.stderr28
-rw-r--r--src/test/ui/issues/issue-20692.stderr23
-rw-r--r--src/test/ui/issues/issue-26056.stderr11
-rw-r--r--src/test/ui/issues/issue-28576.stderr19
-rw-r--r--src/test/ui/issues/issue-28837.rs2
-rw-r--r--src/test/ui/issues/issue-28837.stderr2
-rw-r--r--src/test/ui/issues/issue-35668.rs2
-rw-r--r--src/test/ui/issues/issue-35668.stderr2
-rw-r--r--src/test/ui/issues/issue-3820.rs2
-rw-r--r--src/test/ui/issues/issue-3820.stderr2
-rw-r--r--src/test/ui/issues/issue-38404.stderr10
-rw-r--r--src/test/ui/issues/issue-38604.stderr23
-rw-r--r--src/test/ui/issues/issue-50781.stderr11
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr23
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr12
-rw-r--r--src/test/ui/mismatched_types/binops.rs2
-rw-r--r--src/test/ui/mismatched_types/binops.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.curr.stderr14
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr14
-rw-r--r--src/test/ui/object-safety/object-safety-bounds.stderr11
-rw-r--r--src/test/ui/object-safety/object-safety-generics.curr.stderr28
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr28
-rw-r--r--src/test/ui/object-safety/object-safety-issue-22040.stderr11
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr28
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr28
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.curr.stderr16
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr18
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.curr.stderr11
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr12
-rw-r--r--src/test/ui/object-safety/object-safety-sized.curr.stderr11
-rw-r--r--src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr12
-rw-r--r--src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr11
-rw-r--r--src/test/ui/pattern/pattern-tyvar-2.rs2
-rw-r--r--src/test/ui/pattern/pattern-tyvar-2.stderr2
-rw-r--r--src/test/ui/resolve/issue-3907-2.stderr9
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr33
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr16
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-references-self.stderr29
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr25
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed2
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr18
-rw-r--r--src/test/ui/traits/issue-72410.stderr15
-rw-r--r--src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr9
-rw-r--r--src/test/ui/traits/trait-item-privacy.stderr22
-rw-r--r--src/test/ui/traits/trait-object-macro-matcher.stderr3
-rw-r--r--src/test/ui/traits/trait-object-safety.stderr34
-rw-r--r--src/test/ui/traits/trait-resolution-in-overloaded-op.rs2
-rw-r--r--src/test/ui/traits/trait-resolution-in-overloaded-op.stderr2
-rw-r--r--src/test/ui/traits/trait-test-2.stderr30
-rw-r--r--src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr14
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr36
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr36
-rw-r--r--src/test/ui/wf/wf-fn-where-clause.stderr3
-rw-r--r--src/test/ui/wf/wf-object-safe.stderr14
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr24
90 files changed, 1102 insertions, 741 deletions
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 4686b4989ae..1cd4ddad578 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1138,9 +1138,7 @@ impl<'a> State<'a> {
     fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) {
         self.ibox(INDENT_UNIT);
         self.s.word_space("const");
-        self.s.word("{");
         self.print_anon_const(anon_const);
-        self.s.word("}");
         self.end()
     }
 
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index f873358ff9f..835f75ec8ef 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -2,12 +2,12 @@ use super::ObjectSafetyViolation;
 
 use crate::infer::InferCtxt;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::Symbol;
-use rustc_span::Span;
+use rustc_span::{MultiSpan, Span};
 use std::fmt;
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
@@ -54,10 +54,11 @@ pub fn report_object_safety_error(
         "the trait `{}` cannot be made into an object",
         trait_str
     );
-    err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
+    err.span_label(span, format!("`{}` cannot be made into an object", trait_str));
 
     let mut reported_violations = FxHashSet::default();
-    let mut had_span_label = false;
+    let mut multi_span = vec![];
+    let mut messages = vec![];
     for violation in violations {
         if let ObjectSafetyViolation::SizedSelf(sp) = &violation {
             if !sp.is_empty() {
@@ -71,31 +72,37 @@ pub fn report_object_safety_error(
             let msg = if trait_span.is_none() || spans.is_empty() {
                 format!("the trait cannot be made into an object because {}", violation.error_msg())
             } else {
-                had_span_label = true;
                 format!("...because {}", violation.error_msg())
             };
             if spans.is_empty() {
                 err.note(&msg);
             } else {
                 for span in spans {
-                    err.span_label(span, &msg);
+                    multi_span.push(span);
+                    messages.push(msg.clone());
                 }
             }
-            match (trait_span, violation.solution()) {
-                (Some(_), Some((note, None))) => {
-                    err.help(&note);
-                }
-                (Some(_), Some((note, Some((sugg, span))))) => {
-                    err.span_suggestion(span, &note, sugg, Applicability::MachineApplicable);
-                }
+            if trait_span.is_some() {
                 // Only provide the help if its a local trait, otherwise it's not actionable.
-                _ => {}
+                violation.solution(&mut err);
             }
         }
     }
-    if let (Some(trait_span), true) = (trait_span, had_span_label) {
-        err.span_label(trait_span, "this trait cannot be made into an object...");
+    let has_multi_span = !multi_span.is_empty();
+    let mut note_span = MultiSpan::from_spans(multi_span.clone());
+    if let (Some(trait_span), true) = (trait_span, has_multi_span) {
+        note_span
+            .push_span_label(trait_span, "this trait cannot be made into an object...".to_string());
     }
+    for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) {
+        note_span.push_span_label(span, msg);
+    }
+    err.span_note(
+        note_span,
+        "for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
+         to be resolvable dynamically; for more information visit \
+         <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
+    );
 
     if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
         // Avoid emitting error caused by non-existing method (#58734)
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index b38efedbf60..fa40995407f 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> {
     /// flag drop flags to avoid triggering this check as they are introduced
     /// after typeck.
     ///
-    /// Unsafety checking will also ignore dereferences of these locals,
-    /// so they can be used for raw pointers only used in a desugaring.
-    ///
     /// This should be sound because the drop flags are fully algebraic, and
     /// therefore don't affect the OIBIT or outlives properties of the
     /// generator.
@@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> {
     }
 
     /// Returns `Some` if this is a reference to a static item that is used to
-    /// access that static
+    /// access that static.
     pub fn is_ref_to_static(&self) -> bool {
         matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
     }
 
-    /// Returns `Some` if this is a reference to a static item that is used to
-    /// access that static
+    /// Returns `Some` if this is a reference to a thread-local static item that is used to
+    /// access that static.
     pub fn is_ref_to_thread_local(&self) -> bool {
         match self.local_info {
             Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index b9e4f6fb12e..f0bfdae261c 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> {
                 tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
             }
             Rvalue::ThreadLocalRef(did) => {
+                let static_ty = tcx.type_of(did);
                 if tcx.is_mutable_static(did) {
-                    tcx.mk_mut_ptr(tcx.type_of(did))
+                    tcx.mk_mut_ptr(static_ty)
+                } else if tcx.is_foreign_item(did) {
+                    tcx.mk_imm_ptr(static_ty)
                 } else {
-                    tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did))
+                    // FIXME: These things don't *really* have 'static lifetime.
+                    tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty)
                 }
             }
             Rvalue::Ref(reg, bk, ref place) => {
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 1dd6d590d90..26962aa1083 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
+use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_span::symbol::Symbol;
@@ -646,13 +647,13 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
             ObjectSafetyViolation::SupertraitSelf(ref spans) => {
                 if spans.iter().any(|sp| *sp != DUMMY_SP) {
-                    "it uses `Self` as a type parameter in this".into()
+                    "it uses `Self` as a type parameter".into()
                 } else {
                     "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
                         .into()
                 }
             }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
+            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => {
                 format!("associated function `{}` has no `self` parameter", name).into()
             }
             ObjectSafetyViolation::Method(
@@ -686,32 +687,65 @@ impl ObjectSafetyViolation {
         }
     }
 
-    pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
-        Some(match *self {
-            ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
-                return None;
+    pub fn solution(&self, err: &mut DiagnosticBuilder<'_>) {
+        match *self {
+            ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
+            ObjectSafetyViolation::Method(
+                name,
+                MethodViolationCode::StaticMethod(sugg, self_span, has_args),
+                _,
+            ) => {
+                err.span_suggestion(
+                    self_span,
+                    &format!(
+                        "consider turning `{}` into a method by giving it a `&self` argument",
+                        name
+                    ),
+                    format!("&self{}", if has_args { ", " } else { "" }),
+                    Applicability::MaybeIncorrect,
+                );
+                match sugg {
+                    Some((sugg, span)) => {
+                        err.span_suggestion(
+                            span,
+                            &format!(
+                                "alternatively, consider constraining `{}` so it does not apply to \
+                                 trait objects",
+                                name
+                            ),
+                            sugg.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    None => {
+                        err.help(&format!(
+                            "consider turning `{}` into a method by giving it a `&self` \
+                             argument or constraining it so it does not apply to trait objects",
+                            name
+                        ));
+                    }
+                }
             }
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
-                format!(
-                    "consider turning `{}` into a method by giving it a `&self` argument or \
-                     constraining it so it does not apply to trait objects",
-                    name
-                ),
-                sugg.map(|(sugg, sp)| (sugg.to_string(), sp)),
-            ),
             ObjectSafetyViolation::Method(
                 name,
                 MethodViolationCode::UndispatchableReceiver,
                 span,
-            ) => (
-                format!("consider changing method `{}`'s `self` parameter to be `&self`", name),
-                Some(("&Self".to_string(), span)),
-            ),
+            ) => {
+                err.span_suggestion(
+                    span,
+                    &format!(
+                        "consider changing method `{}`'s `self` parameter to be `&self`",
+                        name
+                    ),
+                    "&Self".to_string(),
+                    Applicability::MachineApplicable,
+                );
+            }
             ObjectSafetyViolation::AssocConst(name, _)
             | ObjectSafetyViolation::Method(name, ..) => {
-                (format!("consider moving `{}` to another trait", name), None)
+                err.help(&format!("consider moving `{}` to another trait", name));
             }
-        })
+        }
     }
 
     pub fn spans(&self) -> SmallVec<[Span; 1]> {
@@ -735,7 +769,7 @@ impl ObjectSafetyViolation {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
 pub enum MethodViolationCode {
     /// e.g., `fn foo()`
-    StaticMethod(Option<(&'static str, Span)>),
+    StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
 
     /// e.g., `fn foo(&self, x: Self)`
     ReferencesSelfInput(usize),
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index b0f0f0ba57f..4a20e1c32f9 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> {
         // Make sure that any constants in the static's type are evaluated.
         let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));
 
+        // Make sure that accesses to unsafe statics end up using raw pointers.
+        // For thread-locals, this needs to be kept in sync with `Rvalue::ty`.
         if self.is_mutable_static(def_id) {
             self.mk_mut_ptr(static_ty)
+        } else if self.is_foreign_item(def_id) {
+            self.mk_imm_ptr(static_ty)
         } else {
             self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
         }
diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs
index 7309a4129e4..3d68b862df2 100644
--- a/compiler/rustc_mir/src/transform/check_unsafety.rs
+++ b/compiler/rustc_mir/src/transform/check_unsafety.rs
@@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             if let [] = proj_base {
                 let decl = &self.body.local_decls[place.local];
                 if decl.internal {
+                    // If the projection root is an artifical local that we introduced when
+                    // desugaring `static`, give a more specific error message
+                    // (avoid the general "raw pointer" clause below, that would only be confusing).
                     if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
                         if self.tcx.is_mutable_static(def_id) {
                             self.require_unsafe(
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 1860f1238c4..5176db82d3b 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -548,7 +548,11 @@ impl<'a> Parser<'a> {
 
     fn check_inline_const(&mut self) -> bool {
         self.check_keyword(kw::Const)
-            && self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace))
+            && self.look_ahead(1, |t| match t.kind {
+                token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)),
+                token::OpenDelim(DelimToken::Brace) => true,
+                _ => false,
+            })
     }
 
     /// Checks to see if the next token is either `+` or `+=`.
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 0e43f1655dd..d1647e686a8 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -13,7 +13,7 @@ use super::elaborate_predicates;
 use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{self, Obligation, ObligationCause};
-use rustc_errors::{Applicability, FatalError};
+use rustc_errors::FatalError;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst};
@@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor, WithConstnes
 use rustc_middle::ty::{Predicate, ToPredicate};
 use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
-use rustc_span::Span;
+use rustc_span::{MultiSpan, Span};
 use smallvec::SmallVec;
 
 use std::array;
@@ -100,49 +100,7 @@ fn object_safety_violations_for_trait(
                 span,
             ) = violation
             {
-                // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
-                // It's also hard to get a use site span, so we use the method definition span.
-                tcx.struct_span_lint_hir(
-                    WHERE_CLAUSES_OBJECT_SAFETY,
-                    hir::CRATE_HIR_ID,
-                    *span,
-                    |lint| {
-                        let mut err = lint.build(&format!(
-                            "the trait `{}` cannot be made into an object",
-                            tcx.def_path_str(trait_def_id)
-                        ));
-                        let node = tcx.hir().get_if_local(trait_def_id);
-                        let msg = if let Some(hir::Node::Item(item)) = node {
-                            err.span_label(
-                                item.ident.span,
-                                "this trait cannot be made into an object...",
-                            );
-                            format!("...because {}", violation.error_msg())
-                        } else {
-                            format!(
-                                "the trait cannot be made into an object because {}",
-                                violation.error_msg()
-                            )
-                        };
-                        err.span_label(*span, &msg);
-                        match (node, violation.solution()) {
-                            (Some(_), Some((note, None))) => {
-                                err.help(&note);
-                            }
-                            (Some(_), Some((note, Some((sugg, span))))) => {
-                                err.span_suggestion(
-                                    span,
-                                    &note,
-                                    sugg,
-                                    Applicability::MachineApplicable,
-                                );
-                            }
-                            // Only provide the help if its a local trait, otherwise it's not actionable.
-                            _ => {}
-                        }
-                        err.emit();
-                    },
-                );
+                lint_object_unsafe_trait(tcx, *span, trait_def_id, violation);
                 false
             } else {
                 true
@@ -180,6 +138,51 @@ fn object_safety_violations_for_trait(
     violations
 }
 
+/// Lint object-unsafe trait.
+fn lint_object_unsafe_trait(
+    tcx: TyCtxt<'_>,
+    span: Span,
+    trait_def_id: DefId,
+    violation: &ObjectSafetyViolation,
+) {
+    // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
+    // It's also hard to get a use site span, so we use the method definition span.
+    tcx.struct_span_lint_hir(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |lint| {
+        let mut err = lint.build(&format!(
+            "the trait `{}` cannot be made into an object",
+            tcx.def_path_str(trait_def_id)
+        ));
+        let node = tcx.hir().get_if_local(trait_def_id);
+        let mut spans = MultiSpan::from_span(span);
+        if let Some(hir::Node::Item(item)) = node {
+            spans.push_span_label(
+                item.ident.span,
+                "this trait cannot be made into an object...".into(),
+            );
+            spans.push_span_label(span, format!("...because {}", violation.error_msg()));
+        } else {
+            spans.push_span_label(
+                span,
+                format!(
+                    "the trait cannot be made into an object because {}",
+                    violation.error_msg()
+                ),
+            );
+        };
+        err.span_note(
+            spans,
+            "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
+             call to be resolvable dynamically; for more information visit \
+             <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
+        );
+        if node.is_some() {
+            // Only provide the help if its a local trait, otherwise it's not
+            violation.solution(&mut err);
+        }
+        err.emit();
+    });
+}
+
 fn sized_trait_bound_spans<'tcx>(
     tcx: TyCtxt<'tcx>,
     bounds: hir::GenericBounds<'tcx>,
@@ -385,6 +388,8 @@ fn virtual_call_violation_for_method<'tcx>(
     trait_def_id: DefId,
     method: &ty::AssocItem,
 ) -> Option<MethodViolationCode> {
+    let sig = tcx.fn_sig(method.def_id);
+
     // The method's first parameter must be named `self`
     if !method.fn_has_self_parameter {
         // We'll attempt to provide a structured suggestion for `Self: Sized`.
@@ -395,11 +400,21 @@ fn virtual_call_violation_for_method<'tcx>(
                     [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()),
                 },
             );
-        return Some(MethodViolationCode::StaticMethod(sugg));
+        // Get the span pointing at where the `self` receiver should be.
+        let sm = tcx.sess.source_map();
+        let self_span = method.ident.span.to(tcx
+            .hir()
+            .span_if_local(method.def_id)
+            .unwrap_or_else(|| sm.next_point(method.ident.span))
+            .shrink_to_hi());
+        let self_span = sm.span_through_char(self_span, '(').shrink_to_hi();
+        return Some(MethodViolationCode::StaticMethod(
+            sugg,
+            self_span,
+            !sig.inputs().skip_binder().is_empty(),
+        ));
     }
 
-    let sig = tcx.fn_sig(method.def_id);
-
     for (i, input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() {
         if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
             return Some(MethodViolationCode::ReferencesSelfInput(i));
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index 2f3fb49717b..02268b11a7a 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -302,7 +302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 true,
                             ),
                             hir::BinOpKind::Mul => (
-                                format!("cannot multiply `{}` to `{}`", rhs_ty, lhs_ty),
+                                format!("cannot multiply `{}` by `{}`", lhs_ty, rhs_ty),
                                 Some("std::ops::Mul"),
                                 true,
                             ),
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 92cbce96054..20c6ebd2292 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -13,8 +13,6 @@ use super::node::{self, marker, ForceResult::*, Handle, NodeRef};
 use super::search::{self, SearchResult::*};
 use super::unwrap_unchecked;
 
-use UnderflowResult::*;
-
 mod entry;
 pub use entry::{Entry, OccupiedEntry, VacantEntry};
 use Entry::*;
@@ -1154,40 +1152,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
 
         let mut right = Self::new();
         let right_root = Self::ensure_is_owned(&mut right.root);
-        for _ in 0..left_root.height() {
-            right_root.push_internal_level();
-        }
-
-        {
-            let mut left_node = left_root.node_as_mut();
-            let mut right_node = right_root.node_as_mut();
-
-            loop {
-                let mut split_edge = match search::search_node(left_node, key) {
-                    // key is going to the right tree
-                    Found(handle) => handle.left_edge(),
-                    GoDown(handle) => handle,
-                };
 
-                split_edge.move_suffix(&mut right_node);
-
-                match (split_edge.force(), right_node.force()) {
-                    (Internal(edge), Internal(node)) => {
-                        left_node = edge.descend();
-                        right_node = node.first_edge().descend();
-                    }
-                    (Leaf(_), Leaf(_)) => {
-                        break;
-                    }
-                    _ => {
-                        unreachable!();
-                    }
-                }
-            }
-        }
-
-        left_root.fix_right_border();
-        right_root.fix_left_border();
+        left_root.split_off(right_root, key);
 
         if left_root.height() < right_root.height() {
             self.length = left_root.node_as_ref().calc_length();
@@ -2250,193 +2216,6 @@ impl<K, V> BTreeMap<K, V> {
     }
 }
 
-impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
-    /// Removes a key/value-pair from the map, and returns that pair, as well as
-    /// the leaf edge corresponding to that former pair.
-    fn remove_kv_tracking<F: FnOnce()>(
-        self,
-        handle_emptied_internal_root: F,
-    ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
-        let (old_kv, mut pos, was_internal) = match self.force() {
-            Leaf(leaf) => {
-                let (old_kv, pos) = leaf.remove();
-                (old_kv, pos, false)
-            }
-            Internal(mut internal) => {
-                // Replace the location freed in the internal node with an
-                // adjacent KV, and remove that adjacent KV from its leaf.
-                // Always choose the adjacent KV on the left side because
-                // it is typically faster to pop an element from the end
-                // of the KV arrays without needing to shift other elements.
-
-                let key_loc = internal.kv_mut().0 as *mut K;
-                let val_loc = internal.kv_mut().1 as *mut V;
-
-                let to_remove = internal.left_edge().descend().last_leaf_edge().left_kv().ok();
-                let to_remove = unsafe { unwrap_unchecked(to_remove) };
-
-                let (kv, pos) = to_remove.remove();
-
-                let old_key = unsafe { mem::replace(&mut *key_loc, kv.0) };
-                let old_val = unsafe { mem::replace(&mut *val_loc, kv.1) };
-
-                ((old_key, old_val), pos, true)
-            }
-        };
-
-        // Handle underflow
-        let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() };
-        let mut at_leaf = true;
-        while cur_node.len() < node::MIN_LEN {
-            match handle_underfull_node(cur_node) {
-                AtRoot => break,
-                Merged(edge, merged_with_left, offset) => {
-                    // If we merged with our right sibling then our tracked
-                    // position has not changed. However if we merged with our
-                    // left sibling then our tracked position is now dangling.
-                    if at_leaf && merged_with_left {
-                        let idx = pos.idx() + offset;
-                        let node = match unsafe { ptr::read(&edge).descend().force() } {
-                            Leaf(leaf) => leaf,
-                            Internal(_) => unreachable!(),
-                        };
-                        pos = unsafe { Handle::new_edge(node, idx) };
-                    }
-
-                    let parent = edge.into_node();
-                    if parent.len() == 0 {
-                        // The parent that was just emptied must be the root,
-                        // because nodes on a lower level would not have been
-                        // left with a single child.
-                        handle_emptied_internal_root();
-                        break;
-                    } else {
-                        cur_node = parent.forget_type();
-                        at_leaf = false;
-                    }
-                }
-                Stole(stole_from_left) => {
-                    // Adjust the tracked position if we stole from a left sibling
-                    if stole_from_left && at_leaf {
-                        // SAFETY: This is safe since we just added an element to our node.
-                        unsafe {
-                            pos.move_next_unchecked();
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-
-        // If we deleted from an internal node then we need to compensate for
-        // the earlier swap and adjust the tracked position to point to the
-        // next element.
-        if was_internal {
-            pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() };
-        }
-
-        (old_kv, pos)
-    }
-}
-
-impl<K, V> node::Root<K, V> {
-    /// Removes empty levels on the top, but keep an empty leaf if the entire tree is empty.
-    fn fix_top(&mut self) {
-        while self.height() > 0 && self.node_as_ref().len() == 0 {
-            self.pop_internal_level();
-        }
-    }
-
-    fn fix_right_border(&mut self) {
-        self.fix_top();
-
-        {
-            let mut cur_node = self.node_as_mut();
-
-            while let Internal(node) = cur_node.force() {
-                let mut last_kv = node.last_kv();
-
-                if last_kv.can_merge() {
-                    cur_node = last_kv.merge().descend();
-                } else {
-                    let right_len = last_kv.reborrow().right_edge().descend().len();
-                    // `MINLEN + 1` to avoid readjust if merge happens on the next level.
-                    if right_len < node::MIN_LEN + 1 {
-                        last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len);
-                    }
-                    cur_node = last_kv.right_edge().descend();
-                }
-            }
-        }
-
-        self.fix_top();
-    }
-
-    /// The symmetric clone of `fix_right_border`.
-    fn fix_left_border(&mut self) {
-        self.fix_top();
-
-        {
-            let mut cur_node = self.node_as_mut();
-
-            while let Internal(node) = cur_node.force() {
-                let mut first_kv = node.first_kv();
-
-                if first_kv.can_merge() {
-                    cur_node = first_kv.merge().descend();
-                } else {
-                    let left_len = first_kv.reborrow().left_edge().descend().len();
-                    if left_len < node::MIN_LEN + 1 {
-                        first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len);
-                    }
-                    cur_node = first_kv.left_edge().descend();
-                }
-            }
-        }
-
-        self.fix_top();
-    }
-}
-
-enum UnderflowResult<'a, K, V> {
-    AtRoot,
-    Merged(Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge>, bool, usize),
-    Stole(bool),
-}
-
-fn handle_underfull_node<'a, K: 'a, V: 'a>(
-    node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>,
-) -> UnderflowResult<'_, K, V> {
-    let parent = match node.ascend() {
-        Ok(parent) => parent,
-        Err(_) => return AtRoot,
-    };
-
-    // Prefer the left KV if it exists. Merging with the left side is faster,
-    // since merging happens towards the left and `node` has fewer elements.
-    // Stealing from the left side is faster, since we can pop from the end of
-    // the KV arrays.
-    let (is_left, mut handle) = match parent.left_kv() {
-        Ok(left) => (true, left),
-        Err(parent) => {
-            let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) };
-            (false, right)
-        }
-    };
-
-    if handle.can_merge() {
-        let offset = if is_left { handle.reborrow().left_edge().descend().len() + 1 } else { 0 };
-        Merged(handle.merge(), is_left, offset)
-    } else {
-        if is_left {
-            handle.steal_left();
-        } else {
-            handle.steal_right();
-        }
-        Stole(is_left)
-    }
-}
-
 impl<K: Ord, V, I: Iterator<Item = (K, V)>> Iterator for MergeIter<K, V, I> {
     type Item = (K, V);
 
diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs
index ecbdacda4b6..bcc50ed5615 100644
--- a/library/alloc/src/collections/btree/mod.rs
+++ b/library/alloc/src/collections/btree/mod.rs
@@ -2,8 +2,10 @@ mod borrow;
 pub mod map;
 mod navigate;
 mod node;
+mod remove;
 mod search;
 pub mod set;
+mod split;
 
 #[doc(hidden)]
 trait Recover<Q: ?Sized> {
diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs
new file mode 100644
index 00000000000..9733b7d6084
--- /dev/null
+++ b/library/alloc/src/collections/btree/remove.rs
@@ -0,0 +1,132 @@
+use super::node::{self, marker, ForceResult, Handle, NodeRef};
+use super::unwrap_unchecked;
+use core::mem;
+use core::ptr;
+
+impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
+    /// Removes a key/value-pair from the map, and returns that pair, as well as
+    /// the leaf edge corresponding to that former pair.
+    pub fn remove_kv_tracking<F: FnOnce()>(
+        self,
+        handle_emptied_internal_root: F,
+    ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
+        let (old_kv, mut pos, was_internal) = match self.force() {
+            ForceResult::Leaf(leaf) => {
+                let (old_kv, pos) = leaf.remove();
+                (old_kv, pos, false)
+            }
+            ForceResult::Internal(mut internal) => {
+                // Replace the location freed in the internal node with an
+                // adjacent KV, and remove that adjacent KV from its leaf.
+                // Always choose the adjacent KV on the left side because
+                // it is typically faster to pop an element from the end
+                // of the KV arrays without needing to shift other elements.
+
+                let key_loc = internal.kv_mut().0 as *mut K;
+                let val_loc = internal.kv_mut().1 as *mut V;
+
+                let to_remove = internal.left_edge().descend().last_leaf_edge().left_kv().ok();
+                let to_remove = unsafe { unwrap_unchecked(to_remove) };
+
+                let (kv, pos) = to_remove.remove();
+
+                let old_key = unsafe { mem::replace(&mut *key_loc, kv.0) };
+                let old_val = unsafe { mem::replace(&mut *val_loc, kv.1) };
+
+                ((old_key, old_val), pos, true)
+            }
+        };
+
+        // Handle underflow
+        let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() };
+        let mut at_leaf = true;
+        while cur_node.len() < node::MIN_LEN {
+            match handle_underfull_node(cur_node) {
+                UnderflowResult::AtRoot => break,
+                UnderflowResult::Merged(edge, merged_with_left, offset) => {
+                    // If we merged with our right sibling then our tracked
+                    // position has not changed. However if we merged with our
+                    // left sibling then our tracked position is now dangling.
+                    if at_leaf && merged_with_left {
+                        let idx = pos.idx() + offset;
+                        let node = match unsafe { ptr::read(&edge).descend().force() } {
+                            ForceResult::Leaf(leaf) => leaf,
+                            ForceResult::Internal(_) => unreachable!(),
+                        };
+                        pos = unsafe { Handle::new_edge(node, idx) };
+                    }
+
+                    let parent = edge.into_node();
+                    if parent.len() == 0 {
+                        // The parent that was just emptied must be the root,
+                        // because nodes on a lower level would not have been
+                        // left with a single child.
+                        handle_emptied_internal_root();
+                        break;
+                    } else {
+                        cur_node = parent.forget_type();
+                        at_leaf = false;
+                    }
+                }
+                UnderflowResult::Stole(stole_from_left) => {
+                    // Adjust the tracked position if we stole from a left sibling
+                    if stole_from_left && at_leaf {
+                        // SAFETY: This is safe since we just added an element to our node.
+                        unsafe {
+                            pos.move_next_unchecked();
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        // If we deleted from an internal node then we need to compensate for
+        // the earlier swap and adjust the tracked position to point to the
+        // next element.
+        if was_internal {
+            pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() };
+        }
+
+        (old_kv, pos)
+    }
+}
+
+enum UnderflowResult<'a, K, V> {
+    AtRoot,
+    Merged(Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::Edge>, bool, usize),
+    Stole(bool),
+}
+
+fn handle_underfull_node<'a, K: 'a, V: 'a>(
+    node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>,
+) -> UnderflowResult<'_, K, V> {
+    let parent = match node.ascend() {
+        Ok(parent) => parent,
+        Err(_) => return UnderflowResult::AtRoot,
+    };
+
+    // Prefer the left KV if it exists. Merging with the left side is faster,
+    // since merging happens towards the left and `node` has fewer elements.
+    // Stealing from the left side is faster, since we can pop from the end of
+    // the KV arrays.
+    let (is_left, mut handle) = match parent.left_kv() {
+        Ok(left) => (true, left),
+        Err(parent) => {
+            let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) };
+            (false, right)
+        }
+    };
+
+    if handle.can_merge() {
+        let offset = if is_left { handle.reborrow().left_edge().descend().len() + 1 } else { 0 };
+        UnderflowResult::Merged(handle.merge(), is_left, offset)
+    } else {
+        if is_left {
+            handle.steal_left();
+        } else {
+            handle.steal_right();
+        }
+        UnderflowResult::Stole(is_left)
+    }
+}
diff --git a/library/alloc/src/collections/btree/split.rs b/library/alloc/src/collections/btree/split.rs
new file mode 100644
index 00000000000..0e6e213f6e8
--- /dev/null
+++ b/library/alloc/src/collections/btree/split.rs
@@ -0,0 +1,104 @@
+use super::node::{self, ForceResult::*, Root};
+use super::search::{self, SearchResult::*};
+use core::borrow::Borrow;
+
+impl<K, V> Root<K, V> {
+    pub fn split_off<Q: ?Sized + Ord>(&mut self, right_root: &mut Self, key: &Q)
+    where
+        K: Borrow<Q>,
+    {
+        debug_assert!(right_root.height() == 0);
+        debug_assert!(right_root.node_as_ref().len() == 0);
+
+        let left_root = self;
+        for _ in 0..left_root.height() {
+            right_root.push_internal_level();
+        }
+
+        {
+            let mut left_node = left_root.node_as_mut();
+            let mut right_node = right_root.node_as_mut();
+
+            loop {
+                let mut split_edge = match search::search_node(left_node, key) {
+                    // key is going to the right tree
+                    Found(handle) => handle.left_edge(),
+                    GoDown(handle) => handle,
+                };
+
+                split_edge.move_suffix(&mut right_node);
+
+                match (split_edge.force(), right_node.force()) {
+                    (Internal(edge), Internal(node)) => {
+                        left_node = edge.descend();
+                        right_node = node.first_edge().descend();
+                    }
+                    (Leaf(_), Leaf(_)) => {
+                        break;
+                    }
+                    _ => unreachable!(),
+                }
+            }
+        }
+
+        left_root.fix_right_border();
+        right_root.fix_left_border();
+    }
+
+    /// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
+    fn fix_top(&mut self) {
+        while self.height() > 0 && self.node_as_ref().len() == 0 {
+            self.pop_internal_level();
+        }
+    }
+
+    fn fix_right_border(&mut self) {
+        self.fix_top();
+
+        {
+            let mut cur_node = self.node_as_mut();
+
+            while let Internal(node) = cur_node.force() {
+                let mut last_kv = node.last_kv();
+
+                if last_kv.can_merge() {
+                    cur_node = last_kv.merge().descend();
+                } else {
+                    let right_len = last_kv.reborrow().right_edge().descend().len();
+                    // `MINLEN + 1` to avoid readjust if merge happens on the next level.
+                    if right_len < node::MIN_LEN + 1 {
+                        last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len);
+                    }
+                    cur_node = last_kv.right_edge().descend();
+                }
+            }
+        }
+
+        self.fix_top();
+    }
+
+    /// The symmetric clone of `fix_right_border`.
+    fn fix_left_border(&mut self) {
+        self.fix_top();
+
+        {
+            let mut cur_node = self.node_as_mut();
+
+            while let Internal(node) = cur_node.force() {
+                let mut first_kv = node.first_kv();
+
+                if first_kv.can_merge() {
+                    cur_node = first_kv.merge().descend();
+                } else {
+                    let left_len = first_kv.reborrow().left_edge().descend().len();
+                    if left_len < node::MIN_LEN + 1 {
+                        first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len);
+                    }
+                    cur_node = first_kv.left_edge().descend();
+                }
+            }
+        }
+
+        self.fix_top();
+    }
+}
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 19f86ced500..92090d8e6fc 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -302,7 +302,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 #[lang = "mul"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented(
-    message = "cannot multiply `{Rhs}` to `{Self}`",
+    message = "cannot multiply `{Self}` by `{Rhs}`",
     label = "no implementation for `{Self} * {Rhs}`"
 )]
 #[doc(alias = "*")]
@@ -826,7 +826,7 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 #[lang = "mul_assign"]
 #[stable(feature = "op_assign_traits", since = "1.8.0")]
 #[rustc_on_unimplemented(
-    message = "cannot multiply-assign `{Rhs}` to `{Self}`",
+    message = "cannot multiply-assign `{Self}` by `{Rhs}`",
     label = "no implementation for `{Self} *= {Rhs}`"
 )]
 #[doc(alias = "*")]
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 9f0284d5d95..b73cd046e5a 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -781,6 +781,34 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     }
 }
 
+impl<T: ?Sized> Pin<&'static T> {
+    /// Get a pinned reference from a static reference.
+    ///
+    /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+    /// never ends.
+    #[unstable(feature = "pin_static_ref", issue = "none")]
+    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+    pub const fn static_ref(r: &'static T) -> Pin<&'static T> {
+        // SAFETY: The 'static borrow guarantees the data will not be
+        // moved/invalidated until it gets dropped (which is never).
+        unsafe { Pin::new_unchecked(r) }
+    }
+}
+
+impl<T: ?Sized> Pin<&'static mut T> {
+    /// Get a pinned mutable reference from a static mutable reference.
+    ///
+    /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+    /// never ends.
+    #[unstable(feature = "pin_static_ref", issue = "none")]
+    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+    pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> {
+        // SAFETY: The 'static borrow guarantees the data will not be
+        // moved/invalidated until it gets dropped (which is never).
+        unsafe { Pin::new_unchecked(r) }
+    }
+}
+
 #[stable(feature = "pin", since = "1.33.0")]
 impl<P: Deref> Deref for Pin<P> {
     type Target = P::Target;
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 02a7362bb3b..b487b399521 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -84,7 +84,7 @@ impl<'a> SourceCollector<'a> {
         };
 
         // Remove the utf-8 BOM if any
-        if contents.starts_with("\u{feff}") {
+        if contents.starts_with('\u{feff}') {
             contents.drain(..3);
         }
 
@@ -99,16 +99,15 @@ impl<'a> SourceCollector<'a> {
             href.push('/');
         });
         self.scx.ensure_dir(&cur)?;
-        let mut fname = p.file_name().expect("source has no filename").to_os_string();
+
+        let src_fname = p.file_name().expect("source has no filename").to_os_string();
+        let mut fname = src_fname.clone();
         fname.push(".html");
         cur.push(&fname);
         href.push_str(&fname.to_string_lossy());
 
-        let title = format!(
-            "{} -- source",
-            cur.file_name().expect("failed to get file name").to_string_lossy()
-        );
-        let desc = format!("Source to the Rust file `{}`.", filename);
+        let title = format!("{} - source", src_fname.to_string_lossy());
+        let desc = format!("Source of the Rust file `{}`.", filename);
         let page = layout::Page {
             title: &title,
             css_class: "source",
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir
index 0d5760b4cd5..88d583b815a 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir
@@ -4,17 +4,17 @@ promoted[0] in FOO: &[&i32; 1] = {
     let mut _0: &[&i32; 1];              // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
     let mut _1: [&i32; 1];               // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
     let mut _2: &i32;                    // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
-    let mut _3: &i32;                    // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+    let mut _3: *const i32;              // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
 
     bb0: {
-        _3 = const {alloc2: &i32};       // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+        _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
                                          // ty::Const
-                                         // + ty: &i32
+                                         // + ty: *const i32
                                          // + val: Value(Scalar(alloc2))
                                          // mir::Constant
                                          // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
-                                         // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) }
-        _2 = _3;                         // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
+                                         // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
+        _2 = &(*_3);                     // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
         _1 = [move _2];                  // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
         _0 = &_1;                        // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
         return;                          // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index a392334e0c9..82277b2a21c 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -7,7 +7,7 @@
       let mut _2: &[&i32; 1];              // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
       let _3: [&i32; 1];                   // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
       let mut _4: &i32;                    // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
-      let _5: &i32;                        // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+      let _5: *const i32;                  // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
 +     let mut _6: &[&i32; 1];              // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
       scope 1 {
       }
@@ -18,16 +18,16 @@
 -         StorageLive(_3);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
 -         StorageLive(_4);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
 -         StorageLive(_5);                 // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
--         _5 = const {alloc2: &i32};       // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+-         _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
 +         _6 = const FOO::promoted[0];     // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
                                            // ty::Const
--                                          // + ty: &i32
+-                                          // + ty: *const i32
 -                                          // + val: Value(Scalar(alloc2))
 +                                          // + ty: &[&i32; 1]
 +                                          // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0]))
                                            // mir::Constant
 -                                          // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
--                                          // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) }
+-                                          // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
 -         _4 = &(*_5);                     // scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
 -         _3 = [move _4];                  // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
 -         _2 = &_3;                        // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
diff --git a/src/test/ui/associated-consts/associated-const-in-trait.stderr b/src/test/ui/associated-consts/associated-const-in-trait.stderr
index a8a8d01ed78..7b459410824 100644
--- a/src/test/ui/associated-consts/associated-const-in-trait.stderr
+++ b/src/test/ui/associated-consts/associated-const-in-trait.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/associated-const-in-trait.rs:9:6
    |
-LL | trait Trait {
-   |       ----- this trait cannot be made into an object...
-LL |     const N: usize;
-   |           - ...because it contains this associated `const`
-...
 LL | impl dyn Trait {
-   |      ^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |      ^^^^^^^^^ `Trait` cannot be made into an object
    |
    = help: consider moving `N` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/associated-const-in-trait.rs:6:11
+   |
+LL | trait Trait {
+   |       ----- this trait cannot be made into an object...
+LL |     const N: usize;
+   |           ^ ...because it contains this associated `const`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr
index 98b545c6e0e..92d74e38cfa 100644
--- a/src/test/ui/associated-item/issue-48027.stderr
+++ b/src/test/ui/associated-item/issue-48027.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-48027.rs:6:6
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     const X: usize;
-   |           - ...because it contains this associated `const`
-...
 LL | impl dyn Bar {}
-   |      ^^^^^^^ the trait `Bar` cannot be made into an object
+   |      ^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `X` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-48027.rs:2:11
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     const X: usize;
+   |           ^ ...because it contains this associated `const`
 
 error[E0283]: type annotations needed
   --> $DIR/issue-48027.rs:3:32
diff --git a/src/test/ui/binop/binop-mul-bool.rs b/src/test/ui/binop/binop-mul-bool.rs
index 27b2f8bb3ff..41494c7a017 100644
--- a/src/test/ui/binop/binop-mul-bool.rs
+++ b/src/test/ui/binop/binop-mul-bool.rs
@@ -1,3 +1,3 @@
-// error-pattern:cannot multiply `bool` to `bool`
+// error-pattern:cannot multiply `bool` by `bool`
 
 fn main() { let x = true * false; }
diff --git a/src/test/ui/binop/binop-mul-bool.stderr b/src/test/ui/binop/binop-mul-bool.stderr
index 859c44a859e..8b5cde63c99 100644
--- a/src/test/ui/binop/binop-mul-bool.stderr
+++ b/src/test/ui/binop/binop-mul-bool.stderr
@@ -1,4 +1,4 @@
-error[E0369]: cannot multiply `bool` to `bool`
+error[E0369]: cannot multiply `bool` by `bool`
   --> $DIR/binop-mul-bool.rs:3:26
    |
 LL | fn main() { let x = true * false; }
diff --git a/src/test/ui/binop/binop-mul-i32-f32.rs b/src/test/ui/binop/binop-mul-i32-f32.rs
new file mode 100644
index 00000000000..d18be51a45f
--- /dev/null
+++ b/src/test/ui/binop/binop-mul-i32-f32.rs
@@ -0,0 +1,5 @@
+fn foo(x: i32, y: f32) -> f32 {
+    x * y //~ ERROR cannot multiply `i32` by `f32`
+}
+
+fn main() {}
diff --git a/src/test/ui/binop/binop-mul-i32-f32.stderr b/src/test/ui/binop/binop-mul-i32-f32.stderr
new file mode 100644
index 00000000000..4a67fe2379b
--- /dev/null
+++ b/src/test/ui/binop/binop-mul-i32-f32.stderr
@@ -0,0 +1,11 @@
+error[E0277]: cannot multiply `i32` by `f32`
+  --> $DIR/binop-mul-i32-f32.rs:2:7
+   |
+LL |     x * y
+   |       ^ no implementation for `i32 * f32`
+   |
+   = help: the trait `Mul<f32>` is not implemented for `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
index cd18a013628..a2b779e2954 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
@@ -1,14 +1,17 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:24
    |
-LL | trait NotObjectSafe { fn eq(&self, other: Self); }
-   |       -------------                       ---- ...because method `eq` references the `Self` type in this parameter
-   |       |
-   |       this trait cannot be made into an object...
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
-   |                        ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
+   |                        ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
    |
    = help: consider moving `eq` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43
+   |
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+   |       -------------                       ^^^^ ...because method `eq` references the `Self` type in this parameter
+   |       |
+   |       this trait cannot be made into an object...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
index a8b160bbb2c..68734cd4ccd 100644
--- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
+++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
@@ -14,9 +14,10 @@ error[E0038]: the trait `Copy` cannot be made into an object
   --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
    |
 LL |     let _: &Copy + 'static;
-   |            ^^^^^ the trait `Copy` cannot be made into an object
+   |            ^^^^^ `Copy` cannot be made into an object
    |
    = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr
index f323a990455..513fda3097c 100644
--- a/src/test/ui/error-codes/E0033-teach.stderr
+++ b/src/test/ui/error-codes/E0033-teach.stderr
@@ -7,15 +7,21 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033-teach.rs:8:20
    |
+LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
+   |                    ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/E0033-teach.rs:4:8
+   |
 LL | trait SomeTrait {
    |       --------- this trait cannot be made into an object...
 LL |     fn foo();
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
-   |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self);
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized;
    |              ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr
index 84481ff16c0..fc1248440d0 100644
--- a/src/test/ui/error-codes/E0033.stderr
+++ b/src/test/ui/error-codes/E0033.stderr
@@ -7,15 +7,21 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033.rs:6:20
    |
+LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
+   |                    ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/E0033.rs:2:8
+   |
 LL | trait SomeTrait {
    |       --------- this trait cannot be made into an object...
 LL |     fn foo();
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
-   |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self);
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized;
    |              ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr
index 638e924b0eb..eb68a6298d1 100644
--- a/src/test/ui/error-codes/E0038.stderr
+++ b/src/test/ui/error-codes/E0038.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/E0038.rs:5:16
    |
-LL | trait Trait {
-   |       ----- this trait cannot be made into an object...
-LL |     fn foo(&self) -> Self;
-   |                      ---- ...because method `foo` references the `Self` type in its return type
-...
 LL | fn call_foo(x: Box<dyn Trait>) {
-   |                ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |                ^^^^^^^^^^^^^^ `Trait` cannot be made into an object
    |
    = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/E0038.rs:2:22
+   |
+LL | trait Trait {
+   |       ----- this trait cannot be made into an object...
+LL |     fn foo(&self) -> Self;
+   |                      ^^^^ ...because method `foo` references the `Self` type in its return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
index e3272e8849f..b61d5604455 100644
--- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
@@ -1,26 +1,35 @@
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
    |
+LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
+   |                                      ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23
+   |
 LL | trait NonObjectSafe1: Sized {}
-   |       --------------  ----- ...because it requires `Self: Sized`
+   |       --------------  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
-   |                                      ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
 
 error[E0038]: the trait `NonObjectSafe2` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36
    |
+LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe2` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:7:8
+   |
 LL | trait NonObjectSafe2 {
    |       -------------- this trait cannot be made into an object...
 LL |     fn static_fn() {}
-   |        --------- ...because associated function `static_fn` has no `self` parameter
-...
-LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object
+   |        ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter
+help: consider turning `static_fn` into a method by giving it a `&self` argument
    |
-help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn static_fn(&self) {}
+   |                  ^^^^^
+help: alternatively, consider constraining `static_fn` so it does not apply to trait objects
    |
 LL |     fn static_fn() where Self: Sized {}
    |                    ^^^^^^^^^^^^^^^^^
@@ -28,39 +37,46 @@ LL |     fn static_fn() where Self: Sized {}
 error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35
    |
-LL | trait NonObjectSafe3 {
-   |       -------------- this trait cannot be made into an object...
-LL |     fn foo<T>(&self);
-   |        --- ...because method `foo` has generic type parameters
-...
 LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
    |
    = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8
+   |
+LL | trait NonObjectSafe3 {
+   |       -------------- this trait cannot be made into an object...
+LL |     fn foo<T>(&self);
+   |        ^^^ ...because method `foo` has generic type parameters
 
 error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35
    |
-LL | trait NonObjectSafe4 {
-   |       -------------- this trait cannot be made into an object...
-LL |     fn foo(&self, &Self);
-   |                   ----- ...because method `foo` references the `Self` type in this parameter
-...
 LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
    |
    = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:15:19
+   |
+LL | trait NonObjectSafe4 {
+   |       -------------- this trait cannot be made into an object...
+LL |     fn foo(&self, &Self);
+   |                   ^^^^^ ...because method `foo` references the `Self` type in this parameter
 
 error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
   --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16
    |
+LL | impl Trait for dyn NonObjectSafe1 {}
+   |                ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23
+   |
 LL | trait NonObjectSafe1: Sized {}
-   |       --------------  ----- ...because it requires `Self: Sized`
+   |       --------------  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL | impl Trait for dyn NonObjectSafe1 {}
-   |                ^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
index 9df5188bbdd..2f3726bdb33 100644
--- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
+++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr
@@ -1,15 +1,21 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13
    |
+LL | fn car() -> dyn NotObjectSafe {
+   |             ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8
+   |
 LL | trait NotObjectSafe {
    |       ------------- this trait cannot be made into an object...
 LL |     fn foo() -> Self;
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL | fn car() -> dyn NotObjectSafe {
-   |             ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self) -> Self;
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() -> Self where Self: Sized;
    |                      ^^^^^^^^^^^^^^^^^
@@ -17,15 +23,21 @@ LL |     fn foo() -> Self where Self: Sized;
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13
    |
+LL | fn cat() -> Box<dyn NotObjectSafe> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8
+   |
 LL | trait NotObjectSafe {
    |       ------------- this trait cannot be made into an object...
 LL |     fn foo() -> Self;
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL | fn cat() -> Box<dyn NotObjectSafe> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self) -> Self;
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() -> Self where Self: Sized;
    |                      ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/inline-const/const-expr-macro.rs b/src/test/ui/inline-const/const-expr-macro.rs
new file mode 100644
index 00000000000..66b58571751
--- /dev/null
+++ b/src/test/ui/inline-const/const-expr-macro.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+#![allow(incomplete_features)]
+#![feature(inline_const)]
+macro_rules! do_const_block{
+    ($val:block) => { const $val }
+}
+
+fn main() {
+    let s = do_const_block!({ 22 });
+    assert_eq!(s, 22);
+}
diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr
index b3ba7aecad0..86b530e85a8 100644
--- a/src/test/ui/issues/issue-18959.stderr
+++ b/src/test/ui/issues/issue-18959.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-18959.rs:11:11
    |
-LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
-   |                    --- ...because method `foo` has generic type parameters
-LL | pub trait Bar: Foo { }
-   |           --- this trait cannot be made into an object...
-...
 LL | fn foo(b: &dyn Bar) {
-   |           ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |           ^^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-18959.rs:1:20
+   |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    ^^^ ...because method `foo` has generic type parameters
+LL | pub trait Bar: Foo { }
+   |           --- this trait cannot be made into an object...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr
index 63f0701974b..c3a5d3dfeee 100644
--- a/src/test/ui/issues/issue-19380.stderr
+++ b/src/test/ui/issues/issue-19380.stderr
@@ -1,15 +1,21 @@
 error[E0038]: the trait `Qiz` cannot be made into an object
   --> $DIR/issue-19380.rs:11:9
    |
+LL |   foos: &'static [&'static (dyn Qiz + 'static)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Qiz` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-19380.rs:2:6
+   |
 LL | trait Qiz {
    |       --- this trait cannot be made into an object...
 LL |   fn qiz();
-   |      --- ...because associated function `qiz` has no `self` parameter
-...
-LL |   foos: &'static [&'static (dyn Qiz + 'static)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
+   |      ^^^ ...because associated function `qiz` has no `self` parameter
+help: consider turning `qiz` into a method by giving it a `&self` argument
    |
-help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |   fn qiz(&self);
+   |          ^^^^^
+help: alternatively, consider constraining `qiz` so it does not apply to trait objects
    |
 LL |   fn qiz() where Self: Sized;
    |            ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr
index 71a013248cf..555d0ff0dc7 100644
--- a/src/test/ui/issues/issue-19538.stderr
+++ b/src/test/ui/issues/issue-19538.stderr
@@ -1,30 +1,34 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:15
    |
+LL |     let test: &mut dyn Bar = &mut thing;
+   |               ^^^^^^^^^^^^ `Bar` cannot be made into an object
+   |
+   = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-19538.rs:2:8
+   |
 LL |     fn foo<T>(&self, val: T);
-   |        --- ...because method `foo` has generic type parameters
+   |        ^^^ ...because method `foo` has generic type parameters
 ...
 LL | trait Bar: Foo { }
    |       --- this trait cannot be made into an object...
-...
-LL |     let test: &mut dyn Bar = &mut thing;
-   |               ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = help: consider moving `foo` to another trait
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:30
    |
+LL |     let test: &mut dyn Bar = &mut thing;
+   |                              ^^^^^^^^^^ `Bar` cannot be made into an object
+   |
+   = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-19538.rs:2:8
+   |
 LL |     fn foo<T>(&self, val: T);
-   |        --- ...because method `foo` has generic type parameters
+   |        ^^^ ...because method `foo` has generic type parameters
 ...
 LL | trait Bar: Foo { }
    |       --- this trait cannot be made into an object...
-...
-LL |     let test: &mut dyn Bar = &mut thing;
-   |                              ^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = help: consider moving `foo` to another trait
    = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
    = note: required by cast to type `&mut dyn Bar`
 
diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr
index 0badf66ba7d..1d7f252e556 100644
--- a/src/test/ui/issues/issue-20692.stderr
+++ b/src/test/ui/issues/issue-20692.stderr
@@ -1,27 +1,32 @@
 error[E0038]: the trait `Array` cannot be made into an object
   --> $DIR/issue-20692.rs:7:5
    |
+LL |     &dyn Array;
+   |     ^^^^^^^^^^ `Array` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-20692.rs:1:14
+   |
 LL | trait Array: Sized + Copy {}
-   |       -----  -----   ---- ...because it requires `Self: Sized`
+   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
    |       |      |
    |       |      ...because it requires `Self: Sized`
    |       this trait cannot be made into an object...
-...
-LL |     &dyn Array;
-   |     ^^^^^^^^^^ the trait `Array` cannot be made into an object
 
 error[E0038]: the trait `Array` cannot be made into an object
   --> $DIR/issue-20692.rs:4:13
    |
+LL |     let _ = x
+   |             ^ `Array` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-20692.rs:1:14
+   |
 LL | trait Array: Sized + Copy {}
-   |       -----  -----   ---- ...because it requires `Self: Sized`
+   |       -----  ^^^^^   ^^^^ ...because it requires `Self: Sized`
    |       |      |
    |       |      ...because it requires `Self: Sized`
    |       this trait cannot be made into an object...
-...
-LL |     let _ = x
-   |             ^ the trait `Array` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T`
    = note: required by cast to type `&dyn Array`
 
diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr
index be438ef9ac7..2c873243fe9 100644
--- a/src/test/ui/issues/issue-26056.stderr
+++ b/src/test/ui/issues/issue-26056.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `Map` cannot be made into an object
   --> $DIR/issue-26056.rs:20:13
    |
+LL |         as &dyn Map<Key=u32,MapValue=u32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-26056.rs:9:12
+   |
 LL | trait Map: MapLookup<<Self as Map>::Key> {
-   |       ---  ----------------------------- ...because it uses `Self` as a type parameter in this
+   |       ---  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-...
-LL |         as &dyn Map<Key=u32,MapValue=u32>;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr
index 658199003c1..203cd0630eb 100644
--- a/src/test/ui/issues/issue-28576.stderr
+++ b/src/test/ui/issues/issue-28576.stderr
@@ -1,16 +1,19 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-28576.rs:7:12
    |
-LL |   pub trait Bar: Foo<Assoc=()> {
-   |             ---  -------------
-   |             |    |   |
-   |             |    |   ...because it uses `Self` as a type parameter in this
-   |             |    ...because it uses `Self` as a type parameter in this
-   |             this trait cannot be made into an object...
-LL |       fn new(&self, b: &
 LL | /            dyn Bar
 LL | |               <Assoc=()>
-   | |________________________^ the trait `Bar` cannot be made into an object
+   | |________________________^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-28576.rs:5:16
+   |
+LL | pub trait Bar: Foo<Assoc=()> {
+   |           ---  ^^^^^^^^^^^^^
+   |           |    |   |
+   |           |    |   ...because it uses `Self` as a type parameter
+   |           |    ...because it uses `Self` as a type parameter
+   |           this trait cannot be made into an object...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-28837.rs b/src/test/ui/issues/issue-28837.rs
index f874b00db0b..9719c3afa68 100644
--- a/src/test/ui/issues/issue-28837.rs
+++ b/src/test/ui/issues/issue-28837.rs
@@ -7,7 +7,7 @@ fn main() {
 
     a - a; //~ ERROR cannot subtract `A` from `A`
 
-    a * a; //~ ERROR cannot multiply `A` to `A`
+    a * a; //~ ERROR cannot multiply `A` by `A`
 
     a / a; //~ ERROR cannot divide `A` by `A`
 
diff --git a/src/test/ui/issues/issue-28837.stderr b/src/test/ui/issues/issue-28837.stderr
index b63e168caf1..07f67bc3de7 100644
--- a/src/test/ui/issues/issue-28837.stderr
+++ b/src/test/ui/issues/issue-28837.stderr
@@ -18,7 +18,7 @@ LL |     a - a;
    |
    = note: an implementation of `std::ops::Sub` might be missing for `A`
 
-error[E0369]: cannot multiply `A` to `A`
+error[E0369]: cannot multiply `A` by `A`
   --> $DIR/issue-28837.rs:10:7
    |
 LL |     a * a;
diff --git a/src/test/ui/issues/issue-35668.rs b/src/test/ui/issues/issue-35668.rs
index 6f6dfb00f86..c970163fcab 100644
--- a/src/test/ui/issues/issue-35668.rs
+++ b/src/test/ui/issues/issue-35668.rs
@@ -1,6 +1,6 @@
 fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> {
     a.iter().map(|a| a*a)
-    //~^ ERROR cannot multiply `&T` to `&T`
+    //~^ ERROR cannot multiply `&T` by `&T`
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-35668.stderr b/src/test/ui/issues/issue-35668.stderr
index 600cacc23ae..81a2bb88c89 100644
--- a/src/test/ui/issues/issue-35668.stderr
+++ b/src/test/ui/issues/issue-35668.stderr
@@ -1,4 +1,4 @@
-error[E0369]: cannot multiply `&T` to `&T`
+error[E0369]: cannot multiply `&T` by `&T`
   --> $DIR/issue-35668.rs:2:23
    |
 LL |     a.iter().map(|a| a*a)
diff --git a/src/test/ui/issues/issue-3820.rs b/src/test/ui/issues/issue-3820.rs
index c0906546232..b987a90b28b 100644
--- a/src/test/ui/issues/issue-3820.rs
+++ b/src/test/ui/issues/issue-3820.rs
@@ -11,5 +11,5 @@ impl Thing {
 fn main() {
     let u = Thing {x: 2};
     let _v = u.mul(&3); // This is ok
-    let w = u * 3; //~ ERROR cannot multiply `{integer}` to `Thing`
+    let w = u * 3; //~ ERROR cannot multiply `Thing` by `{integer}`
 }
diff --git a/src/test/ui/issues/issue-3820.stderr b/src/test/ui/issues/issue-3820.stderr
index 8cc768237a9..84f8f9bd147 100644
--- a/src/test/ui/issues/issue-3820.stderr
+++ b/src/test/ui/issues/issue-3820.stderr
@@ -1,4 +1,4 @@
-error[E0369]: cannot multiply `{integer}` to `Thing`
+error[E0369]: cannot multiply `Thing` by `{integer}`
   --> $DIR/issue-3820.rs:14:15
    |
 LL |     let w = u * 3;
diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr
index 50c5195dc93..d7721d7e69c 100644
--- a/src/test/ui/issues/issue-38404.stderr
+++ b/src/test/ui/issues/issue-38404.stderr
@@ -1,12 +1,16 @@
 error[E0038]: the trait `B` cannot be made into an object
   --> $DIR/issue-38404.rs:3:15
    |
+LL | trait C<T>: A<dyn B<T, Output=usize>> {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-38404.rs:1:13
+   |
 LL | trait A<T>: std::ops::Add<Self> + Sized {}
-   |             ------------------- ...because it uses `Self` as a type parameter in this
+   |             ^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
 LL | trait B<T>: A<T> {}
    |       - this trait cannot be made into an object...
-LL | trait C<T>: A<dyn B<T, Output=usize>> {}
-   |               ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr
index 39a62b81c6c..d41488c15f7 100644
--- a/src/test/ui/issues/issue-38604.stderr
+++ b/src/test/ui/issues/issue-38604.stderr
@@ -1,25 +1,30 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/issue-38604.rs:14:13
    |
+LL |     let _f: Box<dyn Foo> =
+   |             ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-38604.rs:2:22
+   |
 LL | trait Foo where u32: Q<Self> {
-   |       ---            ------- ...because it uses `Self` as a type parameter in this
+   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let _f: Box<dyn Foo> =
-   |             ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/issue-38604.rs:15:9
    |
+LL |         Box::new(());
+   |         ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-38604.rs:2:22
+   |
 LL | trait Foo where u32: Q<Self> {
-   |       ---            ------- ...because it uses `Self` as a type parameter in this
+   |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-...
-LL |         Box::new(());
-   |         ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<()>`
    = note: required by cast to type `Box<dyn Foo>`
 
diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr
index 03e3a7f227a..93bd951d3fa 100644
--- a/src/test/ui/issues/issue-50781.stderr
+++ b/src/test/ui/issues/issue-50781.stderr
@@ -1,10 +1,8 @@
 error: the trait `X` cannot be made into an object
   --> $DIR/issue-50781.rs:6:8
    |
-LL | trait X {
-   |       - this trait cannot be made into an object...
 LL |     fn foo(&self) where Self: Trait;
-   |        ^^^ ...because method `foo` references the `Self` type in its `where` clause
+   |        ^^^
    |
 note: the lint level is defined here
   --> $DIR/issue-50781.rs:1:9
@@ -13,6 +11,13 @@ LL | #![deny(where_clauses_object_safety)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-50781.rs:6:8
+   |
+LL | trait X {
+   |       - this trait cannot be made into an object...
+LL |     fn foo(&self) where Self: Trait;
+   |        ^^^ ...because method `foo` references the `Self` type in its `where` clause
    = help: consider moving `foo` to another trait
 
 error: aborting due to previous error
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index a6fd44d1743..64e56f8c790 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -12,25 +12,30 @@ LL |     take_param(&x);
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/kindck-inherited-copy-bound.rs:28:19
    |
+LL |     let z = &x as &dyn Foo;
+   |                   ^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/kindck-inherited-copy-bound.rs:10:13
+   |
 LL | trait Foo : Copy {
-   |       ---   ---- ...because it requires `Self: Sized`
+   |       ---   ^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let z = &x as &dyn Foo;
-   |                   ^^^^^^^^ the trait `Foo` cannot be made into an object
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/kindck-inherited-copy-bound.rs:28:13
    |
+LL |     let z = &x as &dyn Foo;
+   |             ^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/kindck-inherited-copy-bound.rs:10:13
+   |
 LL | trait Foo : Copy {
-   |       ---   ---- ...because it requires `Self: Sized`
+   |       ---   ^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let z = &x as &dyn Foo;
-   |             ^^ the trait `Foo` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<{integer}>`
    = note: required by cast to type `&dyn Foo`
 
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
index bc7448a05e8..57f7551fd40 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
@@ -12,14 +12,16 @@ LL |     take_param(&x);
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/kindck-inherited-copy-bound.rs:28:13
    |
+LL |     let z = &x as &dyn Foo;
+   |             ^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/kindck-inherited-copy-bound.rs:10:13
+   |
 LL | trait Foo : Copy {
-   |       ---   ---- ...because it requires `Self: Sized`
+   |       ---   ^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let z = &x as &dyn Foo;
-   |             ^^ the trait `Foo` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<i32>`
    = note: required by cast to type `&dyn Foo`
 
diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs
index 12d4826649d..4be7420e33c 100644
--- a/src/test/ui/mismatched_types/binops.rs
+++ b/src/test/ui/mismatched_types/binops.rs
@@ -1,7 +1,7 @@
 fn main() {
     1 + Some(1); //~ ERROR cannot add `Option<{integer}>` to `{integer}`
     2 as usize - Some(1); //~ ERROR cannot subtract `Option<{integer}>` from `usize`
-    3 * (); //~ ERROR cannot multiply `()` to `{integer}`
+    3 * (); //~ ERROR cannot multiply `{integer}` by `()`
     4 / ""; //~ ERROR cannot divide `{integer}` by `&str`
     5 < String::new(); //~ ERROR can't compare `{integer}` with `String`
     6 == Ok(1); //~ ERROR can't compare `{integer}` with `std::result::Result<{integer}, _>`
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index 227c7887fb0..f2bfb12ee9c 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -14,7 +14,7 @@ LL |     2 as usize - Some(1);
    |
    = help: the trait `Sub<Option<{integer}>>` is not implemented for `usize`
 
-error[E0277]: cannot multiply `()` to `{integer}`
+error[E0277]: cannot multiply `{integer}` by `()`
   --> $DIR/binops.rs:4:7
    |
 LL |     3 * ();
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
index 890acde35c4..35ec586892c 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-associated-consts.rs:12:30
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     const X: usize;
-   |           - ...because it contains this associated `const`
-...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `X` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-associated-consts.rs:9:11
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     const X: usize;
+   |           ^ ...because it contains this associated `const`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
index c32038b5a27..d51734ed231 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-associated-consts.rs:14:5
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     const X: usize;
-   |           - ...because it contains this associated `const`
-...
 LL |     t
-   |     ^ the trait `Bar` cannot be made into an object
+   |     ^ `Bar` cannot be made into an object
    |
    = help: consider moving `X` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-associated-consts.rs:9:11
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     const X: usize;
+   |           ^ ...because it contains this associated `const`
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
diff --git a/src/test/ui/object-safety/object-safety-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr
index af454830863..89c4f8ced79 100644
--- a/src/test/ui/object-safety/object-safety-bounds.stderr
+++ b/src/test/ui/object-safety/object-safety-bounds.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `X` cannot be made into an object
   --> $DIR/object-safety-bounds.rs:7:11
    |
+LL | fn f() -> Box<dyn X<U = u32>> {
+   |           ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-bounds.rs:4:13
+   |
 LL | trait X {
    |       - this trait cannot be made into an object...
 LL |     type U: PartialEq<Self>;
-   |             --------------- ...because it uses `Self` as a type parameter in this
-...
-LL | fn f() -> Box<dyn X<U = u32>> {
-   |           ^^^^^^^^^^^^^^^^^^^ the trait `X` cannot be made into an object
+   |             ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr
index 9e70abbd32f..8d6094c5144 100644
--- a/src/test/ui/object-safety/object-safety-generics.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr
@@ -1,28 +1,32 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:18:30
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     fn bar<T>(&self, t: T);
-   |        --- ...because method `bar` has generic type parameters
-...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
-
-error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-generics.rs:24:39
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
    |
 LL | trait Bar {
    |       --- this trait cannot be made into an object...
 LL |     fn bar<T>(&self, t: T);
-   |        --- ...because method `bar` has generic type parameters
-...
+   |        ^^^ ...because method `bar` has generic type parameters
+
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-generics.rs:24:39
+   |
 LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
-   |                                       ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |                                       ^^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
index 7c104fa158d..3d2b2bb228c 100644
--- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -1,30 +1,34 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:20:5
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     fn bar<T>(&self, t: T);
-   |        --- ...because method `bar` has generic type parameters
-...
 LL |     t
-   |     ^ the trait `Bar` cannot be made into an object
+   |     ^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:26:5
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     fn bar<T>(&self, t: T);
-   |        --- ...because method `bar` has generic type parameters
-...
 LL |     t as &dyn Bar
-   |     ^ the trait `Bar` cannot be made into an object
+   |     ^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-generics.rs:10:8
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar<T>(&self, t: T);
+   |        ^^^ ...because method `bar` has generic type parameters
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr
index fe9ca5b6fa4..0262d536246 100644
--- a/src/test/ui/object-safety/object-safety-issue-22040.stderr
+++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `Expr` cannot be made into an object
   --> $DIR/object-safety-issue-22040.rs:12:23
    |
+LL |     elements: Vec<Box<dyn Expr + 'x>>,
+   |                       ^^^^^^^^^^^^^ `Expr` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-issue-22040.rs:5:21
+   |
 LL | trait Expr: Debug + PartialEq {
-   |       ----          --------- ...because it uses `Self` as a type parameter in this
+   |       ----          ^^^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     elements: Vec<Box<dyn Expr + 'x>>,
-   |                       ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
index 4dbb27b425b..336929702e6 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
@@ -1,28 +1,32 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:22:30
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     fn bar(&self, x: &Self);
-   |                      ----- ...because method `bar` references the `Self` type in this parameter
-...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |                              ^^^^^^^^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:11:22
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar(&self, x: &Self);
+   |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
 
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:28:30
    |
-LL | trait Baz {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> Self;
-   |                      ---- ...because method `baz` references the `Self` type in its return type
-...
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
-   |                              ^^^^^^^^ the trait `Baz` cannot be made into an object
+   |                              ^^^^^^^^ `Baz` cannot be made into an object
    |
    = help: consider moving `baz` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:15:22
+   |
+LL | trait Baz {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> Self;
+   |                      ^^^^ ...because method `baz` references the `Self` type in its return type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
index ced26889ba0..6e7896e309c 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -1,30 +1,34 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:24:5
    |
-LL | trait Bar {
-   |       --- this trait cannot be made into an object...
-LL |     fn bar(&self, x: &Self);
-   |                      ----- ...because method `bar` references the `Self` type in this parameter
-...
 LL |     t
-   |     ^ the trait `Bar` cannot be made into an object
+   |     ^ `Bar` cannot be made into an object
    |
    = help: consider moving `bar` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:11:22
+   |
+LL | trait Bar {
+   |       --- this trait cannot be made into an object...
+LL |     fn bar(&self, x: &Self);
+   |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:30:5
    |
-LL | trait Baz {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> Self;
-   |                      ---- ...because method `baz` references the `Self` type in its return type
-...
 LL |     t
-   |     ^ the trait `Baz` cannot be made into an object
+   |     ^ `Baz` cannot be made into an object
    |
    = help: consider moving `baz` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-mentions-Self.rs:15:22
+   |
+LL | trait Baz {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> Self;
+   |                      ^^^^ ...because method `baz` references the `Self` type in its return type
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T`
    = note: required by cast to type `&dyn Baz`
 
diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
index f878cf8b462..e00d6bb2f4a 100644
--- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
@@ -1,15 +1,21 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety-no-static.rs:12:18
    |
+LL | fn diverges() -> Box<dyn Foo> {
+   |                  ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-no-static.rs:9:8
+   |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn foo() {}
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL | fn diverges() -> Box<dyn Foo> {
-   |                  ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self) {}
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized {}
    |              ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
index 8e920697d8f..91a071f5678 100644
--- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -1,17 +1,23 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety-no-static.rs:22:27
    |
+LL |     let b: Box<dyn Foo> = Box::new(Bar);
+   |                           ^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-no-static.rs:9:8
+   |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn foo() {}
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL |     let b: Box<dyn Foo> = Box::new(Bar);
-   |                           ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
+   |        ^^^ ...because associated function `foo` has no `self` parameter
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<Bar>`
    = note: required by cast to type `Box<dyn Foo>`
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self) {}
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized {}
    |              ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
index 2f605d8e904..71236c8e384 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized-2.rs:14:30
    |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+   |                              ^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized-2.rs:9:18
+   |
 LL | trait Bar
    |       --- this trait cannot be made into an object...
 LL |     where Self : Sized
-   |                  ----- ...because it requires `Self: Sized`
-...
-LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
+   |                  ^^^^^ ...because it requires `Self: Sized`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
index cc0463f5d87..b6e4903b079 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -1,14 +1,16 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized-2.rs:16:5
    |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized-2.rs:9:18
+   |
 LL | trait Bar
    |       --- this trait cannot be made into an object...
 LL |     where Self : Sized
-   |                  ----- ...because it requires `Self: Sized`
-...
-LL |     t
-   |     ^ the trait `Bar` cannot be made into an object
-   |
+   |                  ^^^^^ ...because it requires `Self: Sized`
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr
index 54f65c43d9c..94b06ee934d 100644
--- a/src/test/ui/object-safety/object-safety-sized.curr.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized.rs:12:30
    |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+   |                              ^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized.rs:8:13
+   |
 LL | trait Bar : Sized {
-   |       ---   ----- ...because it requires `Self: Sized`
+   |       ---   ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-   |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
index aceacac2db3..645852c7e71 100644
--- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -1,14 +1,16 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized.rs:14:5
    |
+LL |     t
+   |     ^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-sized.rs:8:13
+   |
 LL | trait Bar : Sized {
-   |       ---   ----- ...because it requires `Self: Sized`
+   |       ---   ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     t
-   |     ^ the trait `Bar` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`
 
diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
index ef7f6bacd12..a106ab995b0 100644
--- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
+++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
@@ -1,13 +1,16 @@
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31
    |
+LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+   |                               ^^^^^^^ `Baz` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13
+   |
 LL | trait Baz : Bar<Self> {
-   |       ---   --------- ...because it uses `Self` as a type parameter in this
+   |       ---   ^^^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-...
-LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
-   |                               ^^^^^^^ the trait `Baz` cannot be made into an object
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/pattern-tyvar-2.rs b/src/test/ui/pattern/pattern-tyvar-2.rs
index 532df4fa0cb..7647c766ef9 100644
--- a/src/test/ui/pattern/pattern-tyvar-2.rs
+++ b/src/test/ui/pattern/pattern-tyvar-2.rs
@@ -1,6 +1,6 @@
 enum Bar { T1((), Option<Vec<isize>>), T2, }
 
 fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }
-//~^ ERROR cannot multiply `{integer}` to `Vec<isize>`
+//~^ ERROR cannot multiply `Vec<isize>` by `{integer}`
 
 fn main() { }
diff --git a/src/test/ui/pattern/pattern-tyvar-2.stderr b/src/test/ui/pattern/pattern-tyvar-2.stderr
index e205cd9015e..121817e7056 100644
--- a/src/test/ui/pattern/pattern-tyvar-2.stderr
+++ b/src/test/ui/pattern/pattern-tyvar-2.stderr
@@ -1,4 +1,4 @@
-error[E0369]: cannot multiply `{integer}` to `Vec<isize>`
+error[E0369]: cannot multiply `Vec<isize>` by `{integer}`
   --> $DIR/pattern-tyvar-2.rs:3:71
    |
 LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } }
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index bd6e9d59502..782cfeec4bc 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -2,12 +2,13 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
   --> $DIR/issue-3907-2.rs:11:12
    |
 LL | fn bar(_x: Foo) {}
-   |            ^^^ the trait `issue_3907::Foo` cannot be made into an object
-   | 
-  ::: $DIR/auxiliary/issue-3907.rs:2:8
+   |            ^^^ `issue_3907::Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/auxiliary/issue-3907.rs:2:8
    |
 LL |     fn bar();
-   |        --- the trait cannot be made into an object because associated function `bar` has no `self` parameter
+   |        ^^^ the trait cannot be made into an object because associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
index 85da2c6eeb0..35a65facb57 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -1,31 +1,36 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32
    |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
 LL |     fn foo(self: &Rc<Self>) -> usize;
-   |                  ---------
-   |                  |
-   |                  ...because method `foo`'s `self` parameter cannot be dispatched on
-   |                  help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
+   |                  --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
 ...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
-   |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |                                ^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:8:18
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |                  ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
    |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
 LL |     fn foo(self: &Rc<Self>) -> usize;
-   |                  ---------
-   |                  |
-   |                  ...because method `foo`'s `self` parameter cannot be dispatched on
-   |                  help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
+   |                  --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
 ...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
-   |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |             ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:8:18
    |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |                  ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
    = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
    = note: required by cast to type `Rc<dyn Foo>`
 
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
index c4cde2c3561..a74752cf840 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -1,17 +1,19 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
    |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
 LL |     fn foo(self: &Rc<Self>) -> usize;
-   |                  ---------
-   |                  |
-   |                  ...because method `foo`'s `self` parameter cannot be dispatched on
-   |                  help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
+   |                  --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
 ...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
-   |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |             ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:8:18
    |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |                  ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
    = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
    = note: required by cast to type `Rc<dyn Foo>`
 
diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
index c3cfad70bf4..797406f869f 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr
@@ -1,29 +1,34 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/object-unsafe-trait-references-self.rs:6:11
    |
-LL | trait Trait {
-   |       ----- this trait cannot be made into an object...
-LL |     fn baz(&self, _: Self) {}
-   |                      ---- ...because method `baz` references the `Self` type in this parameter
-LL |     fn bat(&self) -> Self {}
-   |                      ---- ...because method `bat` references the `Self` type in its return type
-...
 LL | fn bar(x: &dyn Trait) {}
-   |           ^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |           ^^^^^^^^^^ `Trait` cannot be made into an object
    |
    = help: consider moving `baz` to another trait
    = help: consider moving `bat` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-references-self.rs:2:22
+   |
+LL | trait Trait {
+   |       ----- this trait cannot be made into an object...
+LL |     fn baz(&self, _: Self) {}
+   |                      ^^^^ ...because method `baz` references the `Self` type in this parameter
+LL |     fn bat(&self) -> Self {}
+   |                      ^^^^ ...because method `bat` references the `Self` type in its return type
 
 error[E0038]: the trait `Other` cannot be made into an object
   --> $DIR/object-unsafe-trait-references-self.rs:10:11
    |
+LL | fn foo(x: &dyn Other) {}
+   |           ^^^^^^^^^^ `Other` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-references-self.rs:8:14
+   |
 LL | trait Other: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-LL | 
-LL | fn foo(x: &dyn Other) {}
-   |           ^^^^^^^^^^ the trait `Other` cannot be made into an object
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr
index 58be59602b9..67491b0446f 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr
@@ -14,12 +14,16 @@ LL |     fn f(a: Self) -> Self;
 error[E0038]: the trait `A` cannot be made into an object
   --> $DIR/object-unsafe-trait-should-use-self.rs:3:13
    |
+LL |     fn f(a: A) -> A;
+   |             ^ `A` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self.rs:2:10
+   |
 LL | trait A: Sized {
-   |       -  ----- ...because it requires `Self: Sized`
+   |       -  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-LL |     fn f(a: A) -> A;
-   |             ^ the trait `A` cannot be made into an object
 
 error: associated item referring to unboxed trait object for its own trait
   --> $DIR/object-unsafe-trait-should-use-self.rs:8:13
@@ -37,14 +41,21 @@ LL |     fn f(a: Self) -> Self;
 error[E0038]: the trait `B` cannot be made into an object
   --> $DIR/object-unsafe-trait-should-use-self.rs:8:13
    |
+LL |     fn f(a: B) -> B;
+   |             ^ `B` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-self.rs:8:8
+   |
 LL | trait B {
    |       - this trait cannot be made into an object...
 LL |     fn f(a: B) -> B;
-   |        -    ^ the trait `B` cannot be made into an object
-   |        |
-   |        ...because associated function `f` has no `self` parameter
+   |        ^ ...because associated function `f` has no `self` parameter
+help: consider turning `f` into a method by giving it a `&self` argument
    |
-help: consider turning `f` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn f(&self, a: B) -> B;
+   |          ^^^^^^
+help: alternatively, consider constraining `f` so it does not apply to trait objects
    |
 LL |     fn f(a: B) -> B where Self: Sized;
    |                     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
index c4b8960b65e..73bb6725f5a 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed
@@ -2,7 +2,7 @@
 #![allow(unused_variables, dead_code)]
 
 trait Trait {
-    fn foo() where Self: Other, Self: Sized, { }
+    fn foo(&self) where Self: Other, Self: Sized, { }
     fn bar(self: &Self) {} //~ ERROR invalid `self` parameter type
 }
 
diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
index 6466a768ecb..a2caf846cc5 100644
--- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
+++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
@@ -1,17 +1,23 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11
    |
+LL | fn bar(x: &dyn Trait) {}
+   |           ^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-unsafe-trait-should-use-where-sized.rs:5:8
+   |
 LL | trait Trait {
    |       ----- this trait cannot be made into an object...
 LL |     fn foo() where Self: Other, { }
-   |        --- ...because associated function `foo` has no `self` parameter
+   |        ^^^ ...because associated function `foo` has no `self` parameter
 LL |     fn bar(self: ()) {}
-   |                  -- ...because method `bar`'s `self` parameter cannot be dispatched on
-...
-LL | fn bar(x: &dyn Trait) {}
-   |           ^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |                  ^^ ...because method `bar`'s `self` parameter cannot be dispatched on
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self) where Self: Other, { }
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Other, Self: Sized, { }
    |                               ^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/issue-72410.stderr b/src/test/ui/traits/issue-72410.stderr
index 1db2320841f..c91d1db4d76 100644
--- a/src/test/ui/traits/issue-72410.stderr
+++ b/src/test/ui/traits/issue-72410.stderr
@@ -1,14 +1,21 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-72410.rs:14:19
    |
+LL |     where for<'a> &'a mut [dyn Bar]: ;
+   |                   ^^^^^^^^^^^^^^^^^ `Bar` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-72410.rs:13:8
+   |
 LL | pub trait Bar {
    |           --- this trait cannot be made into an object...
 LL |     fn map()
-   |        --- ...because associated function `map` has no `self` parameter
-LL |     where for<'a> &'a mut [dyn Bar]: ;
-   |                   ^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
+   |        ^^^ ...because associated function `map` has no `self` parameter
+help: consider turning `map` into a method by giving it a `&self` argument
    |
-help: consider turning `map` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn map(&self)
+   |            ^^^^^
+help: alternatively, consider constraining `map` so it does not apply to trait objects
    |
 LL |     where for<'a> &'a mut [dyn Bar]:, Self: Sized ;
    |                                     ^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
index 1f54e03ee6e..1118a75e085 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr
@@ -2,12 +2,13 @@ error[E0038]: the trait `Eq` cannot be made into an object
   --> $DIR/trait-alias-object-fail.rs:7:13
    |
 LL |     let _: &dyn EqAlias = &123;
-   |             ^^^^^^^^^^^ the trait `Eq` cannot be made into an object
-   | 
-  ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+   |             ^^^^^^^^^^^ `Eq` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
 LL | pub trait Eq: PartialEq<Self> {
-   |               --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this
+   |               ^^^^^^^^^^^^^^^ the trait cannot be made into an object because it uses `Self` as a type parameter
 
 error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
   --> $DIR/trait-alias-object-fail.rs:9:17
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index 3be4f110973..4d97d934376 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -112,23 +112,25 @@ LL |     C::A;
 error[E0038]: the trait `assoc_const::C` cannot be made into an object
   --> $DIR/trait-item-privacy.rs:101:5
    |
+LL |     C::A;
+   |     ^^^^ `assoc_const::C` cannot be made into an object
+   |
+   = help: consider moving `C` to another trait
+   = help: consider moving `B` to another trait
+   = help: consider moving `A` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-item-privacy.rs:25:15
+   |
 LL |         const A: u8 = 0;
-   |               - ...because it contains this associated `const`
+   |               ^ ...because it contains this associated `const`
 ...
 LL |         const B: u8 = 0;
-   |               - ...because it contains this associated `const`
+   |               ^ ...because it contains this associated `const`
 ...
 LL |     pub trait C: A + B {
    |               - this trait cannot be made into an object...
 LL |         const C: u8 = 0;
-   |               - ...because it contains this associated `const`
-...
-LL |     C::A;
-   |     ^^^^ the trait `assoc_const::C` cannot be made into an object
-   |
-   = help: consider moving `C` to another trait
-   = help: consider moving `B` to another trait
-   = help: consider moving `A` to another trait
+   |               ^ ...because it contains this associated `const`
 
 error[E0223]: ambiguous associated type
   --> $DIR/trait-item-privacy.rs:115:12
diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr
index bc567360734..335eeb8f151 100644
--- a/src/test/ui/traits/trait-object-macro-matcher.stderr
+++ b/src/test/ui/traits/trait-object-macro-matcher.stderr
@@ -8,9 +8,10 @@ error[E0038]: the trait `Copy` cannot be made into an object
   --> $DIR/trait-object-macro-matcher.rs:8:8
    |
 LL |     m!(dyn Copy + Send + 'static);
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` cannot be made into an object
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ `Copy` cannot be made into an object
    |
    = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr
index 3fa7c0c484e..16f60962cc1 100644
--- a/src/test/ui/traits/trait-object-safety.stderr
+++ b/src/test/ui/traits/trait-object-safety.stderr
@@ -1,17 +1,23 @@
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:22
    |
+LL |     let _: &dyn Tr = &St;
+   |                      ^^^ `Tr` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-object-safety.rs:4:8
+   |
 LL | trait Tr {
    |       -- this trait cannot be made into an object...
 LL |     fn foo();
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL |     let _: &dyn Tr = &St;
-   |                      ^^^ the trait `Tr` cannot be made into an object
-   |
+   |        ^^^ ...because associated function `foo` has no `self` parameter
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Tr>` for `&St`
    = note: required by cast to type `&dyn Tr`
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+help: consider turning `foo` into a method by giving it a `&self` argument
+   |
+LL |     fn foo(&self);
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized;
    |              ^^^^^^^^^^^^^^^^^
@@ -19,15 +25,21 @@ LL |     fn foo() where Self: Sized;
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:12
    |
+LL |     let _: &dyn Tr = &St;
+   |            ^^^^^^^ `Tr` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-object-safety.rs:4:8
+   |
 LL | trait Tr {
    |       -- this trait cannot be made into an object...
 LL |     fn foo();
-   |        --- ...because associated function `foo` has no `self` parameter
-...
-LL |     let _: &dyn Tr = &St;
-   |            ^^^^^^^ the trait `Tr` cannot be made into an object
+   |        ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
    |
-help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
+LL |     fn foo(&self);
+   |            ^^^^^
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
    |
 LL |     fn foo() where Self: Sized;
    |              ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/trait-resolution-in-overloaded-op.rs b/src/test/ui/traits/trait-resolution-in-overloaded-op.rs
index 28677698516..a9bacc357bc 100644
--- a/src/test/ui/traits/trait-resolution-in-overloaded-op.rs
+++ b/src/test/ui/traits/trait-resolution-in-overloaded-op.rs
@@ -5,7 +5,7 @@ trait MyMul<Rhs, Res> {
 }
 
 fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 {
-    a * b //~ ERROR cannot multiply `f64` to `&T`
+    a * b //~ ERROR cannot multiply `&T` by `f64`
 }
 
 fn main() {}
diff --git a/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr b/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr
index 507d53dc07c..ada76cd8b77 100644
--- a/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr
+++ b/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr
@@ -1,4 +1,4 @@
-error[E0369]: cannot multiply `f64` to `&T`
+error[E0369]: cannot multiply `&T` by `f64`
   --> $DIR/trait-resolution-in-overloaded-op.rs:8:7
    |
 LL |     a * b
diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 0a62f1aeb27..a06f6a49194 100644
--- a/src/test/ui/traits/trait-test-2.stderr
+++ b/src/test/ui/traits/trait-test-2.stderr
@@ -13,32 +13,36 @@ LL |     10.blah::<i32, i32>();
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/trait-test-2.rs:11:16
    |
-LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
-   |       ---                    ----     ---- ...because method `blah` has generic type parameters
-   |       |                      |
-   |       |                      ...because method `dup` references the `Self` type in its return type
-   |       this trait cannot be made into an object...
-...
 LL |     (box 10 as Box<dyn bar>).dup();
-   |                ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
+   |                ^^^^^^^^^^^^ `bar` cannot be made into an object
    |
    = help: consider moving `dup` to another trait
    = help: consider moving `blah` to another trait
-
-error[E0038]: the trait `bar` cannot be made into an object
-  --> $DIR/trait-test-2.rs:11:6
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-test-2.rs:4:30
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
-   |       ---                    ----     ---- ...because method `blah` has generic type parameters
+   |       ---                    ^^^^     ^^^^ ...because method `blah` has generic type parameters
    |       |                      |
    |       |                      ...because method `dup` references the `Self` type in its return type
    |       this trait cannot be made into an object...
-...
+
+error[E0038]: the trait `bar` cannot be made into an object
+  --> $DIR/trait-test-2.rs:11:6
+   |
 LL |     (box 10 as Box<dyn bar>).dup();
-   |      ^^^^^^ the trait `bar` cannot be made into an object
+   |      ^^^^^^ `bar` cannot be made into an object
    |
    = help: consider moving `dup` to another trait
    = help: consider moving `blah` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/trait-test-2.rs:4:30
+   |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |       ---                    ^^^^     ^^^^ ...because method `blah` has generic type parameters
+   |       |                      |
+   |       |                      ...because method `dup` references the `Self` type in its return type
+   |       this trait cannot be made into an object...
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn bar>>` for `Box<{integer}>`
    = note: required by cast to type `Box<dyn bar>`
 
diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
index 539189982a8..2de5f6eb0f0 100644
--- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
+++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
@@ -13,15 +13,17 @@ LL |     let y = x as dyn MyAdd<i32>;
 error[E0038]: the trait `MyAdd` cannot be made into an object
   --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
    |
-LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
-   |       -----                                           ---- ...because method `add` references the `Self` type in its return type
-   |       |
-   |       this trait cannot be made into an object...
-...
 LL |     let y = x as dyn MyAdd<i32>;
-   |                  ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
+   |                  ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object
    |
    = help: consider moving `add` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55
+   |
+LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+   |       -----                                           ^^^^ ...because method `add` references the `Self` type in its return type
+   |       |
+   |       this trait cannot be made into an object...
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
index e707839a97e..29dfb585ac6 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -1,42 +1,48 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
    |
+LL |     let t_box: Box<dyn Trait> = Box::new(S);
+   |                                 ^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let t_box: Box<dyn Trait> = Box::new(S);
-   |                                 ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
    = note: required by cast to type `Box<dyn Trait>`
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
    |
+LL |     takes_box(Box::new(S));
+   |               ^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     takes_box(Box::new(S));
-   |               ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
    = note: required by cast to type `Box<(dyn Trait + 'static)>`
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
    |
+LL |     Box::new(S) as Box<dyn Trait>;
+   |     ^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     Box::new(S) as Box<dyn Trait>;
-   |     ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
    = note: required by cast to type `Box<dyn Trait>`
 
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
index 08d4808b77d..02169f26f90 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -1,42 +1,48 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
    |
+LL |     let t: &dyn Trait = &S;
+   |                         ^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let t: &dyn Trait = &S;
-   |                         ^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
    |
+LL |     takes_trait(&S);
+   |                 ^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     takes_trait(&S);
-   |                 ^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
    |
+LL |     &S as &dyn Trait;
+   |     ^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     &S as &dyn Trait;
-   |     ^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
    = note: required by cast to type `&dyn Trait`
 
diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr
index e7921f3496c..988cb2fa548 100644
--- a/src/test/ui/wf/wf-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-fn-where-clause.stderr
@@ -34,9 +34,10 @@ error[E0038]: the trait `Copy` cannot be made into an object
   --> $DIR/wf-fn-where-clause.rs:12:16
    |
 LL | fn bar() where Vec<dyn Copy>:, {}
-   |                ^^^^^^^^^^^^^ the trait `Copy` cannot be made into an object
+   |                ^^^^^^^^^^^^^ `Copy` cannot be made into an object
    |
    = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr
index 8935d766354..9b749f88fb8 100644
--- a/src/test/ui/wf/wf-object-safe.stderr
+++ b/src/test/ui/wf/wf-object-safe.stderr
@@ -1,15 +1,17 @@
 error[E0038]: the trait `A` cannot be made into an object
   --> $DIR/wf-object-safe.rs:9:13
    |
-LL | trait A {
-   |       - this trait cannot be made into an object...
-LL |     fn foo(&self, _x: &Self);
-   |                       ----- ...because method `foo` references the `Self` type in this parameter
-...
 LL |     let _x: &dyn A;
-   |             ^^^^^^ the trait `A` cannot be made into an object
+   |             ^^^^^^ `A` cannot be made into an object
    |
    = help: consider moving `foo` to another trait
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-object-safe.rs:5:23
+   |
+LL | trait A {
+   |       - this trait cannot be made into an object...
+LL |     fn foo(&self, _x: &Self);
+   |                       ^^^^^ ...because method `foo` references the `Self` type in this parameter
 
 error: aborting due to previous error
 
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 d0f43f800fd..9dbd41ca368 100644
--- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -15,28 +15,32 @@ LL | |     }
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-unsafe-trait-obj-match.rs:26:21
    |
+LL |         Some(()) => &S,
+   |                     ^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-unsafe-trait-obj-match.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |         Some(()) => &S,
-   |                     ^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/wf-unsafe-trait-obj-match.rs:25:25
    |
+LL |     let t: &dyn Trait = match opt() {
+   |                         ^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/wf-unsafe-trait-obj-match.rs:6:14
+   |
 LL | trait Trait: Sized {}
-   |       -----  ----- ...because it requires `Self: Sized`
+   |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-...
-LL |     let t: &dyn Trait = match opt() {
-   |                         ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
    = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&R`
    = note: required by cast to type `&dyn Trait`