Skip to content

Commit 9c609ae

Browse files
committedSep 5, 2023
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 #112319 (comment), and I don't think needs re-litigation. r? `@oli-obk`
2 parents 04374cd + 07fc644 commit 9c609ae

File tree

7 files changed

+68
-22
lines changed

7 files changed

+68
-22
lines changed
 

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

+6
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+
// associated types that require `Self: Sized` do not show up in the built-in
358+
// implementation of `Trait for dyn Trait`, and can be dropped here.
359+
if tcx.generics_require_sized_self(item.def_id) {
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

+3
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+
// Associated types that require `Self: Sized` do not show up in the built-in
539+
// implementation of `Trait for dyn Trait`, and can be dropped here.
540+
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
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

+5-1
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
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/object-safety/assoc_type_bounds_sized_used.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
//! This test checks that even if some associated types have
2-
//! `where Self: Sized` bounds, those without still need to be
3-
//! mentioned in trait objects.
1+
//! This test checks that associated types with `Self: Sized` cannot be projected
2+
//! from a `dyn Trait`.
43
54
trait Bop {
65
type Bar: Default
@@ -16,5 +15,4 @@ fn bop<T: Bop + ?Sized>() {
1615

1716
fn main() {
1817
bop::<dyn Bop>();
19-
//~^ ERROR: the size for values of type `dyn Bop` cannot be known at compilation time
2018
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0599]: the function or associated item `default` exists for associated type `<T as Bop>::Bar`, but its trait bounds were not satisfied
2-
--> $DIR/assoc_type_bounds_sized_used.rs:12:30
2+
--> $DIR/assoc_type_bounds_sized_used.rs:11:30
33
|
44
LL | let _ = <T as Bop>::Bar::default();
55
| ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
@@ -13,15 +13,15 @@ LL | fn bop<T: Bop + ?Sized>() where T: Sized {
1313
| ++++++++++++++
1414

1515
error[E0277]: the size for values of type `T` cannot be known at compilation time
16-
--> $DIR/assoc_type_bounds_sized_used.rs:12:14
16+
--> $DIR/assoc_type_bounds_sized_used.rs:11:14
1717
|
1818
LL | fn bop<T: Bop + ?Sized>() {
1919
| - this type parameter needs to be `Sized`
2020
LL | let _ = <T as Bop>::Bar::default();
2121
| ^ doesn't have a size known at compile-time
2222
|
2323
note: required by a bound in `Bop::Bar`
24-
--> $DIR/assoc_type_bounds_sized_used.rs:8:15
24+
--> $DIR/assoc_type_bounds_sized_used.rs:7:15
2525
|
2626
LL | type Bar: Default
2727
| --- required by a bound in this associated type
@@ -34,20 +34,7 @@ LL - fn bop<T: Bop + ?Sized>() {
3434
LL + fn bop<T: Bop>() {
3535
|
3636

37-
error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time
38-
--> $DIR/assoc_type_bounds_sized_used.rs:18:11
39-
|
40-
LL | bop::<dyn Bop>();
41-
| ^^^^^^^ doesn't have a size known at compile-time
42-
|
43-
= help: the trait `Sized` is not implemented for `dyn Bop`
44-
note: required by a bound in `bop`
45-
--> $DIR/assoc_type_bounds_sized_used.rs:11:11
46-
|
47-
LL | fn bop<T: Bop + ?Sized>() {
48-
| ^^^ required by this bound in `bop`
49-
50-
error: aborting due to 3 previous errors
37+
error: aborting due to 2 previous errors
5138

5239
Some errors have detailed explanations: E0277, E0599.
5340
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// check-pass
2+
// revisions: current next
3+
//[next] compile-flags: -Ztrait-solver=next
4+
5+
trait Foo {
6+
type Bar<'a>
7+
where
8+
Self: Sized;
9+
10+
fn test(&self);
11+
}
12+
13+
impl Foo for () {
14+
type Bar<'a> = () where Self: Sized;
15+
16+
fn test(&self) {}
17+
}
18+
19+
fn test(x: &dyn Foo) {
20+
x.test();
21+
}
22+
23+
fn main() {
24+
test(&());
25+
}

0 commit comments

Comments
 (0)