1
1
use rustc_hir as hir;
2
2
use rustc_index:: vec:: Idx ;
3
3
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
4
+ use rustc_middle:: mir:: interpret:: ConstValue ;
4
5
use rustc_middle:: mir:: Field ;
5
6
use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
6
7
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
@@ -249,11 +250,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
249
250
250
251
fn field_pats (
251
252
& self ,
252
- vals : impl Iterator < Item = & ' tcx ty :: Const < ' tcx > > ,
253
+ vals : impl Iterator < Item = ( ConstValue < ' tcx > , Ty < ' tcx > ) > ,
253
254
) -> Result < Vec < FieldPat < ' tcx > > , FallbackToConstRef > {
255
+ let tcx = self . tcx ( ) ;
254
256
vals. enumerate ( )
255
- . map ( |( idx, val) | {
257
+ . map ( |( idx, ( val, ty ) ) | {
256
258
let field = Field :: new ( idx) ;
259
+ let val = ty:: Const :: from_value ( tcx, val, ty) ;
257
260
Ok ( FieldPat { field, pattern : self . recur ( val, false ) ? } )
258
261
} )
259
262
. collect ( )
@@ -357,7 +360,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
357
360
PatKind :: Wild
358
361
}
359
362
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
+ ) ;
361
366
PatKind :: Variant {
362
367
adt_def,
363
368
substs,
@@ -368,15 +373,19 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
368
373
}
369
374
}
370
375
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
+ ) ;
372
379
PatKind :: Leaf { subpatterns : self . field_pats ( destructured. fields . iter ( ) . copied ( ) ) ? }
373
380
}
374
381
ty:: Array ( ..) => PatKind :: Array {
375
382
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
+ )
377
386
. fields
378
387
. iter ( )
379
- . map ( |val| self . recur ( val, false ) )
388
+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
380
389
. collect :: < Result < _ , _ > > ( ) ?,
381
390
slice : None ,
382
391
suffix : Vec :: new ( ) ,
@@ -404,15 +413,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
404
413
// arrays.
405
414
ty:: Array ( ..) if !self . treat_byte_string_as_slice => {
406
415
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 ) ) ) ;
408
417
let val = PatKind :: Deref {
409
418
subpattern : Pat {
410
419
kind : Box :: new ( PatKind :: Array {
411
420
prefix : tcx
412
421
. destructure_const ( param_env. and ( array) )
413
422
. fields
414
423
. iter ( )
415
- . map ( |val| self . recur ( val, false ) )
424
+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
416
425
. collect :: < Result < _ , _ > > ( ) ?,
417
426
slice : None ,
418
427
suffix : vec ! [ ] ,
@@ -430,15 +439,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
430
439
// pattern.
431
440
ty:: Slice ( elem_ty) => {
432
441
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 ) ) ) ;
434
443
let val = PatKind :: Deref {
435
444
subpattern : Pat {
436
445
kind : Box :: new ( PatKind :: Slice {
437
446
prefix : tcx
438
447
. destructure_const ( param_env. and ( array) )
439
448
. fields
440
449
. iter ( )
441
- . map ( |val| self . recur ( val, false ) )
450
+ . map ( |& ( val, ty ) | self . recur ( ty :: Const :: from_value ( tcx , val, ty ) , false ) )
442
451
. collect :: < Result < _ , _ > > ( ) ?,
443
452
slice : None ,
444
453
suffix : vec ! [ ] ,
@@ -493,7 +502,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
493
502
// we fall back to a const pattern. If we do not do this, we may end up with
494
503
// a !structural-match constant that is not of reference type, which makes it
495
504
// 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 ) {
497
508
Ok ( subpattern) => PatKind :: Deref { subpattern } ,
498
509
Err ( _) => PatKind :: Constant { value : cv } ,
499
510
} ;
0 commit comments