Skip to content

Commit 0978a9e

Browse files
committed
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`
2 parents 5662d93 + c6676db commit 0978a9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+183
-55
lines changed

compiler/rustc_infer/src/infer/resolve.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
22
use super::{FixupError, FixupResult, InferCtxt, Span};
3+
use rustc_middle::mir;
34
use rustc_middle::ty::fold::{TypeFolder, TypeVisitor};
45
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
56

@@ -46,6 +47,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
4647
ct.super_fold_with(self)
4748
}
4849
}
50+
51+
fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
52+
constant.super_fold_with(self)
53+
}
4954
}
5055

5156
/// The opportunistic region resolver opportunistically resolves regions

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,7 +2392,8 @@ pub struct Constant<'tcx> {
23922392
pub literal: ConstantKind<'tcx>,
23932393
}
23942394

2395-
#[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2395+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2396+
#[derive(Lift)]
23962397
pub enum ConstantKind<'tcx> {
23972398
/// This constant came from the type system
23982399
Ty(&'tcx ty::Const<'tcx>),
@@ -2691,7 +2692,13 @@ impl<'tcx> Display for Constant<'tcx> {
26912692
ty::FnDef(..) => {}
26922693
_ => write!(fmt, "const ")?,
26932694
}
2694-
match self.literal {
2695+
Display::fmt(&self.literal, fmt)
2696+
}
2697+
}
2698+
2699+
impl<'tcx> Display for ConstantKind<'tcx> {
2700+
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2701+
match *self {
26952702
ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
26962703
ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
26972704
}

compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
348348
}
349349

350350
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
351+
#[inline(always)]
352+
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
353+
folder.fold_mir_const(self)
354+
}
355+
351356
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
352357
match self {
353358
ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)),

compiler/rustc_middle/src/query/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,13 @@ rustc_queries! {
14861486
desc { "normalizing `{}`", goal.value }
14871487
}
14881488

1489+
/// Do not call this query directly: invoke `normalize_erasing_regions` instead.
1490+
query normalize_mir_const_after_erasing_regions(
1491+
goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
1492+
) -> mir::ConstantKind<'tcx> {
1493+
desc { "normalizing `{}`", goal.value }
1494+
}
1495+
14891496
query implied_outlives_bounds(
14901497
goal: CanonicalTyGoal<'tcx>
14911498
) -> Result<

compiler/rustc_middle/src/ty/erase_regions.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::mir;
12
use crate::ty::fold::{TypeFoldable, TypeFolder};
23
use crate::ty::{self, Ty, TyCtxt, TypeFlags};
34

@@ -65,4 +66,8 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
6566
_ => self.tcx.lifetimes.re_erased,
6667
}
6768
}
69+
70+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
71+
c.super_fold_with(self)
72+
}
6873
}

compiler/rustc_middle/src/ty/fold.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
//!
3131
//! These methods return true to indicate that the visitor has found what it is
3232
//! looking for, and does not need to visit anything else.
33+
use crate::mir;
3334
use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
3435
use rustc_hir as hir;
3536
use rustc_hir::def_id::DefId;
@@ -180,6 +181,10 @@ pub trait TypeFolder<'tcx>: Sized {
180181
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
181182
c.super_fold_with(self)
182183
}
184+
185+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
186+
bug!("most type folders should not be folding MIR datastructures: {:?}", c)
187+
}
183188
}
184189

185190
pub trait TypeVisitor<'tcx>: Sized {

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ impl<'tcx> Instance<'tcx> {
483483
if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { *v }
484484
}
485485

486+
#[inline(always)]
486487
pub fn subst_mir_and_normalize_erasing_regions<T>(
487488
&self,
488489
tcx: TyCtxt<'tcx>,

compiler/rustc_middle/src/ty/normalize_erasing_regions.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//! `normalize_generic_arg_after_erasing_regions` query for each type
88
//! or constant found within. (This underlying query is what is cached.)
99
10+
use crate::mir;
1011
use crate::ty::fold::{TypeFoldable, TypeFolder};
1112
use crate::ty::subst::{Subst, SubstsRef};
1213
use crate::ty::{self, Ty, TyCtxt};
@@ -101,4 +102,10 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
101102
let arg = self.param_env.and(c.into());
102103
self.tcx.normalize_generic_arg_after_erasing_regions(arg).expect_const()
103104
}
105+
106+
#[inline]
107+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
108+
let arg = self.param_env.and(c);
109+
self.tcx.normalize_mir_const_after_erasing_regions(arg)
110+
}
104111
}

compiler/rustc_middle/src/ty/subst.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Type substitutions.
22

3+
use crate::mir;
34
use crate::ty::codec::{TyDecoder, TyEncoder};
45
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
56
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
@@ -506,6 +507,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
506507
c.super_fold_with(self)
507508
}
508509
}
510+
511+
#[inline]
512+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
513+
c.super_fold_with(self)
514+
}
509515
}
510516

511517
impl<'a, 'tcx> SubstFolder<'a, 'tcx> {

compiler/rustc_mir/src/const_eval/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn const_to_valtree_inner<'tcx>(
110110

111111
let variant = ecx.read_discriminant(&place.into()).unwrap().1;
112112

113-
branches(def.variants[variant].fields.len(), Some(variant))
113+
branches(def.variants[variant].fields.len(), def.is_enum().then_some(variant))
114114
}
115115

116116
ty::Never

0 commit comments

Comments
 (0)