about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-10-15 17:23:45 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-10-20 09:26:14 -0700
commitae0e3d051178193aec39cb7ea8110301339b3e44 (patch)
tree0fe1ab087d84a3baaef9565cb6c836e4191ef2f2
parent9832374f6e378971e1a933362cf9781b121bb845 (diff)
downloadrust-ae0e3d051178193aec39cb7ea8110301339b3e44.tar.gz
rust-ae0e3d051178193aec39cb7ea8110301339b3e44.zip
Tweak "object unsafe" errors
Fix #77598.
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs37
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs74
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs70
-rw-r--r--src/test/ui/associated-consts/associated-const-in-trait.stderr12
-rw-r--r--src/test/ui/associated-item/issue-48027.stderr12
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr11
-rw-r--r--src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr1
-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.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr62
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr32
-rw-r--r--src/test/ui/issues/issue-18959.stderr12
-rw-r--r--src/test/ui/issues/issue-19380.stderr16
-rw-r--r--src/test/ui/issues/issue-19538.stderr26
-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.stderr17
-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/object-safety/object-safety-associated-consts.curr.stderr12
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr12
-rw-r--r--src/test/ui/object-safety/object-safety-bounds.stderr11
-rw-r--r--src/test/ui/object-safety/object-safety-generics.curr.stderr24
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr24
-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.stderr24
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr24
-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/resolve/issue-3907-2.stderr7
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr29
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr14
-rw-r--r--src/test/ui/suggestions/object-unsafe-trait-references-self.stderr27
-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.stderr7
-rw-r--r--src/test/ui/traits/trait-item-privacy.stderr22
-rw-r--r--src/test/ui/traits/trait-object-macro-matcher.stderr1
-rw-r--r--src/test/ui/traits/trait-object-safety.stderr34
-rw-r--r--src/test/ui/traits/trait-test-2.stderr26
-rw-r--r--src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr12
-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.stderr1
-rw-r--r--src/test/ui/wf/wf-object-safe.stderr12
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr24
57 files changed, 699 insertions, 421 deletions
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index f873358ff9f..63cfdbd170a 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> {
@@ -57,7 +57,8 @@ pub fn report_object_safety_error(
     err.span_label(span, format!("the trait `{}` 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/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 1dd6d590d90..f21dc71d224 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;
@@ -652,7 +653,7 @@ impl ObjectSafetyViolation {
                         .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_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 0e43f1655dd..a170d963c5c 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;
@@ -112,33 +112,35 @@ fn object_safety_violations_for_trait(
                             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(
+                        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...",
+                                "this trait cannot be made into an object...".into(),
+                            );
+                            spans.push_span_label(
+                                *span,
+                                format!("...because {}", violation.error_msg()),
                             );
-                            format!("...because {}", violation.error_msg())
                         } else {
-                            format!(
-                                "the trait cannot be made into an object because {}",
-                                violation.error_msg()
-                            )
+                            spans.push_span_label(
+                                *span,
+                                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.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();
                     },
@@ -385,6 +387,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 +399,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/src/test/ui/associated-consts/associated-const-in-trait.stderr b/src/test/ui/associated-consts/associated-const-in-trait.stderr
index a8a8d01ed78..e9d3947543e 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
    |
    = 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..43e4374797c 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
    |
    = 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/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
index cd18a013628..7b1f6e58f21 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
    |
    = 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..94efa2b3f64 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
@@ -17,6 +17,7 @@ LL |     let _: &Copy + 'static;
    |            ^^^^^ the trait `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..8647eebc6be 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;
+   |                    ^^^^^^^^^^^^^^ the trait `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..dfc30200980 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;
+   |                    ^^^^^^^^^^^^^^ the trait `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..bb8a7ced7ae 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
    |
    = 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..a5961b5288c 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) {
+   |                                      ^^^^^^^^^^^^^^^^^^^ the trait `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 {
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `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
    |
    = 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
    |
    = 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 {}
+   |                ^^^^^^^^^^^^^^^^^^ the trait `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..2d58b12bfb1 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 {
+   |             ^^^^^^^^^^^^^^^^^ the trait `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> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^ the trait `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/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr
index b3ba7aecad0..2be8c6188bd 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
    |
    = 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..73e329f8d95 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)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `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..c2421970ca2 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 |     fn foo<T>(&self, val: T);
-   |        --- ...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
+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...
-...
+
+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;
    |                              ^^^^^^^^^^ the trait `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
+...
+LL | trait Bar: Foo { }
+   |       --- this trait cannot be made into an object...
    = 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..241e1b51793 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;
+   |     ^^^^^^^^^^ the trait `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
+   |             ^ the trait `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..ba1ec67dfca 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>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `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 in this
    |       |
    |       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..726982d1772 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
+   |
+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 in this
+   |           |    ...because it uses `Self` as a type parameter in this
+   |           this trait cannot be made into an object...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr
index 50c5195dc93..b814f0a3273 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>> {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^ the trait `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 in this
 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..87c873ae35f 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> =
+   |             ^^^^^^^^^^^^ the trait `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 in this
    |       |
    |       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 | trait Foo where u32: Q<Self> {
-   |       ---            ------- ...because it uses `Self` as a type parameter in this
-   |       |
-   |       this trait cannot be made into an object...
-...
 LL |         Box::new(());
    |         ^^^^^^^^^^^^ the trait `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
+   |       |
+   |       this trait 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..3ec3900d883 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;
+   |                   ^^^^^^^^ the trait `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 | trait Foo : Copy {
-   |       ---   ---- ...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: 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`
+   |       |
+   |       this trait 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..14ef610685e 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 | trait Foo : Copy {
-   |       ---   ---- ...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: 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`
+   |       |
+   |       this trait 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/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
index 890acde35c4..ed7200bc620 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
    |
    = 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..97310adee9b 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
    |
    = 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..3f8ed31f1ae 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>> {
+   |           ^^^^^^^^^^^^^^^^^^^ the trait `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 in this
 
 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..f18ac4c813f 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
    |
    = 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
    |
    = 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..62e1dc89543 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
    |
    = 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
    |
    = 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..63b45e25884 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>>,
+   |                       ^^^^^^^^^^^^^ the trait `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 in this
    |       |
    |       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..2d8de311930 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
    |
    = 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
    |
    = 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..3b26ce4eac4 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
    |
    = 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
    |
    = 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..5b42cb55b84 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> {
+   |                  ^^^^^^^^^^^^ the trait `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..5bff24224af 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 | 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
    |
+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
    = 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..eb1fa261636 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 {
+   |                              ^^^^^^^^ the trait `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..eb03763f3e7 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 | 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
    |
+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`
    = 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..fa07501b118 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 {
+   |                              ^^^^^^^^ the trait `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..9ce6ae8022c 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 | trait Bar : 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: 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`
+   |       |
+   |       this trait 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..57435028043 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 {
+   |                               ^^^^^^^ the trait `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 in this
    |       |
    |       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/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index bd6e9d59502..b8a7f3b9742 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -3,11 +3,12 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
 LL | fn bar(_x: Foo) {}
    |            ^^^ the trait `issue_3907::Foo` cannot be made into an object
-   | 
-  ::: $DIR/auxiliary/issue-3907.rs:2:8
+   |
+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..4ea5dae2ec9 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
+   |
+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
    |
+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..9d658e7ac41 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
    |
+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..94f8398a786 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
    |
    = 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) {}
+   |           ^^^^^^^^^^ the trait `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..ee44cec318b 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;
+   |             ^ the trait `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;
+   |             ^ the trait `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..3ea9a516140 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) {}
+   |           ^^^^^^^^^^ the 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..c70fbb3565e 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]: ;
+   |                   ^^^^^^^^^^^^^^^^^ the trait `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..a6e54d42aa7 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
@@ -3,11 +3,12 @@ error[E0038]: the trait `Eq` cannot be made into an object
    |
 LL |     let _: &dyn EqAlias = &123;
    |             ^^^^^^^^^^^ the trait `Eq` cannot be made into an object
-   | 
-  ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+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 in this
 
 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..c7143e5e253 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;
+   |     ^^^^ 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
+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..af2989ae188 100644
--- a/src/test/ui/traits/trait-object-macro-matcher.stderr
+++ b/src/test/ui/traits/trait-object-macro-matcher.stderr
@@ -11,6 +11,7 @@ LL |     m!(dyn Copy + Send + 'static);
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `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..5f034e2a9ef 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 | 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
    |
+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
    = 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;
+   |            ^^^^^^^ the trait `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-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 0a62f1aeb27..0fab29f89c4 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
    |
    = 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
    |
    = 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..c9a5297c42f 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
    |
    = 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..6eadcbac6bd 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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..bb4899ee162 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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..bd10d453576 100644
--- a/src/test/ui/wf/wf-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-fn-where-clause.stderr
@@ -37,6 +37,7 @@ LL | fn bar() where Vec<dyn Copy>:, {}
    |                ^^^^^^^^^^^^^ the trait `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..b5e30afe880 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
    |
    = 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..58ca092433b 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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 | trait Trait: 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: 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`
+   |       |
+   |       this 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`