Auto merge of #83207 - oli-obk:valtree2, r=lcnr
normalize mir::Constant differently from ty::Const in preparation for valtrees Valtrees are unable to represent many kind of constant values (this is on purpose). For constants that are used at runtime, we do not need a valtree representation and can thus use a different form of evaluation. In order to make this explicit and less fragile, I added a `fold_constant` method to `TypeFolder` and implemented it for normalization. Normalization can now, when it wants to eagerly evaluate a constant, normalize `mir::Constant` directly into a `mir::ConstantKind::Val` instead of relying on the `ty::Const` evaluation. In the future we can get rid of the `ty::Const` in there entirely and add our own `Unevaluated` variant to `mir::ConstantKind`. This would allow us to remove the `promoted` field from `ty::ConstKind::Unevaluated`, as promoteds can never occur in the type system. cc `@rust-lang/wg-const-eval` r? `@lcnr`
This commit is contained in:
commit
0978a9eb99
41 changed files with 183 additions and 55 deletions
|
@ -1,24 +1,35 @@
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::subst::GenericArg;
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable};
|
||||
use rustc_trait_selection::traits::query::normalize::AtExt;
|
||||
use rustc_trait_selection::traits::{Normalized, ObligationCause};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
crate fn provide(p: &mut Providers) {
|
||||
*p = Providers { normalize_generic_arg_after_erasing_regions, ..*p };
|
||||
*p = Providers {
|
||||
normalize_generic_arg_after_erasing_regions: |tcx, goal| {
|
||||
debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal);
|
||||
|
||||
tcx.sess
|
||||
.perf_stats
|
||||
.normalize_generic_arg_after_erasing_regions
|
||||
.fetch_add(1, Ordering::Relaxed);
|
||||
normalize_after_erasing_regions(tcx, goal)
|
||||
},
|
||||
normalize_mir_const_after_erasing_regions: |tcx, goal| {
|
||||
normalize_after_erasing_regions(tcx, goal)
|
||||
},
|
||||
..*p
|
||||
};
|
||||
}
|
||||
|
||||
fn normalize_generic_arg_after_erasing_regions<'tcx>(
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>,
|
||||
) -> GenericArg<'tcx> {
|
||||
debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal);
|
||||
|
||||
goal: ParamEnvAnd<'tcx, T>,
|
||||
) -> T {
|
||||
let ParamEnvAnd { param_env, value } = goal;
|
||||
tcx.sess.perf_stats.normalize_generic_arg_after_erasing_regions.fetch_add(1, Ordering::Relaxed);
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let cause = ObligationCause::dummy();
|
||||
match infcx.at(&cause, param_env).normalize(value) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue