about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/traits/object_safety.rs39
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.curr.stderr5
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr4
3 files changed, 41 insertions, 7 deletions
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 8ceefb0abf0..08b980480c5 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -234,17 +234,48 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]>
     tcx.hir()
         .get_if_local(trait_def_id)
         .and_then(|node| match node {
-            hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => Some(
-                bounds
+            hir::Node::Item(hir::Item {
+                kind: hir::ItemKind::Trait(.., generics, bounds, _),
+                ..
+            }) => Some(
+                generics
+                    .where_clause
+                    .predicates
                     .iter()
-                    .filter_map(|b| match b {
+                    .filter_map(|pred| {
+                        match pred {
+                            hir::WherePredicate::BoundPredicate(pred)
+                                if pred.bounded_ty.hir_id.owner_def_id() == trait_def_id =>
+                            {
+                                // Fetch spans for trait bounds that are Sized:
+                                // `trait T where Self: Pred`
+                                Some(pred.bounds.iter().filter_map(|b| match b {
+                                    hir::GenericBound::Trait(
+                                        trait_ref,
+                                        hir::TraitBoundModifier::None,
+                                    ) if trait_has_sized_self(
+                                        tcx,
+                                        trait_ref.trait_ref.trait_def_id(),
+                                    ) =>
+                                    {
+                                        Some(trait_ref.span)
+                                    }
+                                    _ => None,
+                                }))
+                            }
+                            _ => None,
+                        }
+                    })
+                    .flatten()
+                    .chain(bounds.iter().filter_map(|b| match b {
                         hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
                             if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) =>
                         {
+                            // Fetch spans for supertraits that are `Sized`: `trait T: Super`
                             Some(trait_ref.span)
                         }
                         _ => None,
-                    })
+                    }))
                     .collect::<SmallVec<[Span; 1]>>(),
             ),
             _ => None,
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 28fb4f36115..1ab33261111 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,10 +1,11 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized-2.rs:14:30
    |
+LL |     where Self : Sized
+   |                  ----- the trait cannot require that `Self : Sized`
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                              ^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: the trait cannot require that `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 06ecfd019c8..fa1c8957519 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,10 +1,12 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-sized-2.rs:16:5
    |
+LL |     where Self : Sized
+   |                  ----- the trait cannot require that `Self : Sized`
+...
 LL |     t
    |     ^ the trait `Bar` cannot be made into an object
    |
-   = note: the trait cannot require that `Self : Sized`
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T`
    = note: required by cast to type `&dyn Bar`