Skip to content

Commit a9a8f79

Browse files
Normalize unevaluated consts in GCE
1 parent da88968 commit a9a8f79

File tree

5 files changed

+40
-48
lines changed

5 files changed

+40
-48
lines changed

compiler/rustc_hir_typeck/src/writeback.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
803803
// We must deeply normalize in the new solver, since later lints
804804
// expect that types that show up in the typeck are fully
805805
// normalized.
806-
let value = if self.should_normalize {
806+
let mut value = if self.should_normalize {
807807
let body_id = tcx.hir().body_owner_def_id(self.body.id());
808808
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
809809
let at = self.fcx.at(&cause, self.fcx.param_env);
@@ -818,12 +818,27 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
818818
value
819819
};
820820

821+
// Bail if there are any non-region infer.
821822
if value.has_non_region_infer() {
822823
let guar = self.report_error(value);
823-
new_err(tcx, guar)
824-
} else {
825-
tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
824+
value = new_err(tcx, guar);
825+
}
826+
827+
// Erase the regions from the ty, since it's not really meaningful what
828+
// these region values are; there's not a trivial correspondence between
829+
// regions in the HIR and MIR, so when we turn the body into MIR, there's
830+
// no reason to keep regions around. They will be repopulated during MIR
831+
// borrowck, and specifically region constraints will be populated during
832+
// MIR typeck which is run on the new body.
833+
value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
834+
835+
// Normalize consts in writeback, because GCE doesn't normalize eagerly.
836+
if tcx.features().generic_const_exprs {
837+
value =
838+
value.fold_with(&mut EagerlyNormalizeConsts { tcx, param_env: self.fcx.param_env });
826839
}
840+
841+
value
827842
}
828843
}
829844

@@ -858,3 +873,17 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
858873
predicate
859874
}
860875
}
876+
877+
struct EagerlyNormalizeConsts<'tcx> {
878+
tcx: TyCtxt<'tcx>,
879+
param_env: ty::ParamEnv<'tcx>,
880+
}
881+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
882+
fn cx(&self) -> TyCtxt<'tcx> {
883+
self.tcx
884+
}
885+
886+
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
887+
self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
888+
}
889+
}

tests/ui/const-generics/generic_const_exprs/issue-109141.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33

44
impl EntriesBuffer {
55
fn a(&self) -> impl Iterator {
6-
self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
7-
//~| ERROR captures lifetime that does not appear in bounds
6+
self.0.iter_mut()
87
}
98
}
109

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0425]: cannot find value `HashesEntryLEN` in this scope
2-
--> $DIR/issue-109141.rs:11:32
2+
--> $DIR/issue-109141.rs:10:32
33
|
44
LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
55
| ^^^^^^^^^^^^^^ not found in this scope
@@ -9,33 +9,6 @@ help: you might be missing a const parameter
99
LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
1010
| ++++++++++++++++++++++++++++++++++
1111

12-
error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
13-
--> $DIR/issue-109141.rs:6:9
14-
|
15-
LL | self.0.iter_mut()
16-
| ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
17-
|
18-
help: consider changing this to be a mutable reference
19-
|
20-
LL | fn a(&mut self) -> impl Iterator {
21-
| ~~~~~~~~~
22-
23-
error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds
24-
--> $DIR/issue-109141.rs:6:9
25-
|
26-
LL | fn a(&self) -> impl Iterator {
27-
| ----- ------------- opaque type defined here
28-
| |
29-
| hidden type `std::slice::IterMut<'_, [u8; {const error}]>` captures the anonymous lifetime defined here
30-
LL | self.0.iter_mut()
31-
| ^^^^^^^^^^^^^^^^^
32-
|
33-
help: add a `use<...>` bound to explicitly capture `'_`
34-
|
35-
LL | fn a(&self) -> impl Iterator + use<'_> {
36-
| +++++++++
37-
38-
error: aborting due to 3 previous errors
12+
error: aborting due to 1 previous error
3913

40-
Some errors have detailed explanations: E0425, E0596, E0700.
41-
For more information about an error, try `rustc --explain E0425`.
14+
For more information about this error, try `rustc --explain E0425`.

tests/ui/const-generics/generic_const_exprs/opaque_type.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#![allow(incomplete_features)]
33

44
type Foo = impl Sized;
5-
//~^ ERROR: unconstrained opaque type
65

76
fn with_bound<const N: usize>() -> Foo
87
where
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/opaque_type.rs:11:17
2+
--> $DIR/opaque_type.rs:10:17
33
|
44
LL | type Foo = impl Sized;
55
| ---------- the found opaque type
@@ -11,20 +11,12 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
1111
found opaque type `Foo`
1212

1313
error[E0605]: non-primitive cast: `usize` as `Foo`
14-
--> $DIR/opaque_type.rs:11:17
14+
--> $DIR/opaque_type.rs:10:17
1515
|
1616
LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
1717
| ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
1818

19-
error: unconstrained opaque type
20-
--> $DIR/opaque_type.rs:4:12
21-
|
22-
LL | type Foo = impl Sized;
23-
| ^^^^^^^^^^
24-
|
25-
= note: `Foo` must be used in combination with a concrete type within the same module
26-
27-
error: aborting due to 3 previous errors
19+
error: aborting due to 2 previous errors
2820

2921
Some errors have detailed explanations: E0308, E0605.
3022
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)