Skip to content

Commit b5405d8

Browse files
authored
Unrolled build for rust-lang#140672
Rollup merge of rust-lang#140672 - compiler-errors:deeply-normalize, r=lcnr Deeply normalize in the new solver in WF We need to deeply normalize types we check for well-formedness, since we only collect implied bounds from normalized signature types. Fixes rust-lang/trait-system-refactor-initiative#194 r? lcnr
2 parents 2e6882a + 12d3021 commit b5405d8

13 files changed

+137
-64
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+39-8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,36 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
7676
)
7777
}
7878

79+
/// Convenience function to *deeply* normalize during wfcheck. In the old solver,
80+
/// this just dispatches to [`WfCheckingCtxt::normalize`], but in the new solver
81+
/// this calls `deeply_normalize` and reports errors if they are encountered.
82+
///
83+
/// This function should be called in favor of `normalize` in cases where we will
84+
/// then check the well-formedness of the type, since we only use the normalized
85+
/// signature types for implied bounds when checking regions.
86+
// FIXME(-Znext-solver): This should be removed when we compute implied outlives
87+
// bounds using the unnormalized signature of the function we're checking.
88+
fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
89+
where
90+
T: TypeFoldable<TyCtxt<'tcx>>,
91+
{
92+
if self.infcx.next_trait_solver() {
93+
match self.ocx.deeply_normalize(
94+
&ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)),
95+
self.param_env,
96+
value.clone(),
97+
) {
98+
Ok(value) => value,
99+
Err(errors) => {
100+
self.infcx.err_ctxt().report_fulfillment_errors(errors);
101+
value
102+
}
103+
}
104+
} else {
105+
self.normalize(span, loc, value)
106+
}
107+
}
108+
79109
fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) {
80110
let cause = traits::ObligationCause::new(
81111
span,
@@ -297,7 +327,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
297327
{
298328
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
299329
let ty = tcx.type_of(def_id).instantiate_identity();
300-
let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
330+
let item_ty =
331+
wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
301332
wfcx.register_wf_obligation(
302333
hir_ty.span,
303334
Some(WellFormedLoc::Ty(def_id)),
@@ -1073,7 +1104,7 @@ fn check_associated_item(
10731104
match item.kind {
10741105
ty::AssocKind::Const { .. } => {
10751106
let ty = tcx.type_of(item.def_id).instantiate_identity();
1076-
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
1107+
let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
10771108
wfcx.register_wf_obligation(span, loc, ty.into());
10781109
check_sized_if_body(
10791110
wfcx,
@@ -1102,7 +1133,7 @@ fn check_associated_item(
11021133
}
11031134
if item.defaultness(tcx).has_value() {
11041135
let ty = tcx.type_of(item.def_id).instantiate_identity();
1105-
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
1136+
let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
11061137
wfcx.register_wf_obligation(span, loc, ty.into());
11071138
}
11081139
Ok(())
@@ -1149,7 +1180,7 @@ fn check_type_defn<'tcx>(
11491180
let field_id = field.did.expect_local();
11501181
let hir::FieldDef { ty: hir_ty, .. } =
11511182
tcx.hir_node_by_def_id(field_id).expect_field();
1152-
let ty = wfcx.normalize(
1183+
let ty = wfcx.deeply_normalize(
11531184
hir_ty.span,
11541185
None,
11551186
tcx.type_of(field.did).instantiate_identity(),
@@ -1310,7 +1341,7 @@ fn check_item_type(
13101341

13111342
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
13121343
let ty = tcx.type_of(item_id).instantiate_identity();
1313-
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
1344+
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
13141345

13151346
let forbid_unsized = match unsized_handling {
13161347
UnsizedHandling::Forbid => true,
@@ -1375,7 +1406,7 @@ fn check_impl<'tcx>(
13751406
// other `Foo` impls are incoherent.
13761407
tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
13771408
let trait_span = hir_trait_ref.path.span;
1378-
let trait_ref = wfcx.normalize(
1409+
let trait_ref = wfcx.deeply_normalize(
13791410
trait_span,
13801411
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
13811412
trait_ref,
@@ -1435,7 +1466,7 @@ fn check_impl<'tcx>(
14351466
}
14361467
None => {
14371468
let self_ty = tcx.type_of(item.owner_id).instantiate_identity();
1438-
let self_ty = wfcx.normalize(
1469+
let self_ty = wfcx.deeply_normalize(
14391470
item.span,
14401471
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
14411472
self_ty,
@@ -1640,7 +1671,7 @@ fn check_fn_or_method<'tcx>(
16401671

16411672
sig.inputs_and_output =
16421673
tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
1643-
wfcx.normalize(
1674+
wfcx.deeply_normalize(
16441675
arg_span(idx),
16451676
Some(WellFormedLoc::Param {
16461677
function: def_id,

tests/ui/associated-inherent-types/bugs/wf-check-skipped.next.stderr

-13
This file was deleted.

tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//@ revisions: current next
22
//@[next] compile-flags: -Znext-solver
33
//@ ignore-compare-mode-next-solver (explicit revisions)
4-
//@[current] known-bug: #100041
5-
//@[current] check-pass
4+
//@ known-bug: #100041
5+
//@ check-pass
66
// FIXME(inherent_associated_types): This should fail.
77

88
#![feature(inherent_associated_types)]
@@ -15,4 +15,3 @@ impl Foo {
1515
}
1616

1717
fn main() -> Foo::Bar::<Vec<[u32]>> {}
18-
//[next]~^ ERROR the size for values of type `[u32]` cannot be known at compilation time

tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ LL | type Loop = Loop;
77
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
88

99
error[E0275]: overflow normalizing the type alias `Loop`
10-
--> $DIR/inherent-impls-overflow.rs:10:1
10+
--> $DIR/inherent-impls-overflow.rs:12:1
1111
|
1212
LL | impl Loop {}
1313
| ^^^^^^^^^^^^
1414
|
1515
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
1616

1717
error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
18-
--> $DIR/inherent-impls-overflow.rs:14:17
18+
--> $DIR/inherent-impls-overflow.rs:17:17
1919
|
2020
LL | type Poly0<T> = Poly1<(T,)>;
2121
| ^^^^^^^^^^^
2222
|
2323
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
2424

2525
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
26-
--> $DIR/inherent-impls-overflow.rs:17:17
26+
--> $DIR/inherent-impls-overflow.rs:21:17
2727
|
2828
LL | type Poly1<T> = Poly0<(T,)>;
2929
| ^^^^^^^^^^^
3030
|
3131
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
3232

3333
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
34-
--> $DIR/inherent-impls-overflow.rs:21:1
34+
--> $DIR/inherent-impls-overflow.rs:26:1
3535
|
3636
LL | impl Poly0<()> {}
3737
| ^^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
error[E0271]: type mismatch resolving `Loop normalizes-to _`
2-
--> $DIR/inherent-impls-overflow.rs:10:6
2+
--> $DIR/inherent-impls-overflow.rs:8:13
3+
|
4+
LL | type Loop = Loop;
5+
| ^^^^ types differ
6+
7+
error[E0271]: type mismatch resolving `Loop normalizes-to _`
8+
--> $DIR/inherent-impls-overflow.rs:12:1
9+
|
10+
LL | impl Loop {}
11+
| ^^^^^^^^^^^^ types differ
12+
13+
error[E0271]: type mismatch resolving `Loop normalizes-to _`
14+
--> $DIR/inherent-impls-overflow.rs:12:6
315
|
416
LL | impl Loop {}
517
| ^^^^ types differ
618

19+
error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
20+
--> $DIR/inherent-impls-overflow.rs:17:17
21+
|
22+
LL | type Poly0<T> = Poly1<(T,)>;
23+
| ^^^^^^^^^^^
24+
|
25+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
26+
727
error: type parameter `T` is only used recursively
8-
--> $DIR/inherent-impls-overflow.rs:14:24
28+
--> $DIR/inherent-impls-overflow.rs:17:24
929
|
1030
LL | type Poly0<T> = Poly1<(T,)>;
1131
| - ^
@@ -15,8 +35,16 @@ LL | type Poly0<T> = Poly1<(T,)>;
1535
= help: consider removing `T` or referring to it in the body of the type alias
1636
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
1737

38+
error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
39+
--> $DIR/inherent-impls-overflow.rs:21:17
40+
|
41+
LL | type Poly1<T> = Poly0<(T,)>;
42+
| ^^^^^^^^^^^
43+
|
44+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
45+
1846
error: type parameter `T` is only used recursively
19-
--> $DIR/inherent-impls-overflow.rs:17:24
47+
--> $DIR/inherent-impls-overflow.rs:21:24
2048
|
2149
LL | type Poly1<T> = Poly0<(T,)>;
2250
| - ^
@@ -27,14 +55,22 @@ LL | type Poly1<T> = Poly0<(T,)>;
2755
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
2856

2957
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
30-
--> $DIR/inherent-impls-overflow.rs:21:6
58+
--> $DIR/inherent-impls-overflow.rs:26:1
59+
|
60+
LL | impl Poly0<()> {}
61+
| ^^^^^^^^^^^^^^^^^
62+
|
63+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
64+
65+
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
66+
--> $DIR/inherent-impls-overflow.rs:26:6
3167
|
3268
LL | impl Poly0<()> {}
3369
| ^^^^^^^^^
3470
|
3571
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
3672

37-
error: aborting due to 4 previous errors
73+
error: aborting due to 9 previous errors
3874

3975
Some errors have detailed explanations: E0271, E0275.
4076
For more information about an error, try `rustc --explain E0271`.

tests/ui/lazy-type-alias/inherent-impls-overflow.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,27 @@
55
#![feature(lazy_type_alias)]
66
#![allow(incomplete_features)]
77

8-
type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop`
8+
type Loop = Loop;
9+
//[current]~^ ERROR overflow normalizing the type alias `Loop`
10+
//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
911

1012
impl Loop {}
1113
//[current]~^ ERROR overflow normalizing the type alias `Loop`
1214
//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
15+
//[next]~| ERROR type mismatch resolving `Loop normalizes-to _`
1316

1417
type Poly0<T> = Poly1<(T,)>;
1518
//[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
1619
//[next]~^^ ERROR type parameter `T` is only used recursively
20+
//[next]~| ERROR overflow evaluating the requirement
1721
type Poly1<T> = Poly0<(T,)>;
1822
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
1923
//[next]~^^ ERROR type parameter `T` is only used recursively
24+
//[next]~| ERROR overflow evaluating the requirement
2025

2126
impl Poly0<()> {}
2227
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
2328
//[next]~^^ ERROR overflow evaluating the requirement `Poly0<()> == _`
29+
//[next]~| ERROR overflow evaluating the requirement
2430

2531
fn main() {}

tests/ui/traits/next-solver/dont-ice-on-bad-transmute-in-typeck.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
2-
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:11
2+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:22
33
|
44
LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
66
|
77
help: this trait has no implementations, consider adding one
88
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1

tests/ui/traits/next-solver/issue-118950-root-region.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ impl<T> Overlap<T> for T {}
1919
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
2020
//~^ ERROR cannot find type `Missing` in this scope
2121
//~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
22+
//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
2223

2324
fn main() {}

tests/ui/traits/next-solver/issue-118950-root-region.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ LL | trait ToUnit<'a> {
2626
| ^^^^^^^^^^^^^^^^
2727

2828
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
29+
error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
30+
--> $DIR/issue-118950-root-region.rs:19:9
31+
|
32+
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
34+
|
35+
help: this trait has no implementations, consider adding one
36+
--> $DIR/issue-118950-root-region.rs:8:1
37+
|
38+
LL | trait ToUnit<'a> {
39+
| ^^^^^^^^^^^^^^^^
40+
2941
error[E0277]: the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
3042
--> $DIR/issue-118950-root-region.rs:19:47
3143
|
@@ -37,7 +49,7 @@ help: consider further restricting type parameter `T` with trait `Overlap`
3749
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
3850
| ++++++++++++++++++++++++++++++++++++++
3951

40-
error: aborting due to 3 previous errors; 1 warning emitted
52+
error: aborting due to 4 previous errors; 1 warning emitted
4153

4254
Some errors have detailed explanations: E0277, E0412.
4355
For more information about an error, try `rustc --explain E0277`.

tests/ui/traits/next-solver/non-wf-in-coerce-pointers.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `(): Wf` is not satisfied
2-
--> $DIR/non-wf-in-coerce-pointers.rs:8:17
2+
--> $DIR/non-wf-in-coerce-pointers.rs:8:8
33
|
44
LL | f: &'static <() as Wf>::Assoc,
5-
| ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
66
|
77
help: this trait has no implementations, consider adding one
88
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@ check-pass
5+
6+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/194>.
7+
// Ensure that we check the well-formedness of `<Check as Mode>::Output<T>` after normalizing
8+
// the type to `()`, since we only imply outlives bounds from the normalized signature, so we
9+
// don't know (e.g.) that `&mut T` is WF.
10+
11+
12+
trait Mode {
13+
type Output<T>;
14+
fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T>;
15+
}
16+
17+
struct Check;
18+
19+
impl Mode for Check {
20+
type Output<T> = ();
21+
fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T> {}
22+
}
23+
24+
fn main() {}

0 commit comments

Comments
 (0)