RPITITs are considered object-safe, they're always on Self:Sized methods
This commit is contained in:
parent
361f8ba847
commit
7a6b52bf0d
@ -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));
|
||||
}
|
||||
|
@ -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 },
|
||||
)
|
||||
|
@ -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
|
||||
|
23
tests/ui/impl-trait/in-trait/object-safety-sized.rs
Normal file
23
tests/ui/impl-trait/in-trait/object-safety-sized.rs
Normal file
@ -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<Box<dyn Trait>> = 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;
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $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<u32>` to `Box<dyn Foo>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
||||
|
Loading…
Reference in New Issue
Block a user