mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Normalize unevaluated consts in GCE
This commit is contained in:
parent
da889684c8
commit
a9a8f79f86
@ -803,7 +803,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
|||||||
// We must deeply normalize in the new solver, since later lints
|
// We must deeply normalize in the new solver, since later lints
|
||||||
// expect that types that show up in the typeck are fully
|
// expect that types that show up in the typeck are fully
|
||||||
// normalized.
|
// 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 body_id = tcx.hir().body_owner_def_id(self.body.id());
|
||||||
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
|
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
|
||||||
let at = self.fcx.at(&cause, self.fcx.param_env);
|
let at = self.fcx.at(&cause, self.fcx.param_env);
|
||||||
@ -818,12 +818,27 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
|||||||
value
|
value
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bail if there are any non-region infer.
|
||||||
if value.has_non_region_infer() {
|
if value.has_non_region_infer() {
|
||||||
let guar = self.report_error(value);
|
let guar = self.report_error(value);
|
||||||
new_err(tcx, guar)
|
value = new_err(tcx, guar);
|
||||||
} else {
|
|
||||||
tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
|
|||||||
predicate
|
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 {
|
impl EntriesBuffer {
|
||||||
fn a(&self) -> impl Iterator {
|
fn a(&self) -> impl Iterator {
|
||||||
self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
|
self.0.iter_mut()
|
||||||
//~| ERROR captures lifetime that does not appear in bounds
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0425]: cannot find value `HashesEntryLEN` in this scope
|
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]>);
|
LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
|
||||||
| ^^^^^^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^^^^^^ 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]>);
|
LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
|
||||||
| ++++++++++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
|
error: aborting due to 1 previous error
|
||||||
--> $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[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds
|
For more information about this error, try `rustc --explain E0425`.
|
||||||
--> $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`.
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
type Foo = impl Sized;
|
type Foo = impl Sized;
|
||||||
//~^ ERROR: unconstrained opaque type
|
|
||||||
|
|
||||||
fn with_bound<const N: usize>() -> Foo
|
fn with_bound<const N: usize>() -> Foo
|
||||||
where
|
where
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/opaque_type.rs:11:17
|
--> $DIR/opaque_type.rs:10:17
|
||||||
|
|
|
|
||||||
LL | type Foo = impl Sized;
|
LL | type Foo = impl Sized;
|
||||||
| ---------- the found opaque type
|
| ---------- the found opaque type
|
||||||
@ -11,20 +11,12 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
|
|||||||
found opaque type `Foo`
|
found opaque type `Foo`
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `usize` as `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];
|
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
|
| ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: aborting due to 2 previous errors
|
||||||
--> $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
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0605.
|
Some errors have detailed explanations: E0308, E0605.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
Loading…
Reference in New Issue
Block a user