11use rustc_hir as hir;
22use rustc_index:: vec:: Idx ;
33use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
4+ use rustc_middle:: mir:: interpret:: ConstValue ;
45use rustc_middle:: mir:: Field ;
56use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
67use rustc_middle:: ty:: print:: with_no_trimmed_paths;
@@ -249,11 +250,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
249250
250251 fn field_pats (
251252 & self ,
252- vals : impl Iterator < Item = & ' tcx ty :: Const < ' tcx > > ,
253+ vals : impl Iterator < Item = ( ConstValue < ' tcx > , Ty < ' tcx > ) > ,
253254 ) -> Result < Vec < FieldPat < ' tcx > > , FallbackToConstRef > {
255+ let tcx = self . tcx ( ) ;
254256 vals. enumerate ( )
255- . map ( |( idx, val) | {
257+ . map ( |( idx, ( val, ty ) ) | {
256258 let field = Field :: new ( idx) ;
259+ let val = ty:: Const :: from_value ( tcx, val, ty) ;
257260 Ok ( FieldPat { field, pattern : self . recur ( val, false ) ? } )
258261 } )
259262 . collect ( )
@@ -357,7 +360,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
357360 PatKind :: Wild
358361 }
359362 ty:: Adt ( adt_def, substs) if adt_def. is_enum ( ) => {
360- let destructured = tcx. destructure_const ( param_env. and ( cv) ) ;
363+ let destructured = tcx. destructure_const (
364+ param_env. and ( ( cv. val . eval ( tcx, param_env) . try_to_value ( ) . unwrap ( ) , cv. ty ) ) ,
365+ ) ;
361366 PatKind :: Variant {
362367 adt_def,
363368 substs,
@@ -368,15 +373,19 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
368373 }
369374 }
370375 ty:: Tuple ( _) | ty:: Adt ( _, _) => {
371- let destructured = tcx. destructure_const ( param_env. and ( cv) ) ;
376+ let destructured = tcx. destructure_const (
377+ param_env. and ( ( cv. val . eval ( tcx, param_env) . try_to_value ( ) . unwrap ( ) , cv. ty ) ) ,
378+ ) ;
372379 PatKind :: Leaf { subpatterns : self . field_pats ( destructured. fields . iter ( ) . copied ( ) ) ? }
373380 }
374381 ty:: Array ( ..) => PatKind :: Array {
375382 prefix : tcx
376- . destructure_const ( param_env. and ( cv) )
383+ . destructure_const (
384+ param_env. and ( ( cv. val . eval ( tcx, param_env) . try_to_value ( ) . unwrap ( ) , cv. ty ) ) ,
385+ )
377386 . fields
378387 . iter ( )
379- . map ( |val| self . recur ( val, false ) )
388+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
380389 . collect :: < Result < _ , _ > > ( ) ?,
381390 slice : None ,
382391 suffix : Vec :: new ( ) ,
@@ -404,15 +413,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
404413 // arrays.
405414 ty:: Array ( ..) if !self . treat_byte_string_as_slice => {
406415 let old = self . behind_reference . replace ( true ) ;
407- let array = tcx. deref_const ( self . param_env . and ( cv ) ) ;
416+ let array = tcx. deref_const ( self . param_env . and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
408417 let val = PatKind :: Deref {
409418 subpattern : Pat {
410419 kind : Box :: new ( PatKind :: Array {
411420 prefix : tcx
412421 . destructure_const ( param_env. and ( array) )
413422 . fields
414423 . iter ( )
415- . map ( |val| self . recur ( val, false ) )
424+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
416425 . collect :: < Result < _ , _ > > ( ) ?,
417426 slice : None ,
418427 suffix : vec ! [ ] ,
@@ -430,15 +439,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
430439 // pattern.
431440 ty:: Slice ( elem_ty) => {
432441 let old = self . behind_reference . replace ( true ) ;
433- let array = tcx. deref_const ( self . param_env . and ( cv ) ) ;
442+ let array = tcx. deref_const ( self . param_env . and ( ( cv . val . eval ( tcx , param_env ) . try_to_value ( ) . unwrap ( ) , cv . ty ) ) ) ;
434443 let val = PatKind :: Deref {
435444 subpattern : Pat {
436445 kind : Box :: new ( PatKind :: Slice {
437446 prefix : tcx
438447 . destructure_const ( param_env. and ( array) )
439448 . fields
440449 . iter ( )
441- . map ( |val| self . recur ( val, false ) )
450+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
442451 . collect :: < Result < _ , _ > > ( ) ?,
443452 slice : None ,
444453 suffix : vec ! [ ] ,
@@ -493,7 +502,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
493502 // we fall back to a const pattern. If we do not do this, we may end up with
494503 // a !structural-match constant that is not of reference type, which makes it
495504 // very hard to invoke `PartialEq::eq` on it as a fallback.
496- let val = match self . recur ( tcx. deref_const ( self . param_env . and ( cv) ) , false ) {
505+ let ( val, ty) = tcx. deref_const ( self . param_env . and ( ( cv. val . eval ( tcx, param_env) . try_to_value ( ) . unwrap ( ) , cv. ty ) ) ) ;
506+ let deref_cv = ty:: Const :: from_value ( tcx, val, ty) ;
507+ let val = match self . recur ( deref_cv, false ) {
497508 Ok ( subpattern) => PatKind :: Deref { subpattern } ,
498509 Err ( _) => PatKind :: Constant { value : cv } ,
499510 } ;
0 commit comments