@@ -204,7 +204,9 @@ pub enum Const<'tcx> {
204
204
/// Any way of turning `ty::Const` into `ConstValue` should go through `valtree_to_const_val`;
205
205
/// this ensures that we consistently produce "clean" values without data in the padding or
206
206
/// 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 > ) ,
208
210
209
211
/// An unevaluated mir constant which is not part of the type system.
210
212
///
@@ -237,8 +239,15 @@ impl<'tcx> Const<'tcx> {
237
239
#[ inline( always) ]
238
240
pub fn ty ( & self ) -> Ty < ' tcx > {
239
241
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
+ }
242
251
Const :: Val ( _, ty) | Const :: Unevaluated ( _, ty) => * ty,
243
252
}
244
253
}
@@ -248,7 +257,7 @@ impl<'tcx> Const<'tcx> {
248
257
#[ inline]
249
258
pub fn is_required_const ( & self ) -> bool {
250
259
match self {
251
- Const :: Ty ( c) => match c. kind ( ) {
260
+ Const :: Ty ( _ , c) => match c. kind ( ) {
252
261
ty:: ConstKind :: Value ( _, _) => false , // already a value, cannot error
253
262
_ => true ,
254
263
} ,
@@ -260,7 +269,7 @@ impl<'tcx> Const<'tcx> {
260
269
#[ inline]
261
270
pub fn try_to_scalar ( self ) -> Option < Scalar > {
262
271
match self {
263
- Const :: Ty ( c) => match c. kind ( ) {
272
+ Const :: Ty ( _ , c) => match c. kind ( ) {
264
273
ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
265
274
// A valtree of a type where leaves directly represent the scalar const value.
266
275
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
@@ -279,7 +288,7 @@ impl<'tcx> Const<'tcx> {
279
288
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
280
289
match self {
281
290
Const :: Val ( ConstValue :: Scalar ( Scalar :: Int ( x) ) , _) => Some ( x) ,
282
- Const :: Ty ( c) => match c. kind ( ) {
291
+ Const :: Ty ( _ , c) => match c. kind ( ) {
283
292
ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
284
293
Some ( valtree. unwrap_leaf ( ) )
285
294
}
@@ -307,7 +316,7 @@ impl<'tcx> Const<'tcx> {
307
316
span : Span ,
308
317
) -> Result < ConstValue < ' tcx > , ErrorHandled > {
309
318
match self {
310
- Const :: Ty ( c) => {
319
+ Const :: Ty ( _ , c) => {
311
320
// We want to consistently have a "clean" value for type system constants (i.e., no
312
321
// data hidden in the padding), so we always go through a valtree here.
313
322
let ( ty, val) = c. eval ( tcx, param_env, span) ?;
@@ -327,7 +336,7 @@ impl<'tcx> Const<'tcx> {
327
336
match self . eval ( tcx, param_env, DUMMY_SP ) {
328
337
Ok ( val) => Self :: Val ( val, self . ty ( ) ) ,
329
338
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 ( ) ) )
331
340
}
332
341
Err ( ErrorHandled :: TooGeneric ( _span) ) => self ,
333
342
}
@@ -339,7 +348,7 @@ impl<'tcx> Const<'tcx> {
339
348
tcx : TyCtxt < ' tcx > ,
340
349
param_env : ty:: ParamEnv < ' tcx > ,
341
350
) -> Option < Scalar > {
342
- if let Const :: Ty ( c) = self
351
+ if let Const :: Ty ( _ , c) = self
343
352
&& let ty:: ConstKind :: Value ( ty, val) = c. kind ( )
344
353
&& ty. is_primitive ( )
345
354
{
@@ -441,14 +450,14 @@ impl<'tcx> Const<'tcx> {
441
450
Self :: Val ( val, ty)
442
451
}
443
452
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 {
445
454
match c. kind ( ) {
446
455
ty:: ConstKind :: Value ( ty, valtree) => {
447
456
// Make sure that if `c` is normalized, then the return value is normalized.
448
457
let const_val = tcx. valtree_to_const_val ( ( ty, valtree) ) ;
449
458
Self :: Val ( const_val, ty)
450
459
}
451
- _ => Self :: Ty ( c) ,
460
+ _ => Self :: Ty ( ty , c) ,
452
461
}
453
462
}
454
463
@@ -460,7 +469,7 @@ impl<'tcx> Const<'tcx> {
460
469
// - valtrees purposefully generate new allocations
461
470
// - ConstValue::Slice also generate new allocations
462
471
match self {
463
- Const :: Ty ( c) => match c. kind ( ) {
472
+ Const :: Ty ( _ , c) => match c. kind ( ) {
464
473
ty:: ConstKind :: Param ( ..) => true ,
465
474
// A valtree may be a reference. Valtree references correspond to a
466
475
// different allocation each time they are evaluated. Valtrees for primitive
@@ -519,7 +528,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
519
528
impl < ' tcx > Display for Const < ' tcx > {
520
529
fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
521
530
match * self {
522
- Const :: Ty ( c) => pretty_print_const ( c, fmt, true ) ,
531
+ Const :: Ty ( _ , c) => pretty_print_const ( c, fmt, true ) ,
523
532
Const :: Val ( val, ty) => pretty_print_const_value ( val, ty, fmt) ,
524
533
// FIXME(valtrees): Correctly print mir constants.
525
534
Const :: Unevaluated ( c, _ty) => {
0 commit comments