Skip to content
Open
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 @@ -962,8 +962,12 @@ where
.iter()
.filter(|source_projection| self.projection_may_match(**source_projection, alias_term));
let Some(replacement) = matching_projections.next() else {
// This shouldn't happen.
panic!("could not replace {alias_term:?} with term from from {:?}", self.self_ty);
// This replacement is not the right one, i.e. we have projection which
// has the same `def_id` but cannot be normalized or should be normalized
// by other sources such as param env, not object bounds. This is as good
// as `replacement = None`, so just return like it.
// See https://github.com/rust-lang/rust/pull/152859.
return Ok(None);
};
// FIXME: This *may* have issues with duplicated projections.
if matching_projections.next().is_some() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass

// A regression test for https://github.com/rust-lang/rust/issues/152789.
// Ensures we do not trigger an ICE or compilation error when normalizing
// a projection on a trait object, where the matching trait predicate
// (with the same trait id as the object bound) originates from another
// source such as the param env, rather than from the object's own bounds.

pub trait Trait<T> {
type Assoc;
}

pub trait Foo {
type FooAssoc;
}

pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc)
where
dyn Trait<i32, Assoc = i64>: Trait<U::FooAssoc>;

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)
//@ check-pass

// A regression test for https://github.com/rust-lang/rust/issues/152789.
// Ensures we do not trigger an ICE or compilation error when normalizing
// a projection on a trait object, where the matching trait predicate
// (with the same trait id as the object bound) originates from another
// source such as the param env, rather than from the object's own bounds.

pub trait Trait<T> {
type Assoc;
}

pub trait Trait2<T> {
type Assoc2;
}

impl<T, U: ?Sized> Trait<T> for U
where
U: Trait2<T>,
{
type Assoc = <U as Trait2<T>>::Assoc2;
}

pub trait Foo {
type FooAssoc;
}

pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc)
where
dyn Trait<i32, Assoc = i64>: Trait2<U::FooAssoc>;

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0277]: the trait bound `(dyn Trait<i32, Assoc = i64> + 'static): Trait<<U as Foo>::FooAssoc>` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-1.rs:18:25
|
LL | pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<<U as Foo>::FooAssoc>` is not implemented for `(dyn Trait<i32, Assoc = i64> + 'static)`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc) where (dyn Trait<i32, Assoc = i64> + 'static): Trait<<U as Foo>::FooAssoc>;
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0277]: the trait bound `(dyn Trait<i32, Assoc = i64> + 'static): Trait<<U as Foo>::FooAssoc>` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-1.rs:18:25
|
LL | pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<<U as Foo>::FooAssoc>` is not implemented for `(dyn Trait<i32, Assoc = i64> + 'static)`
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc) where (dyn Trait<i32, Assoc = i64> + 'static): Trait<<U as Foo>::FooAssoc>;
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)

// A regression test for https://github.com/rust-lang/rust/issues/152789.
// Ensures we do not trigger an ICE when normalization fails for a
// projection on a trait object, even if the projection has the same
// trait id as the object's bound.

pub trait Trait<T> {
type Assoc;
}

pub trait Foo {
type FooAssoc;
}

pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc);
//~^ ERROR: the trait bound `(dyn Trait<i32, Assoc = i64> + 'static): Trait<<U as Foo>::FooAssoc>` is not satisfied

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:20:14
|
LL | impl<T: Foo> Bar<dyn Callback<T>> {
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^
note: required by a bound in `Bar`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:16:15
|
LL | struct Bar<T: Foo + ?Sized> {
| ^^^ required by this bound in `Bar`

error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:22:14
|
LL | fn event(&self) {
| ^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^
note: required by a bound in `Bar`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:16:15
|
LL | struct Bar<T: Foo + ?Sized> {
| ^^^ required by this bound in `Bar`

error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:24:9
|
LL | (self.callback)(any(), any());
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^

error[E0618]: expected function, found `Box<(dyn Callback<(dyn Callback<T> + 'static), Output = ()> + 'static)>`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:24:9
|
LL | (self.callback)(any(), any());
| ^^^^^^^^^^^^^^^--------------
| |
| call expression requires function

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0277, E0618.
For more information about an error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:20:14
|
LL | impl<T: Foo> Bar<dyn Callback<T>> {
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^
note: required by a bound in `Bar`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:16:15
|
LL | struct Bar<T: Foo + ?Sized> {
| ^^^ required by this bound in `Bar`

error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:22:14
|
LL | fn event(&self) {
| ^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^
note: required by a bound in `Bar`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:16:15
|
LL | struct Bar<T: Foo + ?Sized> {
| ^^^ required by this bound in `Bar`

error[E0618]: expected function, found `Box<(dyn Callback<(dyn Callback<T> + 'static)> + 'static)>`
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:24:9
|
LL | (self.callback)(any(), any());
| ^^^^^^^^^^^^^^^--------------
| |
| call expression requires function

error[E0277]: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:24:9
|
LL | (self.callback)(any(), any());
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<T> + 'static)`
|
help: this trait has no implementations, consider adding one
--> $DIR/object-projection-with-unsatisfied-bound-2.rs:10:1
|
LL | trait Foo {
| ^^^^^^^^^

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0277, E0618.
For more information about an error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@ ignore-compare-mode-next-solver (explicit revisions)

// A regression test for https://github.com/rust-lang/rust/issues/151329.
// Ensures we do not trigger an ICE when normalization fails for a
// projection on a trait object, even if the projection has the same
// trait id as the object's bound.

trait Foo {
type V;
}

trait Callback<T: Foo>: Fn(&T, &T::V) {}

struct Bar<T: Foo + ?Sized> {
callback: Box<dyn Callback<T>>,
}

impl<T: Foo> Bar<dyn Callback<T>> {
//~^ ERROR: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
fn event(&self) {
//~^ ERROR: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
(self.callback)(any(), any());
//~^ ERROR: the trait bound `(dyn Callback<T> + 'static): Foo` is not satisfied
//~| ERROR: expected function
}
}

fn any() {}

fn main() {}
Loading