@@ -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> {
519528impl < ' 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) => {
0 commit comments