@@ -204,7 +204,7 @@ 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
+ Ty ( Ty < ' tcx > , ty:: Const < ' tcx > ) ,
208
208
209
209
/// An unevaluated mir constant which is not part of the type system.
210
210
///
@@ -237,8 +237,15 @@ impl<'tcx> Const<'tcx> {
237
237
#[ inline( always) ]
238
238
pub fn ty ( & self ) -> Ty < ' tcx > {
239
239
match self {
240
- // THISPR
241
- Const :: Ty ( c) => todo ! ( ) ,
240
+ Const :: Ty ( ty, ct) => {
241
+ match ct. kind ( ) {
242
+ // Dont use the outter ty as on invalid code we can wind up with them not being the same.
243
+ // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
244
+ // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
245
+ ty:: ConstKind :: Value ( ty, _) => ty,
246
+ _ => * ty,
247
+ }
248
+ }
242
249
Const :: Val ( _, ty) | Const :: Unevaluated ( _, ty) => * ty,
243
250
}
244
251
}
@@ -248,7 +255,7 @@ impl<'tcx> Const<'tcx> {
248
255
#[ inline]
249
256
pub fn is_required_const ( & self ) -> bool {
250
257
match self {
251
- Const :: Ty ( c) => match c. kind ( ) {
258
+ Const :: Ty ( _ , c) => match c. kind ( ) {
252
259
ty:: ConstKind :: Value ( _, _) => false , // already a value, cannot error
253
260
_ => true ,
254
261
} ,
@@ -260,7 +267,7 @@ impl<'tcx> Const<'tcx> {
260
267
#[ inline]
261
268
pub fn try_to_scalar ( self ) -> Option < Scalar > {
262
269
match self {
263
- Const :: Ty ( c) => match c. kind ( ) {
270
+ Const :: Ty ( _ , c) => match c. kind ( ) {
264
271
ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
265
272
// A valtree of a type where leaves directly represent the scalar const value.
266
273
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
@@ -279,7 +286,7 @@ impl<'tcx> Const<'tcx> {
279
286
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
280
287
match self {
281
288
Const :: Val ( ConstValue :: Scalar ( Scalar :: Int ( x) ) , _) => Some ( x) ,
282
- Const :: Ty ( c) => match c. kind ( ) {
289
+ Const :: Ty ( _ , c) => match c. kind ( ) {
283
290
ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
284
291
Some ( valtree. unwrap_leaf ( ) )
285
292
}
@@ -307,7 +314,7 @@ impl<'tcx> Const<'tcx> {
307
314
span : Span ,
308
315
) -> Result < ConstValue < ' tcx > , ErrorHandled > {
309
316
match self {
310
- Const :: Ty ( c) => {
317
+ Const :: Ty ( _ , c) => {
311
318
// We want to consistently have a "clean" value for type system constants (i.e., no
312
319
// data hidden in the padding), so we always go through a valtree here.
313
320
let ( ty, val) = c. eval ( tcx, param_env, span) ?;
@@ -327,7 +334,7 @@ impl<'tcx> Const<'tcx> {
327
334
match self . eval ( tcx, param_env, DUMMY_SP ) {
328
335
Ok ( val) => Self :: Val ( val, self . ty ( ) ) ,
329
336
Err ( ErrorHandled :: Reported ( guar, _span) ) => {
330
- Self :: Ty ( ty:: Const :: new_error ( tcx, guar. into ( ) ) )
337
+ Self :: Ty ( Ty :: new_error ( tcx , guar . into ( ) ) , ty:: Const :: new_error ( tcx, guar. into ( ) ) )
331
338
}
332
339
Err ( ErrorHandled :: TooGeneric ( _span) ) => self ,
333
340
}
@@ -339,7 +346,7 @@ impl<'tcx> Const<'tcx> {
339
346
tcx : TyCtxt < ' tcx > ,
340
347
param_env : ty:: ParamEnv < ' tcx > ,
341
348
) -> Option < Scalar > {
342
- if let Const :: Ty ( c) = self
349
+ if let Const :: Ty ( _ , c) = self
343
350
&& let ty:: ConstKind :: Value ( ty, val) = c. kind ( )
344
351
&& ty. is_primitive ( )
345
352
{
@@ -441,14 +448,14 @@ impl<'tcx> Const<'tcx> {
441
448
Self :: Val ( val, ty)
442
449
}
443
450
444
- pub fn from_ty_const ( c : ty:: Const < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Self {
451
+ pub fn from_ty_const ( c : ty:: Const < ' tcx > , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Self {
445
452
match c. kind ( ) {
446
453
ty:: ConstKind :: Value ( ty, valtree) => {
447
454
// Make sure that if `c` is normalized, then the return value is normalized.
448
455
let const_val = tcx. valtree_to_const_val ( ( ty, valtree) ) ;
449
456
Self :: Val ( const_val, ty)
450
457
}
451
- _ => Self :: Ty ( c) ,
458
+ _ => Self :: Ty ( ty , c) ,
452
459
}
453
460
}
454
461
@@ -460,7 +467,7 @@ impl<'tcx> Const<'tcx> {
460
467
// - valtrees purposefully generate new allocations
461
468
// - ConstValue::Slice also generate new allocations
462
469
match self {
463
- Const :: Ty ( c) => match c. kind ( ) {
470
+ Const :: Ty ( _ , c) => match c. kind ( ) {
464
471
ty:: ConstKind :: Param ( ..) => true ,
465
472
// A valtree may be a reference. Valtree references correspond to a
466
473
// different allocation each time they are evaluated. Valtrees for primitive
@@ -519,7 +526,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
519
526
impl < ' tcx > Display for Const < ' tcx > {
520
527
fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
521
528
match * self {
522
- Const :: Ty ( c) => pretty_print_const ( c, fmt, true ) ,
529
+ Const :: Ty ( _ , c) => pretty_print_const ( c, fmt, true ) ,
523
530
Const :: Val ( val, ty) => pretty_print_const_value ( val, ty, fmt) ,
524
531
// FIXME(valtrees): Correctly print mir constants.
525
532
Const :: Unevaluated ( c, _ty) => {
0 commit comments