Skip to content

Commit

Permalink
Unrolled build for rust-lang#125786
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#125786 - compiler-errors:fold-item-bounds, r=lcnr

Fold item bounds before proving them in `check_type_bounds` in new solver

Vaguely confident that this is sufficient to prevent rust-lang/trait-system-refactor-initiative#46 and rust-lang/trait-system-refactor-initiative#62.

This is not the "correct" solution, but will probably suffice until coinduction, at which point we implement the right solution (`check_type_bounds` must prove `Assoc<...> alias-eq ConcreteType`, normalizing requires proving item bounds).

r? lcnr
  • Loading branch information
rust-timer authored May 31, 2024
2 parents 366da30 + 5c68eb3 commit d2a25ac
Show file tree
Hide file tree
Showing 35 changed files with 557 additions and 144 deletions.
29 changes: 27 additions & 2 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2026,10 +2026,19 @@ pub(super) fn check_type_bounds<'tcx>(
// to its definition type. This should be the param-env we use to *prove* the
// predicate too, but we don't do that because of performance issues.
// See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
let trait_projection_ty = Ty::new_projection(tcx, trait_ty.def_id, rebased_args);
let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
for mut obligation in util::elaborate(tcx, obligations) {
let normalized_predicate =
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate);
let normalized_predicate = if infcx.next_trait_solver() {
obligation.predicate.fold_with(&mut ReplaceTy {
tcx,
from: trait_projection_ty,
to: impl_identity_ty,
})
} else {
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
};
debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
obligation.predicate = normalized_predicate;

Expand All @@ -2050,6 +2059,22 @@ pub(super) fn check_type_bounds<'tcx>(
ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env)
}

struct ReplaceTy<'tcx> {
tcx: TyCtxt<'tcx>,
from: Ty<'tcx>,
to: Ty<'tcx>,
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if self.from == ty { self.to } else { ty.super_fold_with(self) }
}
}

/// Install projection predicates that allow GATs to project to their own
/// definition types. This is not allowed in general in cases of default
/// associated types in trait definitions, or when specialization is involved,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:13:22
--> $DIR/defaults-suitability.rs:16:22
|
LL | type Ty: Clone = NotClone;
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
|
note: required by a bound in `Tr::Ty`
--> $DIR/defaults-suitability.rs:13:14
--> $DIR/defaults-suitability.rs:16:14
|
LL | type Ty: Clone = NotClone;
| ^^^^^ required by this bound in `Tr::Ty`
Expand All @@ -16,13 +16,13 @@ LL | struct NotClone;
|

error[E0277]: the trait bound `NotClone: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:22:15
--> $DIR/defaults-suitability.rs:25:15
|
LL | type Ty = NotClone;
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
|
note: required by a bound in `Tr2::Ty`
--> $DIR/defaults-suitability.rs:20:15
--> $DIR/defaults-suitability.rs:23:15
|
LL | Self::Ty: Clone,
| ^^^^^ required by this bound in `Tr2::Ty`
Expand All @@ -36,14 +36,14 @@ LL | struct NotClone;
|

error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:28:23
--> $DIR/defaults-suitability.rs:31:23
|
LL | type Bar: Clone = Vec<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec<T>: Clone`
|
= note: required for `Vec<T>` to implement `Clone`
note: required by a bound in `Foo::Bar`
--> $DIR/defaults-suitability.rs:28:15
--> $DIR/defaults-suitability.rs:31:15
|
LL | type Bar: Clone = Vec<T>;
| ^^^^^ required by this bound in `Foo::Bar`
Expand All @@ -53,30 +53,30 @@ LL | trait Foo<T: std::clone::Clone> {
| +++++++++++++++++++

error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
--> $DIR/defaults-suitability.rs:34:29
--> $DIR/defaults-suitability.rs:37:29
|
LL | type Assoc: Foo<Self> = ();
| ^^ the trait `Foo<Self>` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/defaults-suitability.rs:27:1
--> $DIR/defaults-suitability.rs:30:1
|
LL | trait Foo<T> {
| ^^^^^^^^^^^^
note: required by a bound in `Bar::Assoc`
--> $DIR/defaults-suitability.rs:34:17
--> $DIR/defaults-suitability.rs:37:17
|
LL | type Assoc: Foo<Self> = ();
| ^^^^^^^^^ required by this bound in `Bar::Assoc`

error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
--> $DIR/defaults-suitability.rs:56:18
--> $DIR/defaults-suitability.rs:59:18
|
LL | type Assoc = NotClone;
| ^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
|
note: required by a bound in `D::Assoc`
--> $DIR/defaults-suitability.rs:53:18
--> $DIR/defaults-suitability.rs:56:18
|
LL | Self::Assoc: IsU8<Self::Assoc>,
| ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
Expand All @@ -85,14 +85,14 @@ LL | type Assoc = NotClone;
| ----- required by a bound in this associated type

error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:65:23
--> $DIR/defaults-suitability.rs:68:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`, which is required by `Vec<<Self as Foo2<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo2::Bar`
--> $DIR/defaults-suitability.rs:65:15
--> $DIR/defaults-suitability.rs:68:15
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^ required by this bound in `Foo2::Bar`
Expand All @@ -102,14 +102,14 @@ LL | trait Foo2<T> where <Self as Foo2<T>>::Baz: Clone {
| +++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:74:23
--> $DIR/defaults-suitability.rs:77:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`, which is required by `Vec<<Self as Foo25<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo25::Bar`
--> $DIR/defaults-suitability.rs:74:15
--> $DIR/defaults-suitability.rs:77:15
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^ required by this bound in `Foo25::Bar`
Expand All @@ -119,13 +119,13 @@ LL | trait Foo25<T: Clone> where <Self as Foo25<T>>::Baz: Clone {
| ++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:87:16
--> $DIR/defaults-suitability.rs:90:16
|
LL | type Baz = T;
| ^ the trait `Clone` is not implemented for `T`
|
note: required by a bound in `Foo3::Baz`
--> $DIR/defaults-suitability.rs:84:16
--> $DIR/defaults-suitability.rs:87:16
|
LL | Self::Baz: Clone,
| ^^^^^ required by this bound in `Foo3::Baz`
Expand Down
142 changes: 142 additions & 0 deletions tests/ui/associated-types/defaults-suitability.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:16:22
|
LL | type Ty: Clone = NotClone;
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
|
note: required by a bound in `Tr::Ty`
--> $DIR/defaults-suitability.rs:16:14
|
LL | type Ty: Clone = NotClone;
| ^^^^^ required by this bound in `Tr::Ty`
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct NotClone;
|

error[E0277]: the trait bound `NotClone: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:25:15
|
LL | type Ty = NotClone;
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
|
note: required by a bound in `Tr2::Ty`
--> $DIR/defaults-suitability.rs:23:15
|
LL | Self::Ty: Clone,
| ^^^^^ required by this bound in `Tr2::Ty`
LL | {
LL | type Ty = NotClone;
| -- required by a bound in this associated type
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct NotClone;
|

error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:31:23
|
LL | type Bar: Clone = Vec<T>;
| ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec<T>: Clone`
|
= note: required for `Vec<T>` to implement `Clone`
note: required by a bound in `Foo::Bar`
--> $DIR/defaults-suitability.rs:31:15
|
LL | type Bar: Clone = Vec<T>;
| ^^^^^ required by this bound in `Foo::Bar`
help: consider restricting type parameter `T`
|
LL | trait Foo<T: std::clone::Clone> {
| +++++++++++++++++++

error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
--> $DIR/defaults-suitability.rs:37:29
|
LL | type Assoc: Foo<Self> = ();
| ^^ the trait `Foo<Self>` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/defaults-suitability.rs:30:1
|
LL | trait Foo<T> {
| ^^^^^^^^^^^^
note: required by a bound in `Bar::Assoc`
--> $DIR/defaults-suitability.rs:37:17
|
LL | type Assoc: Foo<Self> = ();
| ^^^^^^^^^ required by this bound in `Bar::Assoc`

error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
--> $DIR/defaults-suitability.rs:59:18
|
LL | type Assoc = NotClone;
| ^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
|
note: required by a bound in `D::Assoc`
--> $DIR/defaults-suitability.rs:56:18
|
LL | Self::Assoc: IsU8<Self::Assoc>,
| ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
...
LL | type Assoc = NotClone;
| ----- required by a bound in this associated type

error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:68:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`, which is required by `Vec<<Self as Foo2<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo2::Bar`
--> $DIR/defaults-suitability.rs:68:15
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^ required by this bound in `Foo2::Bar`
help: consider further restricting the associated type
|
LL | trait Foo2<T> where <Self as Foo2<T>>::Baz: Clone {
| +++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:77:23
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`, which is required by `Vec<<Self as Foo25<T>>::Baz>: Clone`
|
= note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
note: required by a bound in `Foo25::Bar`
--> $DIR/defaults-suitability.rs:77:15
|
LL | type Bar: Clone = Vec<Self::Baz>;
| ^^^^^ required by this bound in `Foo25::Bar`
help: consider further restricting the associated type
|
LL | trait Foo25<T: Clone> where <Self as Foo25<T>>::Baz: Clone {
| ++++++++++++++++++++++++++++++++++++

error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:90:16
|
LL | type Baz = T;
| ^ the trait `Clone` is not implemented for `T`
|
note: required by a bound in `Foo3::Baz`
--> $DIR/defaults-suitability.rs:87:16
|
LL | Self::Baz: Clone,
| ^^^^^ required by this bound in `Foo3::Baz`
...
LL | type Baz = T;
| --- required by a bound in this associated type
help: consider further restricting type parameter `T`
|
LL | Self::Baz: Clone, T: std::clone::Clone
| ~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0277`.
3 changes: 3 additions & 0 deletions tests/ui/associated-types/defaults-suitability.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//! Checks that associated type defaults are properly validated.
//!
//! This means:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
error[E0277]: `Self` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-1.rs:26:96
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ `Self` cannot be formatted with the default formatter
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:26:86
--> $DIR/defaults-unsound-62211-1.rs:24:86
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^^^^ required by this bound in `UncheckedCopy::Output`
Expand All @@ -16,13 +16,13 @@ LL | trait UncheckedCopy: Sized + std::fmt::Display {
| +++++++++++++++++++

error[E0277]: cannot add-assign `&'static str` to `Self`
--> $DIR/defaults-unsound-62211-1.rs:26:96
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ no implementation for `Self += &'static str`
|
note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:26:47
--> $DIR/defaults-unsound-62211-1.rs:24:47
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
Expand All @@ -32,13 +32,13 @@ LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
| +++++++++++++++++++++++++

error[E0277]: the trait bound `Self: Deref` is not satisfied
--> $DIR/defaults-unsound-62211-1.rs:26:96
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ the trait `Deref` is not implemented for `Self`
|
note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:26:25
--> $DIR/defaults-unsound-62211-1.rs:24:25
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
Expand All @@ -48,13 +48,13 @@ LL | trait UncheckedCopy: Sized + Deref {
| +++++++

error[E0277]: the trait bound `Self: Copy` is not satisfied
--> $DIR/defaults-unsound-62211-1.rs:26:96
--> $DIR/defaults-unsound-62211-1.rs:24:96
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ the trait `Copy` is not implemented for `Self`
|
note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:26:18
--> $DIR/defaults-unsound-62211-1.rs:24:18
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ required by this bound in `UncheckedCopy::Output`
Expand Down
Loading

0 comments on commit d2a25ac

Please sign in to comment.