Skip to content

Commit dbacfbc

Browse files
committed
Add a new normalization query just for mir constants
1 parent c7c39ce commit dbacfbc

File tree

19 files changed

+128
-34
lines changed

19 files changed

+128
-34
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
@@ -2410,7 +2410,8 @@ pub struct Constant<'tcx> {
24102410
pub literal: ConstantKind<'tcx>,
24112411
}
24122412

2413-
#[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2413+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2414+
#[derive(Lift)]
24142415
pub enum ConstantKind<'tcx> {
24152416
/// This constant came from the type system
24162417
Ty(&'tcx ty::Const<'tcx>),
@@ -2709,7 +2710,13 @@ impl<'tcx> Display for Constant<'tcx> {
27092710
ty::FnDef(..) => {}
27102711
_ => write!(fmt, "const ")?,
27112712
}
2712-
match self.literal {
2713+
Display::fmt(&self.literal, fmt)
2714+
}
2715+
}
2716+
2717+
impl<'tcx> Display for ConstantKind<'tcx> {
2718+
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2719+
match *self {
27132720
ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
27142721
ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
27152722
}

compiler/rustc_middle/src/mir/type_foldable.rs

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

350350
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
351+
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
352+
folder.fold_mir_const(self)
353+
}
354+
351355
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
352356
match self {
353357
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
@@ -1482,6 +1482,13 @@ rustc_queries! {
14821482
desc { "normalizing `{}`", goal.value }
14831483
}
14841484

1485+
/// Do not call this query directly: invoke `normalize_erasing_regions` instead.
1486+
query normalize_mir_const_after_erasing_regions(
1487+
goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
1488+
) -> mir::ConstantKind<'tcx> {
1489+
desc { "normalizing `{}`", goal.value }
1490+
}
1491+
14851492
query implied_outlives_bounds(
14861493
goal: CanonicalTyGoal<'tcx>
14871494
) -> 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;
@@ -179,6 +180,10 @@ pub trait TypeFolder<'tcx>: Sized {
179180
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
180181
c.super_fold_with(self)
181182
}
183+
184+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
185+
bug!("most type folders should not be folding MIR datastructures: {:?}", c)
186+
}
182187
}
183188

184189
pub trait TypeVisitor<'tcx>: Sized {

compiler/rustc_middle/src/ty/normalize_erasing_regions.rs

Lines changed: 6 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,9 @@ 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+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
107+
let arg = self.param_env.and(c);
108+
self.tcx.normalize_mir_const_after_erasing_regions(arg)
109+
}
104110
}

compiler/rustc_middle/src/ty/subst.rs

Lines changed: 5 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};
@@ -503,6 +504,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
503504
c.super_fold_with(self)
504505
}
505506
}
507+
508+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
509+
c.super_fold_with(self)
510+
}
506511
}
507512

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

compiler/rustc_mir/src/monomorphize/collector.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
184184
use rustc_hir::itemlikevisit::ItemLikeVisitor;
185185
use rustc_hir::lang_items::LangItem;
186186
use rustc_index::bit_set::GrowableBitSet;
187-
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
188187
use rustc_middle::mir::interpret::{AllocId, ConstValue};
189188
use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
190189
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
@@ -193,6 +192,7 @@ use rustc_middle::mir::{self, Local, Location};
193192
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
194193
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
195194
use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
195+
use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext};
196196
use rustc_session::config::EntryFnType;
197197
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
198198
use smallvec::SmallVec;
@@ -638,6 +638,35 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
638638
self.super_rvalue(rvalue, location);
639639
}
640640

641+
/// This does not walk the constant, as it has been handled entirely here and trying
642+
/// to walk it would attempt to evaluate the `ty::Const` inside, which doesn't necessarily
643+
/// work, as some constants cannot be represented in the type system.
644+
fn visit_constant(&mut self, constant: &mir::Constant<'tcx>, location: Location) {
645+
let literal = self.monomorphize(constant.literal);
646+
let val = match literal {
647+
mir::ConstantKind::Val(val, _) => val,
648+
mir::ConstantKind::Ty(ct) => match ct.val {
649+
ty::ConstKind::Value(val) => val,
650+
ty::ConstKind::Unevaluated(ct) => {
651+
let param_env = ty::ParamEnv::reveal_all();
652+
match self.tcx.const_eval_resolve(param_env, ct, None) {
653+
// The `monomorphize` call should have evaluated that constant already.
654+
Ok(val) => val,
655+
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => return,
656+
Err(ErrorHandled::TooGeneric) => span_bug!(
657+
self.body.source_info(location).span,
658+
"collection encountered polymorphic constant: {:?}",
659+
literal
660+
),
661+
}
662+
}
663+
_ => return,
664+
},
665+
};
666+
collect_const_value(self.tcx, val, self.output);
667+
self.visit_ty(literal.ty(), TyContext::Location(location));
668+
}
669+
641670
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) {
642671
debug!("visiting const {:?} @ {:?}", *constant, location);
643672

compiler/rustc_mir/src/util/pretty.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,11 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
452452
match literal {
453453
ConstantKind::Ty(literal) => self.push(&format!("+ literal: {:?}", literal)),
454454
ConstantKind::Val(val, ty) => {
455-
self.push(&format!("+ literal: {:?}, {}", val, ty))
455+
// To keep the diffs small, we render this almost like we render ty::Const
456+
self.push(&format!(
457+
"+ literal: Const {{ ty: {}, val: Value({:?}) }}",
458+
ty, val
459+
))
456460
}
457461
}
458462
}

0 commit comments

Comments
 (0)