Skip to content

Commit 43bd68e

Browse files
committed
Add Ty to mir::Const::Ty
1 parent 2c4a8fc commit 43bd68e

File tree

19 files changed

+81
-51
lines changed

19 files changed

+81
-51
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
346346
} else {
347347
let tcx = self.tcx();
348348
let maybe_uneval = match constant.const_ {
349-
Const::Ty(ct) => match ct.kind() {
349+
Const::Ty(_, ct) => match ct.kind() {
350350
ty::ConstKind::Unevaluated(_) => {
351351
bug!("should not encounter unevaluated Const::Ty here, got {:?}", ct)
352352
}
@@ -1856,7 +1856,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18561856

18571857
if let Operand::Constant(constant) = op {
18581858
let maybe_uneval = match constant.const_ {
1859-
Const::Val(..) | Const::Ty(_) => None,
1859+
Const::Val(..) | Const::Ty(_, _) => None,
18601860
Const::Unevaluated(uv, _) => Some(uv),
18611861
};
18621862

compiler/rustc_codegen_ssa/src/mir/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
4040
) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
4141
let uv = match self.monomorphize(constant.const_) {
4242
mir::Const::Unevaluated(uv, _) => uv.shrink(),
43-
mir::Const::Ty(c) => match c.kind() {
43+
mir::Const::Ty(_, c) => match c.kind() {
4444
// A constant that came from a const generic but was then used as an argument to old-style
4545
// simd_shuffle (passing as argument instead of as a generic param).
4646
rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)),

compiler/rustc_const_eval/src/check_consts/qualifs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,15 @@ where
357357

358358
// Check the qualifs of the value of `const` items.
359359
let uneval = match constant.const_ {
360-
Const::Ty(ct)
360+
Const::Ty(_, ct)
361361
if matches!(
362362
ct.kind(),
363363
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _)
364364
) =>
365365
{
366366
None
367367
}
368-
Const::Ty(c) => {
368+
Const::Ty(_, c) => {
369369
bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c)
370370
}
371371
Const::Unevaluated(uv, _) => Some(uv),

compiler/rustc_middle/src/mir/consts.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ pub enum Const<'tcx> {
204204
/// Any way of turning `ty::Const` into `ConstValue` should go through `valtree_to_const_val`;
205205
/// this ensures that we consistently produce "clean" values without data in the padding or
206206
/// anything like that.
207-
Ty(ty::Const<'tcx>),
207+
///
208+
/// FIXME(BoxyUwU): We should remove this `Ty` and look up the type for params via `ParamEnv`
209+
Ty(Ty<'tcx>, ty::Const<'tcx>),
208210

209211
/// An unevaluated mir constant which is not part of the type system.
210212
///
@@ -237,8 +239,15 @@ impl<'tcx> Const<'tcx> {
237239
#[inline(always)]
238240
pub fn ty(&self) -> Ty<'tcx> {
239241
match self {
240-
// THISPR
241-
Const::Ty(c) => todo!(),
242+
Const::Ty(ty, ct) => {
243+
match ct.kind() {
244+
// Dont use the outter ty as on invalid code we can wind up with them not being the same.
245+
// this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
246+
// was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
247+
ty::ConstKind::Value(ty, _) => ty,
248+
_ => *ty,
249+
}
250+
}
242251
Const::Val(_, ty) | Const::Unevaluated(_, ty) => *ty,
243252
}
244253
}
@@ -248,7 +257,7 @@ impl<'tcx> Const<'tcx> {
248257
#[inline]
249258
pub fn is_required_const(&self) -> bool {
250259
match self {
251-
Const::Ty(c) => match c.kind() {
260+
Const::Ty(_, c) => match c.kind() {
252261
ty::ConstKind::Value(_, _) => false, // already a value, cannot error
253262
_ => true,
254263
},
@@ -260,7 +269,7 @@ impl<'tcx> Const<'tcx> {
260269
#[inline]
261270
pub fn try_to_scalar(self) -> Option<Scalar> {
262271
match self {
263-
Const::Ty(c) => match c.kind() {
272+
Const::Ty(_, c) => match c.kind() {
264273
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
265274
// A valtree of a type where leaves directly represent the scalar const value.
266275
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
@@ -279,7 +288,7 @@ impl<'tcx> Const<'tcx> {
279288
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
280289
match self {
281290
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
282-
Const::Ty(c) => match c.kind() {
291+
Const::Ty(_, c) => match c.kind() {
283292
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
284293
Some(valtree.unwrap_leaf())
285294
}
@@ -307,7 +316,7 @@ impl<'tcx> Const<'tcx> {
307316
span: Span,
308317
) -> Result<ConstValue<'tcx>, ErrorHandled> {
309318
match self {
310-
Const::Ty(c) => {
319+
Const::Ty(_, c) => {
311320
// We want to consistently have a "clean" value for type system constants (i.e., no
312321
// data hidden in the padding), so we always go through a valtree here.
313322
let (ty, val) = c.eval(tcx, param_env, span)?;
@@ -327,7 +336,7 @@ impl<'tcx> Const<'tcx> {
327336
match self.eval(tcx, param_env, DUMMY_SP) {
328337
Ok(val) => Self::Val(val, self.ty()),
329338
Err(ErrorHandled::Reported(guar, _span)) => {
330-
Self::Ty(ty::Const::new_error(tcx, guar.into()))
339+
Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into()))
331340
}
332341
Err(ErrorHandled::TooGeneric(_span)) => self,
333342
}
@@ -339,7 +348,7 @@ impl<'tcx> Const<'tcx> {
339348
tcx: TyCtxt<'tcx>,
340349
param_env: ty::ParamEnv<'tcx>,
341350
) -> Option<Scalar> {
342-
if let Const::Ty(c) = self
351+
if let Const::Ty(_, c) = self
343352
&& let ty::ConstKind::Value(ty, val) = c.kind()
344353
&& ty.is_primitive()
345354
{
@@ -441,14 +450,14 @@ impl<'tcx> Const<'tcx> {
441450
Self::Val(val, ty)
442451
}
443452

444-
pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
453+
pub fn from_ty_const(c: ty::Const<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
445454
match c.kind() {
446455
ty::ConstKind::Value(ty, valtree) => {
447456
// Make sure that if `c` is normalized, then the return value is normalized.
448457
let const_val = tcx.valtree_to_const_val((ty, valtree));
449458
Self::Val(const_val, ty)
450459
}
451-
_ => Self::Ty(c),
460+
_ => Self::Ty(ty, c),
452461
}
453462
}
454463

@@ -460,7 +469,7 @@ impl<'tcx> Const<'tcx> {
460469
// - valtrees purposefully generate new allocations
461470
// - ConstValue::Slice also generate new allocations
462471
match self {
463-
Const::Ty(c) => match c.kind() {
472+
Const::Ty(_, c) => match c.kind() {
464473
ty::ConstKind::Param(..) => true,
465474
// A valtree may be a reference. Valtree references correspond to a
466475
// different allocation each time they are evaluated. Valtrees for primitive
@@ -519,7 +528,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
519528
impl<'tcx> Display for Const<'tcx> {
520529
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
521530
match *self {
522-
Const::Ty(c) => pretty_print_const(c, fmt, true),
531+
Const::Ty(_, c) => pretty_print_const(c, fmt, true),
523532
Const::Val(val, ty) => pretty_print_const_value(val, ty, fmt),
524533
// FIXME(valtrees): Correctly print mir constants.
525534
Const::Unevaluated(c, _ty) => {

compiler/rustc_middle/src/mir/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
13131313
};
13141314

13151315
let val = match const_ {
1316-
Const::Ty(ct) => match ct.kind() {
1316+
Const::Ty(_, ct) => match ct.kind() {
13171317
ty::ConstKind::Param(p) => format!("ty::Param({p})"),
13181318
ty::ConstKind::Unevaluated(uv) => {
13191319
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
@@ -1417,7 +1417,7 @@ pub fn write_allocations<'tcx>(
14171417
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
14181418
fn visit_constant(&mut self, c: &ConstOperand<'tcx>, _: Location) {
14191419
match c.const_ {
1420-
Const::Ty(_) | Const::Unevaluated(..) => {}
1420+
Const::Ty(_, _) | Const::Unevaluated(..) => {}
14211421
Const::Val(val, _) => {
14221422
self.0.extend(alloc_ids_from_const_val(val));
14231423
}

compiler/rustc_middle/src/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ macro_rules! make_mir_visitor {
895895

896896
self.visit_span($(& $mutability)? *span);
897897
match const_ {
898-
Const::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
898+
Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location),
899899
Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
900900
Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
901901
}

compiler/rustc_mir_build/src/build/expr/as_constant.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput,
77
use rustc_middle::mir::*;
88
use rustc_middle::thir::*;
99
use rustc_middle::ty::{
10-
self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex,
10+
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
1111
};
1212
use rustc_middle::{bug, span_bug};
1313
use rustc_target::abi::Size;
@@ -50,7 +50,9 @@ pub(crate) fn as_constant_inner<'tcx>(
5050
let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg })
5151
{
5252
Ok(c) => c,
53-
Err(LitToConstError::Reported(guar)) => Const::Ty(ty::Const::new_error(tcx, guar)),
53+
Err(LitToConstError::Reported(guar)) => {
54+
Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar))
55+
}
5456
Err(LitToConstError::TypeError) => {
5557
bug!("encountered type error in `lit_to_mir_constant`")
5658
}
@@ -82,7 +84,7 @@ pub(crate) fn as_constant_inner<'tcx>(
8284
}
8385
ExprKind::ConstParam { param, def_id: _ } => {
8486
let const_param = ty::Const::new_param(tcx, param);
85-
let const_ = Const::Ty(const_param);
87+
let const_ = Const::Ty(expr.ty, const_param);
8688

8789
ConstOperand { user_ty: None, span, const_ }
8890
}

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ impl<'tcx> ConstToPat<'tcx> {
101101
// level of indirection can be eliminated
102102

103103
let have_valtree =
104-
matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
104+
matches!(cv, mir::Const::Ty(_, c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
105105
let inlined_const_as_pat = match cv {
106-
mir::Const::Ty(c) => match c.kind() {
106+
mir::Const::Ty(_, c) => match c.kind() {
107107
ty::ConstKind::Param(_)
108108
| ty::ConstKind::Infer(_)
109109
| ty::ConstKind::Bound(_, _)
@@ -336,9 +336,9 @@ impl<'tcx> ConstToPat<'tcx> {
336336
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
337337
// `&str` is represented as a valtree, let's keep using this
338338
// optimization for now.
339-
ty::Str => {
340-
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
341-
}
339+
ty::Str => PatKind::Constant {
340+
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
341+
},
342342
// All other references are converted into deref patterns and then recursively
343343
// convert the dereferenced constant to a pattern that is the sub-pattern of the
344344
// deref pattern.
@@ -382,13 +382,15 @@ impl<'tcx> ConstToPat<'tcx> {
382382
self.saw_const_match_error.set(Some(e));
383383
return Err(FallbackToOpaqueConst);
384384
} else {
385-
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
385+
PatKind::Constant {
386+
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
387+
}
386388
}
387389
}
388390
ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
389391
// The raw pointers we see here have been "vetted" by valtree construction to be
390392
// just integers, so we simply allow them.
391-
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
393+
PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) }
392394
}
393395
ty::FnPtr(..) => {
394396
unreachable!(

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
580580
.tcx
581581
.const_eval_global_id_for_typeck(param_env_reveal_all, cid, span)
582582
.map(|val| match val {
583-
Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
583+
Some(valtree) => mir::Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
584584
None => mir::Const::Val(
585585
self.tcx
586586
.const_eval_global_id(param_env_reveal_all, cid, span)
@@ -659,7 +659,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
659659
};
660660
if let Some(lit_input) = lit_input {
661661
match tcx.at(expr.span).lit_to_const(lit_input) {
662-
Ok(c) => return self.const_to_pat(Const::Ty(c), id, span).kind,
662+
Ok(c) => return self.const_to_pat(Const::Ty(ty, c), id, span).kind,
663663
// If an error occurred, ignore that it's a literal
664664
// and leave reporting the error up to const eval of
665665
// the unevaluated constant below.
@@ -681,8 +681,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
681681
// but something more principled, like a trait query checking whether this can be turned into a valtree.
682682
if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span)
683683
{
684-
let subpattern =
685-
self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span);
684+
let subpattern = self.const_to_pat(
685+
Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
686+
id,
687+
span,
688+
);
686689
PatKind::InlineConstant { subpattern, def: def_id }
687690
} else {
688691
// If that fails, convert it to an opaque constant pattern.
@@ -720,10 +723,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
720723
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
721724
};
722725

723-
let lit_input =
724-
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
726+
let ct_ty = self.typeck_results.expr_ty(expr);
727+
let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
725728
match self.tcx.at(expr.span).lit_to_const(lit_input) {
726-
Ok(constant) => self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span).kind,
729+
Ok(constant) => {
730+
self.const_to_pat(Const::Ty(ct_ty, constant), expr.hir_id, lit.span).kind
731+
}
727732
Err(LitToConstError::Reported(e)) => PatKind::Error(e),
728733
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
729734
}

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
203203
&& let operand_ty = operand.ty(self.local_decls, self.tcx)
204204
&& let Some(operand_ty) = operand_ty.builtin_deref(true)
205205
&& let ty::Array(_, len) = operand_ty.kind()
206-
&& let Some(len) = Const::Ty(*len).try_eval_scalar_int(self.tcx, self.param_env)
206+
&& let Some(len) = Const::Ty(self.tcx.types.usize, *len)
207+
.try_eval_scalar_int(self.tcx, self.param_env)
207208
{
208209
state.insert_value_idx(target_len, FlatSet::Elem(len.into()), self.map());
209210
}
@@ -221,7 +222,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
221222
Rvalue::Len(place) => {
222223
let place_ty = place.ty(self.local_decls, self.tcx);
223224
if let ty::Array(_, len) = place_ty.ty.kind() {
224-
Const::Ty(*len)
225+
Const::Ty(self.tcx.types.usize, *len)
225226
.try_eval_scalar(self.tcx, self.param_env)
226227
.map_or(FlatSet::Top, FlatSet::Elem)
227228
} else if let [ProjectionElem::Deref] = place.projection[..] {

compiler/rustc_mir_transform/src/gvn.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
11081108
// Trivial case: we are fetching a statically known length.
11091109
let place_ty = place.ty(self.local_decls, self.tcx).ty;
11101110
if let ty::Array(_, len) = place_ty.kind() {
1111-
return self.insert_constant(Const::from_ty_const(*len, self.tcx));
1111+
return self.insert_constant(Const::from_ty_const(
1112+
*len,
1113+
self.tcx.types.usize,
1114+
self.tcx,
1115+
));
11121116
}
11131117

11141118
let mut inner = self.simplify_place_value(place, location)?;
@@ -1130,7 +1134,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
11301134
&& let Some(to) = to.builtin_deref(true)
11311135
&& let ty::Slice(..) = to.kind()
11321136
{
1133-
return self.insert_constant(Const::from_ty_const(*len, self.tcx));
1137+
return self.insert_constant(Const::from_ty_const(
1138+
*len,
1139+
self.tcx.types.usize,
1140+
self.tcx,
1141+
));
11341142
}
11351143

11361144
// Fallback: a symbolic `Len`.

compiler/rustc_mir_transform/src/instsimplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
150150
return;
151151
}
152152

153-
let const_ = Const::from_ty_const(len, self.tcx);
153+
let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
154154
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
155155
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
156156
}

compiler/rustc_mir_transform/src/normalize_array_len.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
9595
*rvalue = Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
9696
span: rustc_span::DUMMY_SP,
9797
user_ty: None,
98-
const_: Const::from_ty_const(len, self.tcx),
98+
const_: Const::from_ty_const(len, self.tcx.types.usize, self.tcx),
9999
})));
100100
}
101101
self.super_rvalue(rvalue, loc);

compiler/rustc_monomorphize/src/polymorphize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
263263

264264
fn visit_constant(&mut self, ct: &mir::ConstOperand<'tcx>, location: Location) {
265265
match ct.const_ {
266-
mir::Const::Ty(c) => {
266+
mir::Const::Ty(_, c) => {
267267
c.visit_with(self);
268268
}
269269
mir::Const::Unevaluated(mir::UnevaluatedConst { def, args: _, promoted }, ty) => {

compiler/rustc_pattern_analysis/src/rustc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
737737
// this). We show this to the user as `usize::MAX..` which is slightly incorrect but
738738
// probably clear enough.
739739
let c = ty.numeric_max_val(cx.tcx).unwrap();
740-
let value = mir::Const::from_ty_const(c, cx.tcx);
740+
let value = mir::Const::from_ty_const(c, self.tcx.types.usize, cx.tcx);
741741
lo = PatRangeBoundary::Finite(value);
742742
}
743743
let hi = if let Some(hi) = range.hi.minus_one() {

0 commit comments

Comments
 (0)