@@ -2,6 +2,7 @@ use rustc_hir as hir;
22use rustc_index:: vec:: Idx ;
33use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
44use rustc_middle:: mir:: Field ;
5+ use rustc_middle:: mir:: interpret:: ConstValue ;
56use rustc_middle:: ty:: print:: with_no_trimmed_paths;
67use rustc_middle:: ty:: { self , AdtDef , Ty , TyCtxt } ;
78use rustc_session:: lint;
@@ -248,11 +249,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
248249
249250 fn field_pats (
250251 & self ,
251- vals : impl Iterator < Item = & ' tcx ty :: Const < ' tcx > > ,
252+ vals : impl Iterator < Item = ( ConstValue < ' tcx > , Ty < ' tcx > ) > ,
252253 ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToConstRef > {
254+ let tcx = self . tcx ( ) ;
253255 vals. enumerate ( )
254- . map ( |( idx, val) | {
256+ . map ( |( idx, ( val, ty ) ) | {
255257 let field = Field :: new ( idx) ;
258+ let val = ty:: Const :: from_value ( tcx, val, ty) ;
256259 Ok ( FieldPat { field, pattern : self . recur ( val, false ) ? } )
257260 } )
258261 . collect ( )
@@ -356,7 +359,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
356359 PatKind :: Wild
357360 }
358361 ty:: Adt ( adt_def, substs) if adt_def. is_enum ( ) => {
359- let destructured = tcx. destructure_const ( param_env. and ( cv ) ) ;
362+ let destructured = tcx. destructure_const ( param_env. and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
360363 PatKind :: Variant {
361364 adt_def,
362365 substs,
@@ -367,15 +370,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
367370 }
368371 }
369372 ty:: Tuple ( _) | ty:: Adt ( _, _) => {
370- let destructured = tcx. destructure_const ( param_env. and ( cv ) ) ;
373+ let destructured = tcx. destructure_const ( param_env. and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
371374 PatKind :: Leaf { subpatterns : self . field_pats ( destructured. fields . iter ( ) . copied ( ) ) ? }
372375 }
373376 ty:: Array ( ..) => PatKind :: Array {
374377 prefix : tcx
375- . destructure_const ( param_env. and ( cv ) )
378+ . destructure_const ( param_env. and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) )
376379 . fields
377380 . iter ( )
378- . map ( |val| self . recur ( val, false ) )
381+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
379382 . collect :: < Result < _ , _ > > ( ) ?,
380383 slice : None ,
381384 suffix : Vec :: new ( ) ,
@@ -403,15 +406,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
403406 // arrays.
404407 ty:: Array ( ..) if !self . treat_byte_string_as_slice => {
405408 let old = self . behind_reference . replace ( true ) ;
406- let array = tcx. deref_const ( self . param_env . and ( cv ) ) ;
409+ let array = tcx. deref_const ( self . param_env . and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
407410 let val = PatKind :: Deref {
408411 subpattern : Pat {
409412 kind : Box :: new ( PatKind :: Array {
410413 prefix : tcx
411414 . destructure_const ( param_env. and ( array) )
412415 . fields
413416 . iter ( )
414- . map ( |val| self . recur ( val, false ) )
417+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
415418 . collect :: < Result < _ , _ > > ( ) ?,
416419 slice : None ,
417420 suffix : vec ! [ ] ,
@@ -429,15 +432,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
429432 // pattern.
430433 ty:: Slice ( elem_ty) => {
431434 let old = self . behind_reference . replace ( true ) ;
432- let array = tcx. deref_const ( self . param_env . and ( cv ) ) ;
435+ let array = tcx. deref_const ( self . param_env . and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
433436 let val = PatKind :: Deref {
434437 subpattern : Pat {
435438 kind : Box :: new ( PatKind :: Slice {
436439 prefix : tcx
437440 . destructure_const ( param_env. and ( array) )
438441 . fields
439442 . iter ( )
440- . map ( |val| self . recur ( val, false ) )
443+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
441444 . collect :: < Result < _ , _ > > ( ) ?,
442445 slice : None ,
443446 suffix : vec ! [ ] ,
@@ -492,7 +495,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
492495 // we fall back to a const pattern. If we do not do this, we may end up with
493496 // a !structural-match constant that is not of reference type, which makes it
494497 // very hard to invoke `PartialEq::eq` on it as a fallback.
495- let val = match self . recur ( tcx. deref_const ( self . param_env . and ( cv) ) , false ) {
498+ let ( val, ty) = tcx. deref_const ( self . param_env . and ( ( cv. val . eval ( tcx, param_env) . try_to_value ( ) . unwrap ( ) , cv. ty ) ) ) ;
499+ let deref_cv = ty:: Const :: from_value ( tcx, val, ty) ;
500+ let val = match self . recur ( deref_cv, false ) {
496501 Ok ( subpattern) => PatKind :: Deref { subpattern } ,
497502 Err ( _) => PatKind :: Constant { value : cv } ,
498503 } ;
0 commit comments