@@ -204,7 +204,7 @@ 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+ Ty ( Ty < ' tcx > , ty:: Const < ' tcx > ) ,
208208
209209 /// An unevaluated mir constant which is not part of the type system.
210210 ///
@@ -237,8 +237,15 @@ impl<'tcx> Const<'tcx> {
237237 #[ inline( always) ]
238238 pub fn ty ( & self ) -> Ty < ' tcx > {
239239 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+ }
242249 Const :: Val ( _, ty) | Const :: Unevaluated ( _, ty) => * ty,
243250 }
244251 }
@@ -248,7 +255,7 @@ impl<'tcx> Const<'tcx> {
248255 #[ inline]
249256 pub fn is_required_const ( & self ) -> bool {
250257 match self {
251- Const :: Ty ( c) => match c. kind ( ) {
258+ Const :: Ty ( _ , c) => match c. kind ( ) {
252259 ty:: ConstKind :: Value ( _, _) => false , // already a value, cannot error
253260 _ => true ,
254261 } ,
@@ -260,7 +267,7 @@ impl<'tcx> Const<'tcx> {
260267 #[ inline]
261268 pub fn try_to_scalar ( self ) -> Option < Scalar > {
262269 match self {
263- Const :: Ty ( c) => match c. kind ( ) {
270+ Const :: Ty ( _ , c) => match c. kind ( ) {
264271 ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
265272 // A valtree of a type where leaves directly represent the scalar const value.
266273 // Just checking whether it is a leaf is insufficient as e.g. references are leafs
@@ -279,7 +286,7 @@ impl<'tcx> Const<'tcx> {
279286 // This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
280287 match self {
281288 Const :: Val ( ConstValue :: Scalar ( Scalar :: Int ( x) ) , _) => Some ( x) ,
282- Const :: Ty ( c) => match c. kind ( ) {
289+ Const :: Ty ( _ , c) => match c. kind ( ) {
283290 ty:: ConstKind :: Value ( ty, valtree) if ty. is_primitive ( ) => {
284291 Some ( valtree. unwrap_leaf ( ) )
285292 }
@@ -307,7 +314,7 @@ impl<'tcx> Const<'tcx> {
307314 span : Span ,
308315 ) -> Result < ConstValue < ' tcx > , ErrorHandled > {
309316 match self {
310- Const :: Ty ( c) => {
317+ Const :: Ty ( _ , c) => {
311318 // We want to consistently have a "clean" value for type system constants (i.e., no
312319 // data hidden in the padding), so we always go through a valtree here.
313320 let ( ty, val) = c. eval ( tcx, param_env, span) ?;
@@ -327,7 +334,7 @@ impl<'tcx> Const<'tcx> {
327334 match self . eval ( tcx, param_env, DUMMY_SP ) {
328335 Ok ( val) => Self :: Val ( val, self . ty ( ) ) ,
329336 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 ( ) ) )
331338 }
332339 Err ( ErrorHandled :: TooGeneric ( _span) ) => self ,
333340 }
@@ -339,7 +346,7 @@ impl<'tcx> Const<'tcx> {
339346 tcx : TyCtxt < ' tcx > ,
340347 param_env : ty:: ParamEnv < ' tcx > ,
341348 ) -> Option < Scalar > {
342- if let Const :: Ty ( c) = self
349+ if let Const :: Ty ( _ , c) = self
343350 && let ty:: ConstKind :: Value ( ty, val) = c. kind ( )
344351 && ty. is_primitive ( )
345352 {
@@ -441,14 +448,14 @@ impl<'tcx> Const<'tcx> {
441448 Self :: Val ( val, ty)
442449 }
443450
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 {
445452 match c. kind ( ) {
446453 ty:: ConstKind :: Value ( ty, valtree) => {
447454 // Make sure that if `c` is normalized, then the return value is normalized.
448455 let const_val = tcx. valtree_to_const_val ( ( ty, valtree) ) ;
449456 Self :: Val ( const_val, ty)
450457 }
451- _ => Self :: Ty ( c) ,
458+ _ => Self :: Ty ( ty , c) ,
452459 }
453460 }
454461
@@ -460,7 +467,7 @@ impl<'tcx> Const<'tcx> {
460467 // - valtrees purposefully generate new allocations
461468 // - ConstValue::Slice also generate new allocations
462469 match self {
463- Const :: Ty ( c) => match c. kind ( ) {
470+ Const :: Ty ( _ , c) => match c. kind ( ) {
464471 ty:: ConstKind :: Param ( ..) => true ,
465472 // A valtree may be a reference. Valtree references correspond to a
466473 // different allocation each time they are evaluated. Valtrees for primitive
@@ -519,7 +526,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
519526impl < ' tcx > Display for Const < ' tcx > {
520527 fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
521528 match * self {
522- Const :: Ty ( c) => pretty_print_const ( c, fmt, true ) ,
529+ Const :: Ty ( _ , c) => pretty_print_const ( c, fmt, true ) ,
523530 Const :: Val ( val, ty) => pretty_print_const_value ( val, ty, fmt) ,
524531 // FIXME(valtrees): Correctly print mir constants.
525532 Const :: Unevaluated ( c, _ty) => {
0 commit comments