Skip to content

Commit 2f4b7dc

Browse files
Fold item bound before checking that they hold
1 parent 7feb191 commit 2f4b7dc

20 files changed

+246
-115
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-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`
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,81 @@
1-
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
2-
--> $DIR/defaults-unsound-62211-1.rs:52:5
1+
error[E0277]: `Self` doesn't implement `std::fmt::Display`
2+
--> $DIR/defaults-unsound-62211-1.rs:24:96
33
|
4-
LL | drop(origin);
5-
| ^^^^^------^
6-
| |
7-
| argument has type `<T as UncheckedCopy>::Output`
4+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
5+
| ^^^^ `Self` cannot be formatted with the default formatter
86
|
9-
= note: `#[warn(dropping_copy_types)]` on by default
10-
help: use `let _ = ...` to ignore the expression or result
7+
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
8+
note: required by a bound in `UncheckedCopy::Output`
9+
--> $DIR/defaults-unsound-62211-1.rs:24:86
1110
|
12-
LL - drop(origin);
13-
LL + let _ = origin;
11+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
12+
| ^^^^^^^ required by this bound in `UncheckedCopy::Output`
13+
help: consider further restricting `Self`
1414
|
15+
LL | trait UncheckedCopy: Sized + std::fmt::Display {
16+
| +++++++++++++++++++
1517

16-
warning: 1 warning emitted
18+
error[E0277]: cannot add-assign `&'static str` to `Self`
19+
--> $DIR/defaults-unsound-62211-1.rs:24:96
20+
|
21+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
22+
| ^^^^ no implementation for `Self += &'static str`
23+
|
24+
note: required by a bound in `UncheckedCopy::Output`
25+
--> $DIR/defaults-unsound-62211-1.rs:24:47
26+
|
27+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
28+
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
29+
help: consider further restricting `Self`
30+
|
31+
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
32+
| +++++++++++++++++++++++++
33+
34+
error[E0271]: type mismatch resolving `<Self as Deref>::Target == str`
35+
--> $DIR/defaults-unsound-62211-1.rs:24:96
36+
|
37+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
38+
| ^^^^ types differ
39+
|
40+
note: required by a bound in `UncheckedCopy::Output`
41+
--> $DIR/defaults-unsound-62211-1.rs:24:31
42+
|
43+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
44+
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
45+
46+
error[E0277]: the trait bound `Self: Deref` is not satisfied
47+
--> $DIR/defaults-unsound-62211-1.rs:24:96
48+
|
49+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
50+
| ^^^^ the trait `Deref` is not implemented for `Self`
51+
|
52+
note: required by a bound in `UncheckedCopy::Output`
53+
--> $DIR/defaults-unsound-62211-1.rs:24:25
54+
|
55+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
56+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
57+
help: consider further restricting `Self`
58+
|
59+
LL | trait UncheckedCopy: Sized + Deref {
60+
| +++++++
61+
62+
error[E0277]: the trait bound `Self: Copy` is not satisfied
63+
--> $DIR/defaults-unsound-62211-1.rs:24:96
64+
|
65+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
66+
| ^^^^ the trait `Copy` is not implemented for `Self`
67+
|
68+
note: required by a bound in `UncheckedCopy::Output`
69+
--> $DIR/defaults-unsound-62211-1.rs:24:18
70+
|
71+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
72+
| ^^^^ required by this bound in `UncheckedCopy::Output`
73+
help: consider further restricting `Self`
74+
|
75+
LL | trait UncheckedCopy: Sized + Copy {
76+
| ++++++
77+
78+
error: aborting due to 5 previous errors
1779

80+
Some errors have detailed explanations: E0271, E0277.
81+
For more information about an error, try `rustc --explain E0271`.

tests/ui/associated-types/defaults-unsound-62211-1.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//@ revisions: current next
22
//@[next] compile-flags: -Znext-solver
33
//@ ignore-compare-mode-next-solver (explicit revisions)
4-
//@[next] known-bug: rust-lang/trait-system-refactor-initiative#46
5-
//@[next] check-pass
64

75
//! Regression test for https://github.com/rust-lang/rust/issues/62211
86
//!
@@ -24,10 +22,11 @@ trait UncheckedCopy: Sized {
2422
// This Output is said to be Copy. Yet we default to Self
2523
// and it's accepted, not knowing if Self ineed is Copy
2624
type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
27-
//[current]~^ ERROR the trait bound `Self: Copy` is not satisfied
28-
//[current]~| ERROR the trait bound `Self: Deref` is not satisfied
29-
//[current]~| ERROR cannot add-assign `&'static str` to `Self`
30-
//[current]~| ERROR `Self` doesn't implement `std::fmt::Display`
25+
//~^ ERROR the trait bound `Self: Copy` is not satisfied
26+
//~| ERROR the trait bound `Self: Deref` is not satisfied
27+
//~| ERROR cannot add-assign `&'static str` to `Self`
28+
//~| ERROR `Self` doesn't implement `std::fmt::Display`
29+
//[next]~| ERROR type mismatch resolving `<Self as Deref>::Target == str`
3130

3231
// We said the Output type was Copy, so we can Copy it freely!
3332
fn unchecked_copy(other: &Self::Output) -> Self::Output {

tests/ui/associated-types/defaults-unsound-62211-2.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-2.rs:26:96
2+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:86
9+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:96
19+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:47
25+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:96
35+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:25
41+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:96
51+
--> $DIR/defaults-unsound-62211-2.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-2.rs:26:18
57+
--> $DIR/defaults-unsound-62211-2.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`
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,81 @@
1-
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
2-
--> $DIR/defaults-unsound-62211-2.rs:52:5
1+
error[E0277]: `Self` doesn't implement `std::fmt::Display`
2+
--> $DIR/defaults-unsound-62211-2.rs:24:96
33
|
4-
LL | drop(origin);
5-
| ^^^^^------^
6-
| |
7-
| argument has type `<T as UncheckedCopy>::Output`
4+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
5+
| ^^^^ `Self` cannot be formatted with the default formatter
86
|
9-
= note: `#[warn(dropping_copy_types)]` on by default
10-
help: use `let _ = ...` to ignore the expression or result
7+
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
8+
note: required by a bound in `UncheckedCopy::Output`
9+
--> $DIR/defaults-unsound-62211-2.rs:24:86
1110
|
12-
LL - drop(origin);
13-
LL + let _ = origin;
11+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
12+
| ^^^^^^^ required by this bound in `UncheckedCopy::Output`
13+
help: consider further restricting `Self`
1414
|
15+
LL | trait UncheckedCopy: Sized + std::fmt::Display {
16+
| +++++++++++++++++++
1517

16-
warning: 1 warning emitted
18+
error[E0277]: cannot add-assign `&'static str` to `Self`
19+
--> $DIR/defaults-unsound-62211-2.rs:24:96
20+
|
21+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
22+
| ^^^^ no implementation for `Self += &'static str`
23+
|
24+
note: required by a bound in `UncheckedCopy::Output`
25+
--> $DIR/defaults-unsound-62211-2.rs:24:47
26+
|
27+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
28+
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
29+
help: consider further restricting `Self`
30+
|
31+
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
32+
| +++++++++++++++++++++++++
33+
34+
error[E0271]: type mismatch resolving `<Self as Deref>::Target == str`
35+
--> $DIR/defaults-unsound-62211-2.rs:24:96
36+
|
37+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
38+
| ^^^^ types differ
39+
|
40+
note: required by a bound in `UncheckedCopy::Output`
41+
--> $DIR/defaults-unsound-62211-2.rs:24:31
42+
|
43+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
44+
| ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
45+
46+
error[E0277]: the trait bound `Self: Deref` is not satisfied
47+
--> $DIR/defaults-unsound-62211-2.rs:24:96
48+
|
49+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
50+
| ^^^^ the trait `Deref` is not implemented for `Self`
51+
|
52+
note: required by a bound in `UncheckedCopy::Output`
53+
--> $DIR/defaults-unsound-62211-2.rs:24:25
54+
|
55+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
56+
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
57+
help: consider further restricting `Self`
58+
|
59+
LL | trait UncheckedCopy: Sized + Deref {
60+
| +++++++
61+
62+
error[E0277]: the trait bound `Self: Copy` is not satisfied
63+
--> $DIR/defaults-unsound-62211-2.rs:24:96
64+
|
65+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
66+
| ^^^^ the trait `Copy` is not implemented for `Self`
67+
|
68+
note: required by a bound in `UncheckedCopy::Output`
69+
--> $DIR/defaults-unsound-62211-2.rs:24:18
70+
|
71+
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
72+
| ^^^^ required by this bound in `UncheckedCopy::Output`
73+
help: consider further restricting `Self`
74+
|
75+
LL | trait UncheckedCopy: Sized + Copy {
76+
| ++++++
77+
78+
error: aborting due to 5 previous errors
1779

80+
Some errors have detailed explanations: E0271, E0277.
81+
For more information about an error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)