Skip to content

Commit 4a39657

Browse files
committed
Auto 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
2 parents 434999e + 5c68eb3 commit 4a39657

35 files changed

+557
-144
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -2026,10 +2026,19 @@ pub(super) fn check_type_bounds<'tcx>(
20262026
// to its definition type. This should be the param-env we use to *prove* the
20272027
// predicate too, but we don't do that because of performance issues.
20282028
// See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
2029+
let trait_projection_ty = Ty::new_projection(tcx, trait_ty.def_id, rebased_args);
2030+
let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
20292031
let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
20302032
for mut obligation in util::elaborate(tcx, obligations) {
2031-
let normalized_predicate =
2032-
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate);
2033+
let normalized_predicate = if infcx.next_trait_solver() {
2034+
obligation.predicate.fold_with(&mut ReplaceTy {
2035+
tcx,
2036+
from: trait_projection_ty,
2037+
to: impl_identity_ty,
2038+
})
2039+
} else {
2040+
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
2041+
};
20332042
debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
20342043
obligation.predicate = normalized_predicate;
20352044

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

2062+
struct ReplaceTy<'tcx> {
2063+
tcx: TyCtxt<'tcx>,
2064+
from: Ty<'tcx>,
2065+
to: Ty<'tcx>,
2066+
}
2067+
2068+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
2069+
fn interner(&self) -> TyCtxt<'tcx> {
2070+
self.tcx
2071+
}
2072+
2073+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
2074+
if self.from == ty { self.to } else { ty.super_fold_with(self) }
2075+
}
2076+
}
2077+
20532078
/// Install projection predicates that allow GATs to project to their own
20542079
/// definition types. This is not allowed in general in cases of default
20552080
/// associated types in trait definitions, or when specialization is involved,

tests/ui/associated-types/defaults-suitability.stderr tests/ui/associated-types/defaults-suitability.current.stderr

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
2-
--> $DIR/defaults-suitability.rs:13:22
2+
--> $DIR/defaults-suitability.rs:16:22
33
|
44
LL | type Ty: Clone = NotClone;
55
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
66
|
77
note: required by a bound in `Tr::Ty`
8-
--> $DIR/defaults-suitability.rs:13:14
8+
--> $DIR/defaults-suitability.rs:16:14
99
|
1010
LL | type Ty: Clone = NotClone;
1111
| ^^^^^ required by this bound in `Tr::Ty`
@@ -16,13 +16,13 @@ LL | struct NotClone;
1616
|
1717

1818
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
19-
--> $DIR/defaults-suitability.rs:22:15
19+
--> $DIR/defaults-suitability.rs:25:15
2020
|
2121
LL | type Ty = NotClone;
2222
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
2323
|
2424
note: required by a bound in `Tr2::Ty`
25-
--> $DIR/defaults-suitability.rs:20:15
25+
--> $DIR/defaults-suitability.rs:23:15
2626
|
2727
LL | Self::Ty: Clone,
2828
| ^^^^^ required by this bound in `Tr2::Ty`
@@ -36,14 +36,14 @@ LL | struct NotClone;
3636
|
3737

3838
error[E0277]: the trait bound `T: Clone` is not satisfied
39-
--> $DIR/defaults-suitability.rs:28:23
39+
--> $DIR/defaults-suitability.rs:31:23
4040
|
4141
LL | type Bar: Clone = Vec<T>;
4242
| ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec<T>: Clone`
4343
|
4444
= note: required for `Vec<T>` to implement `Clone`
4545
note: required by a bound in `Foo::Bar`
46-
--> $DIR/defaults-suitability.rs:28:15
46+
--> $DIR/defaults-suitability.rs:31:15
4747
|
4848
LL | type Bar: Clone = Vec<T>;
4949
| ^^^^^ required by this bound in `Foo::Bar`
@@ -53,30 +53,30 @@ LL | trait Foo<T: std::clone::Clone> {
5353
| +++++++++++++++++++
5454

5555
error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
56-
--> $DIR/defaults-suitability.rs:34:29
56+
--> $DIR/defaults-suitability.rs:37:29
5757
|
5858
LL | type Assoc: Foo<Self> = ();
5959
| ^^ the trait `Foo<Self>` is not implemented for `()`
6060
|
6161
help: this trait has no implementations, consider adding one
62-
--> $DIR/defaults-suitability.rs:27:1
62+
--> $DIR/defaults-suitability.rs:30:1
6363
|
6464
LL | trait Foo<T> {
6565
| ^^^^^^^^^^^^
6666
note: required by a bound in `Bar::Assoc`
67-
--> $DIR/defaults-suitability.rs:34:17
67+
--> $DIR/defaults-suitability.rs:37:17
6868
|
6969
LL | type Assoc: Foo<Self> = ();
7070
| ^^^^^^^^^ required by this bound in `Bar::Assoc`
7171

7272
error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
73-
--> $DIR/defaults-suitability.rs:56:18
73+
--> $DIR/defaults-suitability.rs:59:18
7474
|
7575
LL | type Assoc = NotClone;
7676
| ^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
7777
|
7878
note: required by a bound in `D::Assoc`
79-
--> $DIR/defaults-suitability.rs:53:18
79+
--> $DIR/defaults-suitability.rs:56:18
8080
|
8181
LL | Self::Assoc: IsU8<Self::Assoc>,
8282
| ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
@@ -85,14 +85,14 @@ LL | type Assoc = NotClone;
8585
| ----- required by a bound in this associated type
8686

8787
error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
88-
--> $DIR/defaults-suitability.rs:65:23
88+
--> $DIR/defaults-suitability.rs:68:23
8989
|
9090
LL | type Bar: Clone = Vec<Self::Baz>;
9191
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`, which is required by `Vec<<Self as Foo2<T>>::Baz>: Clone`
9292
|
9393
= note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
9494
note: required by a bound in `Foo2::Bar`
95-
--> $DIR/defaults-suitability.rs:65:15
95+
--> $DIR/defaults-suitability.rs:68:15
9696
|
9797
LL | type Bar: Clone = Vec<Self::Baz>;
9898
| ^^^^^ required by this bound in `Foo2::Bar`
@@ -102,14 +102,14 @@ LL | trait Foo2<T> where <Self as Foo2<T>>::Baz: Clone {
102102
| +++++++++++++++++++++++++++++++++++
103103

104104
error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
105-
--> $DIR/defaults-suitability.rs:74:23
105+
--> $DIR/defaults-suitability.rs:77:23
106106
|
107107
LL | type Bar: Clone = Vec<Self::Baz>;
108108
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`, which is required by `Vec<<Self as Foo25<T>>::Baz>: Clone`
109109
|
110110
= note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
111111
note: required by a bound in `Foo25::Bar`
112-
--> $DIR/defaults-suitability.rs:74:15
112+
--> $DIR/defaults-suitability.rs:77:15
113113
|
114114
LL | type Bar: Clone = Vec<Self::Baz>;
115115
| ^^^^^ required by this bound in `Foo25::Bar`
@@ -119,13 +119,13 @@ LL | trait Foo25<T: Clone> where <Self as Foo25<T>>::Baz: Clone {
119119
| ++++++++++++++++++++++++++++++++++++
120120

121121
error[E0277]: the trait bound `T: Clone` is not satisfied
122-
--> $DIR/defaults-suitability.rs:87:16
122+
--> $DIR/defaults-suitability.rs:90:16
123123
|
124124
LL | type Baz = T;
125125
| ^ the trait `Clone` is not implemented for `T`
126126
|
127127
note: required by a bound in `Foo3::Baz`
128-
--> $DIR/defaults-suitability.rs:84:16
128+
--> $DIR/defaults-suitability.rs:87:16
129129
|
130130
LL | Self::Baz: Clone,
131131
| ^^^^^ required by this bound in `Foo3::Baz`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
2+
--> $DIR/defaults-suitability.rs:16:22
3+
|
4+
LL | type Ty: Clone = NotClone;
5+
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
6+
|
7+
note: required by a bound in `Tr::Ty`
8+
--> $DIR/defaults-suitability.rs:16:14
9+
|
10+
LL | type Ty: Clone = NotClone;
11+
| ^^^^^ required by this bound in `Tr::Ty`
12+
help: consider annotating `NotClone` with `#[derive(Clone)]`
13+
|
14+
LL + #[derive(Clone)]
15+
LL | struct NotClone;
16+
|
17+
18+
error[E0277]: the trait bound `NotClone: Clone` is not satisfied
19+
--> $DIR/defaults-suitability.rs:25:15
20+
|
21+
LL | type Ty = NotClone;
22+
| ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
23+
|
24+
note: required by a bound in `Tr2::Ty`
25+
--> $DIR/defaults-suitability.rs:23:15
26+
|
27+
LL | Self::Ty: Clone,
28+
| ^^^^^ required by this bound in `Tr2::Ty`
29+
LL | {
30+
LL | type Ty = NotClone;
31+
| -- required by a bound in this associated type
32+
help: consider annotating `NotClone` with `#[derive(Clone)]`
33+
|
34+
LL + #[derive(Clone)]
35+
LL | struct NotClone;
36+
|
37+
38+
error[E0277]: the trait bound `T: Clone` is not satisfied
39+
--> $DIR/defaults-suitability.rs:31:23
40+
|
41+
LL | type Bar: Clone = Vec<T>;
42+
| ^^^^^^ the trait `Clone` is not implemented for `T`, which is required by `Vec<T>: Clone`
43+
|
44+
= note: required for `Vec<T>` to implement `Clone`
45+
note: required by a bound in `Foo::Bar`
46+
--> $DIR/defaults-suitability.rs:31:15
47+
|
48+
LL | type Bar: Clone = Vec<T>;
49+
| ^^^^^ required by this bound in `Foo::Bar`
50+
help: consider restricting type parameter `T`
51+
|
52+
LL | trait Foo<T: std::clone::Clone> {
53+
| +++++++++++++++++++
54+
55+
error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
56+
--> $DIR/defaults-suitability.rs:37:29
57+
|
58+
LL | type Assoc: Foo<Self> = ();
59+
| ^^ the trait `Foo<Self>` is not implemented for `()`
60+
|
61+
help: this trait has no implementations, consider adding one
62+
--> $DIR/defaults-suitability.rs:30:1
63+
|
64+
LL | trait Foo<T> {
65+
| ^^^^^^^^^^^^
66+
note: required by a bound in `Bar::Assoc`
67+
--> $DIR/defaults-suitability.rs:37:17
68+
|
69+
LL | type Assoc: Foo<Self> = ();
70+
| ^^^^^^^^^ required by this bound in `Bar::Assoc`
71+
72+
error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
73+
--> $DIR/defaults-suitability.rs:59:18
74+
|
75+
LL | type Assoc = NotClone;
76+
| ^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
77+
|
78+
note: required by a bound in `D::Assoc`
79+
--> $DIR/defaults-suitability.rs:56:18
80+
|
81+
LL | Self::Assoc: IsU8<Self::Assoc>,
82+
| ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
83+
...
84+
LL | type Assoc = NotClone;
85+
| ----- required by a bound in this associated type
86+
87+
error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
88+
--> $DIR/defaults-suitability.rs:68:23
89+
|
90+
LL | type Bar: Clone = Vec<Self::Baz>;
91+
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`, which is required by `Vec<<Self as Foo2<T>>::Baz>: Clone`
92+
|
93+
= note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
94+
note: required by a bound in `Foo2::Bar`
95+
--> $DIR/defaults-suitability.rs:68:15
96+
|
97+
LL | type Bar: Clone = Vec<Self::Baz>;
98+
| ^^^^^ required by this bound in `Foo2::Bar`
99+
help: consider further restricting the associated type
100+
|
101+
LL | trait Foo2<T> where <Self as Foo2<T>>::Baz: Clone {
102+
| +++++++++++++++++++++++++++++++++++
103+
104+
error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
105+
--> $DIR/defaults-suitability.rs:77:23
106+
|
107+
LL | type Bar: Clone = Vec<Self::Baz>;
108+
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`, which is required by `Vec<<Self as Foo25<T>>::Baz>: Clone`
109+
|
110+
= note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
111+
note: required by a bound in `Foo25::Bar`
112+
--> $DIR/defaults-suitability.rs:77:15
113+
|
114+
LL | type Bar: Clone = Vec<Self::Baz>;
115+
| ^^^^^ required by this bound in `Foo25::Bar`
116+
help: consider further restricting the associated type
117+
|
118+
LL | trait Foo25<T: Clone> where <Self as Foo25<T>>::Baz: Clone {
119+
| ++++++++++++++++++++++++++++++++++++
120+
121+
error[E0277]: the trait bound `T: Clone` is not satisfied
122+
--> $DIR/defaults-suitability.rs:90:16
123+
|
124+
LL | type Baz = T;
125+
| ^ the trait `Clone` is not implemented for `T`
126+
|
127+
note: required by a bound in `Foo3::Baz`
128+
--> $DIR/defaults-suitability.rs:87:16
129+
|
130+
LL | Self::Baz: Clone,
131+
| ^^^^^ required by this bound in `Foo3::Baz`
132+
...
133+
LL | type Baz = T;
134+
| --- required by a bound in this associated type
135+
help: consider further restricting type parameter `T`
136+
|
137+
LL | Self::Baz: Clone, T: std::clone::Clone
138+
| ~~~~~~~~~~~~~~~~~~~~~~
139+
140+
error: aborting due to 8 previous errors
141+
142+
For more information about this error, try `rustc --explain E0277`.

tests/ui/associated-types/defaults-suitability.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
14
//! Checks that associated type defaults are properly validated.
25
//!
36
//! This means:

tests/ui/associated-types/defaults-unsound-62211-1.current.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
error[E0277]: `Self` doesn't implement `std::fmt::Display`
2-
--> $DIR/defaults-unsound-62211-1.rs:26:96
2+
--> $DIR/defaults-unsound-62211-1.rs:24:96
33
|
44
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
55
| ^^^^ `Self` cannot be formatted with the default formatter
66
|
77
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
88
note: required by a bound in `UncheckedCopy::Output`
9-
--> $DIR/defaults-unsound-62211-1.rs:26:86
9+
--> $DIR/defaults-unsound-62211-1.rs:24:86
1010
|
1111
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
1212
| ^^^^^^^ required by this bound in `UncheckedCopy::Output`
@@ -16,13 +16,13 @@ LL | trait UncheckedCopy: Sized + std::fmt::Display {
1616
| +++++++++++++++++++
1717

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

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

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

0 commit comments

Comments
 (0)