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 c47767101a4..60f5084adc1 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 { + // RPITITs are not checked here, since they are not (currently) object-safe + // and cannot be named from a non-`Self: Sized` method. + if item.is_impl_trait_in_trait() { + 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 8a24f96743a..f2b546c3956 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 @@ fn confirm_object_candidate( let assoc_types: Vec<_> = tcx .associated_items(trait_predicate.def_id()) .in_definition_order() + // RPITITs are not checked here, since they are not (currently) object-safe + // and cannot be named from a non-`Self: Sized` method. + .filter(|item| !item.is_impl_trait_in_trait()) .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 5d55b9fa4f9..18bb63745d7 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 00000000000..f221cfbb176 --- /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/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs index 9a231e59b09..dd35b9a2d8a 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.rs +++ b/tests/ui/impl-trait/in-trait/object-safety.rs @@ -19,5 +19,4 @@ fn main() { //~| ERROR the trait `Foo` cannot be made into an object let s = i.baz(); //~^ ERROR the trait `Foo` cannot be made into an object - //~| ERROR the trait `Foo` cannot be made into an object } diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr index 0170dc5d0fc..4a3b3b11465 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.stderr @@ -13,21 +13,6 @@ LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:15 - | -LL | let s = i.baz(); - | ^^^ `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 - --> $DIR/object-safety.rs:7:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety.rs:20:13 | @@ -59,6 +44,6 @@ LL | fn baz(&self) -> impl Debug; = help: consider moving `baz` to another trait = note: required for the cast from `Box` to `Box` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`.