@@ -18,7 +18,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
1818use rustc_hir:: RangeEnd ;
1919use rustc_index:: Idx ;
2020use rustc_middle:: mir:: interpret:: {
21- ConstValue , ErrorHandled , LitToConstError , LitToConstInput , Scalar ,
21+ ConstValue , ErrorHandled , GlobalId , LitToConstError , LitToConstInput , Scalar ,
2222} ;
2323use rustc_middle:: mir:: { self , UserTypeProjection } ;
2424use rustc_middle:: mir:: { BorrowKind , Mutability } ;
@@ -518,16 +518,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
518518 }
519519 } ;
520520
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 ( ) ) ) ;
531537
532538 if !is_associated_const {
533539 return pattern;
@@ -578,9 +584,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
578584 span : Span ,
579585 ) -> PatKind < ' tcx > {
580586 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+ } ;
584602
585603 match value {
586604 mir:: ConstantKind :: Ty ( c) => match c. kind ( ) {
@@ -591,15 +609,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
591609 ConstKind :: Error ( _) => {
592610 return PatKind :: Wild ;
593611 }
594- _ => bug ! ( "Expected ConstKind::Param" ) ,
612+ _ => { }
595613 } ,
596- mir:: ConstantKind :: Val ( _, _) => self . const_to_pat ( value , id , span , false ) . kind ,
614+ mir:: ConstantKind :: Val ( _, _) => { }
597615 mir:: ConstantKind :: Unevaluated ( ..) => {
598616 // If we land here it means the const can't be evaluated because it's `TooGeneric`.
599617 self . tcx . sess . emit_err ( ConstPatternDependsOnGenericParameter { span } ) ;
600618 return PatKind :: Wild ;
601619 }
602620 }
621+
622+ self . const_to_pat ( value, id, span, None ) . kind
603623 }
604624
605625 /// Converts literals, paths and negation of literals to patterns.
@@ -626,8 +646,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
626646
627647 let lit_input =
628648 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 ,
631657 Err ( LitToConstError :: Reported ( _) ) => PatKind :: Wild ,
632658 Err ( LitToConstError :: TypeError ) => bug ! ( "lower_lit: had type error" ) ,
633659 }
@@ -806,6 +832,9 @@ pub(crate) fn compare_const_vals<'tcx>(
806832 mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( a) ) , _a_ty) ,
807833 mir:: ConstantKind :: Val ( ConstValue :: Scalar ( Scalar :: Int ( b) ) , _b_ty) ,
808834 ) => return Some ( a. cmp ( & b) ) ,
835+ ( mir:: ConstantKind :: Ty ( a) , mir:: ConstantKind :: Ty ( b) ) => {
836+ return Some ( a. kind ( ) . cmp ( & b. kind ( ) ) ) ;
837+ }
809838 _ => { }
810839 } ,
811840 }
0 commit comments