diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index c47767101a466..b61e02ba76106 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -354,6 +354,12 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( // FIXME(associated_const_equality): Also add associated consts to // the requirements here. if item.kind == ty::AssocKind::Type { + // associated types that require `Self: Sized` do not show up in the built-in + // implementation of `Trait for dyn Trait`, and can be dropped here. + if tcx.generics_require_sized_self(item.def_id) { + continue; + } + requirements .extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args)); } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8a24f96743a6a..eadac70057cd8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -535,6 +535,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let assoc_types: Vec<_> = tcx .associated_items(trait_predicate.def_id()) .in_definition_order() + // Associated types that require `Self: Sized` do not show up in the built-in + // implementation of `Trait for dyn Trait`, and can be dropped here. + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .filter_map( |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None }, ) diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.stderr index 5d55b9fa4f999..18bb63745d7a5 100644 --- a/tests/ui/impl-trait/in-trait/issue-102140.stderr +++ b/tests/ui/impl-trait/in-trait/issue-102140.stderr @@ -6,7 +6,11 @@ LL | MyTrait::foo(&self) | | | required by a bound introduced by this call | - = help: the trait `MyTrait` is implemented for `Outer` +help: consider removing the leading `&`-reference + | +LL - MyTrait::foo(&self) +LL + MyTrait::foo(self) + | error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied --> $DIR/issue-102140.rs:23:9 diff --git a/tests/ui/impl-trait/in-trait/object-safety-sized.rs b/tests/ui/impl-trait/in-trait/object-safety-sized.rs new file mode 100644 index 0000000000000..f221cfbb17665 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/object-safety-sized.rs @@ -0,0 +1,23 @@ +// check-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +#![feature(return_position_impl_trait_in_trait)] + +fn main() { + let vec: Vec> = Vec::new(); + + for i in vec { + i.fn_2(); + } +} + +trait OtherTrait {} + +trait Trait { + fn fn_1(&self) -> impl OtherTrait + where + Self: Sized; + + fn fn_2(&self) -> bool; +} diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs index cf5345b1c1dca..d59fc1712ea7e 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.rs +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.rs @@ -1,6 +1,5 @@ -//! This test checks that even if some associated types have -//! `where Self: Sized` bounds, those without still need to be -//! mentioned in trait objects. +//! This test checks that associated types with `Self: Sized` cannot be projected +//! from a `dyn Trait`. trait Bop { type Bar: Default @@ -16,5 +15,4 @@ fn bop() { fn main() { bop::(); - //~^ ERROR: the size for values of type `dyn Bop` cannot be known at compilation time } diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr index 6b5bc3603491e..224d33fb2da18 100644 --- a/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr +++ b/tests/ui/object-safety/assoc_type_bounds_sized_used.stderr @@ -1,5 +1,5 @@ error[E0599]: the function or associated item `default` exists for associated type `::Bar`, but its trait bounds were not satisfied - --> $DIR/assoc_type_bounds_sized_used.rs:12:30 + --> $DIR/assoc_type_bounds_sized_used.rs:11:30 | LL | let _ = ::Bar::default(); | ^^^^^^^ function or associated item cannot be called on `::Bar` due to unsatisfied trait bounds @@ -13,7 +13,7 @@ LL | fn bop() where T: Sized { | ++++++++++++++ error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/assoc_type_bounds_sized_used.rs:12:14 + --> $DIR/assoc_type_bounds_sized_used.rs:11:14 | LL | fn bop() { | - this type parameter needs to be `Sized` @@ -21,7 +21,7 @@ LL | let _ = ::Bar::default(); | ^ doesn't have a size known at compile-time | note: required by a bound in `Bop::Bar` - --> $DIR/assoc_type_bounds_sized_used.rs:8:15 + --> $DIR/assoc_type_bounds_sized_used.rs:7:15 | LL | type Bar: Default | --- required by a bound in this associated type @@ -34,20 +34,7 @@ LL - fn bop() { LL + fn bop() { | -error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time - --> $DIR/assoc_type_bounds_sized_used.rs:18:11 - | -LL | bop::(); - | ^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Bop` -note: required by a bound in `bop` - --> $DIR/assoc_type_bounds_sized_used.rs:11:11 - | -LL | fn bop() { - | ^^^ required by this bound in `bop` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs new file mode 100644 index 0000000000000..0b30a88fdd42c --- /dev/null +++ b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs @@ -0,0 +1,25 @@ +// check-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +trait Foo { + type Bar<'a> + where + Self: Sized; + + fn test(&self); +} + +impl Foo for () { + type Bar<'a> = () where Self: Sized; + + fn test(&self) {} +} + +fn test(x: &dyn Foo) { + x.test(); +} + +fn main() { + test(&()); +}