Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not require associated types with Self: Sized to uphold bounds when confirming object candidate #115467

Merged
merged 2 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
// 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
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, trait_ref.args));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let assoc_types: Vec<_> = tcx
.associated_items(trait_predicate.def_id())
.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(
|item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
)
Expand Down
6 changes: 5 additions & 1 deletion tests/ui/impl-trait/in-trait/issue-102140.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +9 to +12
Copy link
Member Author

@compiler-errors compiler-errors Sep 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly sure why this diagnostic has come back -- it's kinda sketchy, but also it's kinda implemented sketchily. I kinda don't want to bother fixing it, but I guess could be convinced otherwise.

|

error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:23:9
Expand Down
23 changes: 23 additions & 0 deletions tests/ui/impl-trait/in-trait/object-safety-sized.rs
Original file line number Diff line number Diff line change
@@ -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;
}
6 changes: 2 additions & 4 deletions tests/ui/object-safety/assoc_type_bounds_sized_used.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! This test checks that even if some associated types have
//! `where Self: Sized` bounds, those without still need to be
//! mentioned in trait objects.
//! This test checks that associated types with `Self: Sized` cannot be projected
//! from a `dyn Trait`.

trait Bop {
type Bar: Default
Expand All @@ -16,5 +15,4 @@ fn bop<T: Bop + ?Sized>() {

fn main() {
bop::<dyn Bop>();
//~^ ERROR: the size for values of type `dyn Bop` cannot be known at compilation time
}
21 changes: 4 additions & 17 deletions tests/ui/object-safety/assoc_type_bounds_sized_used.stderr
Original file line number Diff line number Diff line change
@@ -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
--> $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();
| ^^^^^^^ function or associated item cannot be called on `<T as Bop>::Bar` due to unsatisfied trait bounds
Expand All @@ -13,15 +13,15 @@ LL | fn bop<T: Bop + ?Sized>() where T: Sized {
| ++++++++++++++

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>() {
| - this type parameter needs to be `Sized`
LL | let _ = <T as Bop>::Bar::default();
| ^ doesn't have a size known at compile-time
|
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
| --- required by a bound in this associated type
Expand All @@ -34,20 +34,7 @@ LL - fn bop<T: Bop + ?Sized>() {
LL + fn bop<T: Bop>() {
|

error[E0277]: the size for values of type `dyn Bop` cannot be known at compilation time
--> $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
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
25 changes: 25 additions & 0 deletions tests/ui/object-safety/call-when-assoc-ty-is-sized.rs
Original file line number Diff line number Diff line change
@@ -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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in stable behaviour (compiles now, errors on nightly) and needs an FCP

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that's what you mean by "doesn't need re-litigation". Ugh... I agree, but we have procedures out of a reason, too.

Copy link
Member Author

@compiler-errors compiler-errors Sep 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it does -- but if you think it needs one, then start an FCP 🤷

(edited for clarity, sorry the wording was kind of terse before 😅)

}

fn main() {
test(&());
}
Loading