Rollup merge of #130645 - compiler-errors:normalize-gce-writeback, r=BoxyUwU
Normalize consts in writeback when GCE is enabled GCE lazily normalizes its unevaluated consts. This PR ensures that, like the new solver with its lazy norm types, we can assume that the writeback results are fully normalized. This is important since we're trying to eliminate unnecessary calls to `ty::Const::{eval,normalize}` since they won't work with mGCE. Previously, we'd keep those consts unnormalized in writeback all the way through MIR build, and they'd only get normalized if we explicitly called `ty::Const::{eval,normalize}`, or during codegen since that calls `normalize_erasing_regions` (which invokes the `QueryNormalizer`, which evaluates the const accordingly). This hack can (hopefully obviously) be removed when mGCE is implemented and we yeet the old GCE; it's only reachable with the GCE flag anyways, so I'm not worried about the implications here. r? `@BoxyUwU`
This commit is contained in:
commit
e6cf3bd267
@ -11,7 +11,6 @@
|
||||
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind};
|
||||
use rustc_infer::infer;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
||||
@ -2413,17 +2412,7 @@ fn check_array_pat_len(
|
||||
len: ty::Const<'tcx>,
|
||||
min_len: u64,
|
||||
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
|
||||
let len = match len.eval(self.tcx, self.param_env, span) {
|
||||
Ok((_, val)) => val
|
||||
.try_to_scalar()
|
||||
.and_then(|scalar| scalar.try_to_scalar_int().ok())
|
||||
.map(|int| int.to_target_usize(self.tcx)),
|
||||
Err(ErrorHandled::Reported(..)) => {
|
||||
let guar = self.error_scrutinee_unfixed_length(span);
|
||||
return (Some(Ty::new_error(self.tcx, guar)), arr_ty);
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(..)) => None,
|
||||
};
|
||||
let len = len.try_eval_target_usize(self.tcx, self.param_env);
|
||||
|
||||
let guar = if let Some(len) = len {
|
||||
// Now we know the length...
|
||||
|
@ -803,7 +803,7 @@ fn handle_term<T>(
|
||||
// We must deeply normalize in the new solver, since later lints
|
||||
// expect that types that show up in the typeck are fully
|
||||
// normalized.
|
||||
let value = if self.should_normalize {
|
||||
let mut value = if self.should_normalize {
|
||||
let body_id = tcx.hir().body_owner_def_id(self.body.id());
|
||||
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
|
||||
let at = self.fcx.at(&cause, self.fcx.param_env);
|
||||
@ -818,12 +818,27 @@ fn handle_term<T>(
|
||||
value
|
||||
};
|
||||
|
||||
// Bail if there are any non-region infer.
|
||||
if value.has_non_region_infer() {
|
||||
let guar = self.report_error(value);
|
||||
new_err(tcx, guar)
|
||||
} else {
|
||||
tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
|
||||
value = new_err(tcx, guar);
|
||||
}
|
||||
|
||||
// Erase the regions from the ty, since it's not really meaningful what
|
||||
// these region values are; there's not a trivial correspondence between
|
||||
// regions in the HIR and MIR, so when we turn the body into MIR, there's
|
||||
// no reason to keep regions around. They will be repopulated during MIR
|
||||
// borrowck, and specifically region constraints will be populated during
|
||||
// MIR typeck which is run on the new body.
|
||||
value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
|
||||
|
||||
// Normalize consts in writeback, because GCE doesn't normalize eagerly.
|
||||
if tcx.features().generic_const_exprs {
|
||||
value =
|
||||
value.fold_with(&mut EagerlyNormalizeConsts { tcx, param_env: self.fcx.param_env });
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
@ -858,3 +873,17 @@ fn fold_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ty::Predicate<'t
|
||||
predicate
|
||||
}
|
||||
}
|
||||
|
||||
struct EagerlyNormalizeConsts<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
impl EntriesBuffer {
|
||||
fn a(&self) -> impl Iterator {
|
||||
self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
|
||||
//~| ERROR captures lifetime that does not appear in bounds
|
||||
self.0.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0425]: cannot find value `HashesEntryLEN` in this scope
|
||||
--> $DIR/issue-109141.rs:11:32
|
||||
--> $DIR/issue-109141.rs:10:32
|
||||
|
|
||||
LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
|
||||
| ^^^^^^^^^^^^^^ not found in this scope
|
||||
@ -9,33 +9,6 @@ help: you might be missing a const parameter
|
||||
LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
|
||||
| ++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
|
||||
--> $DIR/issue-109141.rs:6:9
|
||||
|
|
||||
LL | self.0.iter_mut()
|
||||
| ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||
|
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | fn a(&mut self) -> impl Iterator {
|
||||
| ~~~~~~~~~
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds
|
||||
--> $DIR/issue-109141.rs:6:9
|
||||
|
|
||||
LL | fn a(&self) -> impl Iterator {
|
||||
| ----- ------------- opaque type defined here
|
||||
| |
|
||||
| hidden type `std::slice::IterMut<'_, [u8; {const error}]>` captures the anonymous lifetime defined here
|
||||
LL | self.0.iter_mut()
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: add a `use<...>` bound to explicitly capture `'_`
|
||||
|
|
||||
LL | fn a(&self) -> impl Iterator + use<'_> {
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0596, E0700.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
@ -2,7 +2,6 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Foo = impl Sized;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
fn with_bound<const N: usize>() -> Foo
|
||||
where
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque_type.rs:11:17
|
||||
--> $DIR/opaque_type.rs:10:17
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ---------- the found opaque type
|
||||
@ -11,20 +11,12 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
|
||||
found opaque type `Foo`
|
||||
|
||||
error[E0605]: non-primitive cast: `usize` as `Foo`
|
||||
--> $DIR/opaque_type.rs:11:17
|
||||
--> $DIR/opaque_type.rs:10:17
|
||||
|
|
||||
LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
|
||||
| ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/opaque_type.rs:4:12
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0605.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
@ -4,7 +4,7 @@
|
||||
fn something(path: [usize; N]) -> impl Clone {
|
||||
//~^ ERROR cannot find value `N` in this scope
|
||||
match path {
|
||||
[] => 0, //~ ERROR cannot pattern-match on an array without a fixed length
|
||||
[] => 0,
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
@ -9,13 +9,6 @@ help: you might be missing a const parameter
|
||||
LL | fn something<const N: /* Type */>(path: [usize; N]) -> impl Clone {
|
||||
| +++++++++++++++++++++
|
||||
|
||||
error[E0730]: cannot pattern-match on an array without a fixed length
|
||||
--> $DIR/issue-116186.rs:7:9
|
||||
|
|
||||
LL | [] => 0,
|
||||
| ^^
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0730.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
Loading…
Reference in New Issue
Block a user