diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 8ceefb0abf03..08b980480c57 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::>(), ), _ => 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 28fb4f36115f..1ab33261111f 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: &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 06ecfd019c84..fa1c89575198 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`