Skip to content

Commit 7a6b52b

Browse files
RPITITs are considered object-safe, they're always on Self:Sized methods
1 parent 361f8ba commit 7a6b52b

File tree

6 files changed

+38
-18
lines changed

6 files changed

+38
-18
lines changed

compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
354354
// FIXME(associated_const_equality): Also add associated consts to
355355
// the requirements here.
356356
if item.kind == ty::AssocKind::Type {
357+
// RPITITs are not checked here, since they are not (currently) object-safe
358+
// and cannot be named from a non-`Self: Sized` method.
359+
if item.is_impl_trait_in_trait() {
360+
continue;
361+
}
362+
357363
requirements
358364
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args));
359365
}

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
535535
let assoc_types: Vec<_> = tcx
536536
.associated_items(trait_predicate.def_id())
537537
.in_definition_order()
538+
// RPITITs are not checked here, since they are not (currently) object-safe
539+
// and cannot be named from a non-`Self: Sized` method.
540+
.filter(|item| !item.is_impl_trait_in_trait())
538541
.filter_map(
539542
|item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
540543
)

tests/ui/impl-trait/in-trait/issue-102140.stderr

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ LL | MyTrait::foo(&self)
66
| |
77
| required by a bound introduced by this call
88
|
9-
= help: the trait `MyTrait` is implemented for `Outer`
9+
help: consider removing the leading `&`-reference
10+
|
11+
LL - MyTrait::foo(&self)
12+
LL + MyTrait::foo(self)
13+
|
1014

1115
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
1216
--> $DIR/issue-102140.rs:23:9
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// check-pass
2+
// revisions: current next
3+
//[next] compile-flags: -Ztrait-solver=next
4+
5+
#![feature(return_position_impl_trait_in_trait)]
6+
7+
fn main() {
8+
let vec: Vec<Box<dyn Trait>> = Vec::new();
9+
10+
for i in vec {
11+
i.fn_2();
12+
}
13+
}
14+
15+
trait OtherTrait {}
16+
17+
trait Trait {
18+
fn fn_1(&self) -> impl OtherTrait
19+
where
20+
Self: Sized;
21+
22+
fn fn_2(&self) -> bool;
23+
}

tests/ui/impl-trait/in-trait/object-safety.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,4 @@ fn main() {
1919
//~| ERROR the trait `Foo` cannot be made into an object
2020
let s = i.baz();
2121
//~^ ERROR the trait `Foo` cannot be made into an object
22-
//~| ERROR the trait `Foo` cannot be made into an object
2322
}

tests/ui/impl-trait/in-trait/object-safety.stderr

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,6 @@ LL | fn baz(&self) -> impl Debug;
1313
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
1414
= help: consider moving `baz` to another trait
1515

16-
error[E0038]: the trait `Foo` cannot be made into an object
17-
--> $DIR/object-safety.rs:20:15
18-
|
19-
LL | let s = i.baz();
20-
| ^^^ `Foo` cannot be made into an object
21-
|
22-
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>
23-
--> $DIR/object-safety.rs:7:22
24-
|
25-
LL | trait Foo {
26-
| --- this trait cannot be made into an object...
27-
LL | fn baz(&self) -> impl Debug;
28-
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
29-
= help: consider moving `baz` to another trait
30-
3116
error[E0038]: the trait `Foo` cannot be made into an object
3217
--> $DIR/object-safety.rs:20:13
3318
|
@@ -59,6 +44,6 @@ LL | fn baz(&self) -> impl Debug;
5944
= help: consider moving `baz` to another trait
6045
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
6146

62-
error: aborting due to 4 previous errors
47+
error: aborting due to 3 previous errors
6348

6449
For more information about this error, try `rustc --explain E0038`.

0 commit comments

Comments
 (0)