Auto merge of #115467 - compiler-errors:assoc-ty-object-safety, r=oli-obk
Do not require associated types with Self: Sized to uphold bounds when confirming object candidate RPITITs and associated types that have `Self: Sized` bounds are opted out of the `dyn Trait` well-formedness check that happens during confirmation. This ensures that we can actually *use* `dyn Trait`s that have associated types that, e.g., have GATs and RPITITs and other naughty things as long as those are opted-out of object safety via a `Self: Sized` bound. Fixes #115464 This seems like a natural part of https://github.com/rust-lang/rust/pull/112319#issuecomment-1592574451, and I don't think needs re-litigation. r? `@oli-obk`
This commit is contained in:
commit
9c609ae158
@ -354,6 +354,12 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
|
|||||||
// FIXME(associated_const_equality): Also add associated consts to
|
// FIXME(associated_const_equality): Also add associated consts to
|
||||||
// the requirements here.
|
// the requirements here.
|
||||||
if item.kind == ty::AssocKind::Type {
|
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
|
requirements
|
||||||
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args));
|
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args));
|
||||||
}
|
}
|
||||||
|
@ -535,6 +535,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let assoc_types: Vec<_> = tcx
|
let assoc_types: Vec<_> = tcx
|
||||||
.associated_items(trait_predicate.def_id())
|
.associated_items(trait_predicate.def_id())
|
||||||
.in_definition_order()
|
.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(
|
.filter_map(
|
||||||
|item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
|
|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
|
| 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
|
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
--> $DIR/issue-102140.rs:23:9
|
--> $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;
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
//! This test checks that even if some associated types have
|
//! This test checks that associated types with `Self: Sized` cannot be projected
|
||||||
//! `where Self: Sized` bounds, those without still need to be
|
//! from a `dyn Trait`.
|
||||||
//! mentioned in trait objects.
|
|
||||||
|
|
||||||
trait Bop {
|
trait Bop {
|
||||||
type Bar: Default
|
type Bar: Default
|
||||||
@ -16,5 +15,4 @@ fn bop<T: Bop + ?Sized>() {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
bop::<dyn Bop>();
|
bop::<dyn Bop>();
|
||||||
//~^ ERROR: the size for values of type `dyn Bop` cannot be known at compilation time
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::Bar`, but its trait bounds were not satisfied
|
error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::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 _ = <T as Bop>::Bar::default();
|
LL | let _ = <T as Bop>::Bar::default();
|
||||||
| ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
|
| ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
|
||||||
@ -13,7 +13,7 @@ LL | fn bop<T: Bop + ?Sized>() where T: Sized {
|
|||||||
| ++++++++++++++
|
| ++++++++++++++
|
||||||
|
|
||||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
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<T: Bop + ?Sized>() {
|
LL | fn bop<T: Bop + ?Sized>() {
|
||||||
| - this type parameter needs to be `Sized`
|
| - this type parameter needs to be `Sized`
|
||||||
@ -21,7 +21,7 @@ LL | let _ = <T as Bop>::Bar::default();
|
|||||||
| ^ doesn't have a size known at compile-time
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
note: required by a bound in `Bop::Bar`
|
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
|
LL | type Bar: Default
|
||||||
| --- required by a bound in this associated type
|
| --- required by a bound in this associated type
|
||||||
@ -34,20 +34,7 @@ LL - fn bop<T: Bop + ?Sized>() {
|
|||||||
LL + fn bop<T: Bop>() {
|
LL + fn bop<T: Bop>() {
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/assoc_type_bounds_sized_used.rs:18:11
|
|
||||||
|
|
|
||||||
LL | bop::<dyn 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<T: Bop + ?Sized>() {
|
|
||||||
| ^^^ required by this bound in `bop`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0599.
|
Some errors have detailed explanations: E0277, E0599.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
25
tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
Normal file
25
tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
Normal file
@ -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(&());
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user