@@ -18,7 +18,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
18
18
use rustc_hir:: RangeEnd ;
19
19
use rustc_index:: Idx ;
20
20
use rustc_middle:: mir:: interpret:: {
21
- ConstValue , ErrorHandled , LitToConstError , LitToConstInput , Scalar ,
21
+ ConstValue , ErrorHandled , GlobalId , LitToConstError , LitToConstInput , Scalar ,
22
22
} ;
23
23
use rustc_middle:: mir:: { self , UserTypeProjection } ;
24
24
use rustc_middle:: mir:: { BorrowKind , Mutability } ;
@@ -518,16 +518,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
518
518
}
519
519
} ;
520
520
521
- // `mir_const_qualif` must be called with the `DefId` of the item where the const is
522
- // defined, not where it is declared. The difference is significant for associated
523
- // constants.
524
- let mir_structural_match_violation = self . tcx . mir_const_qualif ( instance. def_id ( ) ) . custom_eq ;
525
- debug ! ( "mir_structural_match_violation({:?}) -> {}" , qpath, mir_structural_match_violation) ;
526
-
527
- match self . tcx . const_eval_instance ( param_env_reveal_all, instance, Some ( span) ) {
528
- Ok ( literal) => {
529
- let const_ = mir:: ConstantKind :: Val ( literal, ty) ;
530
- let pattern = self . const_to_pat ( const_, id, span, mir_structural_match_violation) ;
521
+ let cid = GlobalId { instance, promoted : None } ;
522
+ // Prefer
523
+ let const_value = self
524
+ . tcx
525
+ . const_eval_global_id_for_typeck ( param_env_reveal_all, cid, Some ( span) )
526
+ . and_then ( |val| match val {
527
+ Some ( valtree) => Ok ( mir:: ConstantKind :: Ty ( self . tcx . mk_const ( valtree, ty) ) ) ,
528
+ None => self
529
+ . tcx
530
+ . const_eval_global_id ( param_env_reveal_all, cid, Some ( span) )
531
+ . map ( |lit| mir:: ConstantKind :: Val ( lit, ty) ) ,
532
+ } ) ;
533
+
534
+ match const_value {
535
+ Ok ( const_) => {
536
+ let pattern = self . const_to_pat ( const_, id, span, Some ( instance. def_id ( ) ) ) ;
531
537
532
538
if !is_associated_const {
533
539
return pattern;
@@ -578,9 +584,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
578
584
span : Span ,
579
585
) -> PatKind < ' tcx > {
580
586
let value = mir:: ConstantKind :: from_inline_const ( self . tcx , anon_const. def_id ) ;
581
-
582
- // Evaluate early like we do in `lower_path`.
583
- let value = value. eval ( self . tcx , self . param_env ) ;
587
+ let value = match value {
588
+ mir:: ConstantKind :: Ty ( _) => value,
589
+ // Evaluate early like we do in `lower_path`.
590
+ mir:: ConstantKind :: Unevaluated ( ct, ty) => {
591
+ let ct = ty:: UnevaluatedConst { def : ct. def , substs : ct. substs } ;
592
+ if let Ok ( Some ( valtree) ) =
593
+ self . tcx . const_eval_resolve_for_typeck ( self . param_env , ct, Some ( span) )
594
+ {
595
+ mir:: ConstantKind :: Ty ( self . tcx . mk_const ( valtree, ty) )
596
+ } else {
597
+ value. eval ( self . tcx , self . param_env )
598
+ }
599
+ }
600
+ mir:: ConstantKind :: Val ( _, _) => unreachable ! ( ) ,
601
+ } ;
584
602
585
603
match value {
586
604
mir:: ConstantKind :: Ty ( c) => match c. kind ( ) {
@@ -591,15 +609,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
591
609
ConstKind :: Error ( _) => {
592
610
return PatKind :: Wild ;
593
611
}
594
- _ => bug ! ( "Expected ConstKind::Param" ) ,
612
+ _ => { }
595
613
} ,
596
- mir:: ConstantKind :: Val ( _, _) => self . const_to_pat ( value , id , span , false ) . kind ,
614
+ mir:: ConstantKind :: Val ( _, _) => { }
597
615
mir:: ConstantKind :: Unevaluated ( ..) => {
598
616
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
599
617
self . tcx . sess . emit_err ( ConstPatternDependsOnGenericParameter { span } ) ;
600
618
return PatKind :: Wild ;
601
619
}
602
620
}
621
+
622
+ self . const_to_pat ( value, id, span, None ) . kind
603
623
}
604
624
605
625
/// Converts literals, paths and negation of literals to patterns.
@@ -626,8 +646,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
626
646
627
647
let lit_input =
628
648
LitToConstInput { lit : & lit. node , ty : self . typeck_results . expr_ty ( expr) , neg } ;
629
- match self . tcx . at ( expr. span ) . lit_to_mir_constant ( lit_input) {
630
- Ok ( constant) => self . const_to_pat ( constant, expr. hir_id , lit. span , false ) . kind ,
649
+ match self
650
+ . tcx
651
+ . at ( expr. span )
652
+ . lit_to_const ( lit_input)
653
+ . map ( mir:: ConstantKind :: Ty )
654
+ . or_else ( |_| self . tcx . at ( expr. span ) . lit_to_mir_constant ( lit_input) )
655
+ {
656
+ Ok ( constant) => self . const_to_pat ( constant, expr. hir_id , lit. span , None ) . kind ,
631
657
Err ( LitToConstError :: Reported ( _) ) => PatKind :: Wild ,
632
658
Err ( LitToConstError :: TypeError ) => bug ! ( "lower_lit: had type error" ) ,
633
659
}
@@ -806,6 +832,9 @@ pub(crate) fn compare_const_vals<'tcx>(
806
832
mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( a) ) , _a_ty) ,
807
833
mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( b) ) , _b_ty) ,
808
834
) => return Some ( a. cmp ( & b) ) ,
835
+ ( mir:: ConstantKind :: Ty ( a) , mir:: ConstantKind :: Ty ( b) ) => {
836
+ return Some ( a. kind ( ) . cmp ( & b. kind ( ) ) ) ;
837
+ }
809
838
_ => { }
810
839
} ,
811
840
}
0 commit comments