@@ -14,13 +14,11 @@ use rustc_abi::VariantIdx;
1414use rustc_data_structures:: fx:: FxIndexMap ;
1515use rustc_data_structures:: stack:: ensure_sufficient_stack;
1616use rustc_hir:: { BindingMode , ByRef , LetStmt , LocalSource , Node } ;
17+ use rustc_middle:: bug;
1718use rustc_middle:: middle:: region;
1819use rustc_middle:: mir:: { self , * } ;
1920use rustc_middle:: thir:: { self , * } ;
20- use rustc_middle:: ty:: {
21- self , CanonicalUserTypeAnnotation , Ty , TypeVisitableExt , ValTree , ValTreeKind ,
22- } ;
23- use rustc_middle:: { bug, span_bug} ;
21+ use rustc_middle:: ty:: { self , CanonicalUserTypeAnnotation , Ty , ValTree , ValTreeKind } ;
2422use rustc_pattern_analysis:: constructor:: RangeEnd ;
2523use rustc_pattern_analysis:: rustc:: { DeconstructedPat , RustcPatCtxt } ;
2624use rustc_span:: { BytePos , Pos , Span , Symbol , sym} ;
@@ -2871,14 +2869,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
28712869 pub ( crate ) fn static_pattern_match (
28722870 & self ,
28732871 cx : & RustcPatCtxt < ' _ , ' tcx > ,
2874- constant : ConstOperand < ' tcx > ,
2872+ valtree : ValTree < ' tcx > ,
28752873 arms : & [ ArmId ] ,
28762874 built_match_tree : & BuiltMatchTree < ' tcx > ,
28772875 ) -> Option < BasicBlock > {
28782876 let it = arms. iter ( ) . zip ( built_match_tree. branches . iter ( ) ) ;
28792877 for ( & arm_id, branch) in it {
28802878 let pat = cx. lower_pat ( & * self . thir . arms [ arm_id] . pattern ) ;
28812879
2880+ // Peel off or-patterns if they exist.
28822881 if let rustc_pattern_analysis:: rustc:: Constructor :: Or = pat. ctor ( ) {
28832882 for pat in pat. iter_fields ( ) {
28842883 // For top-level or-patterns (the only ones we accept right now), when the
@@ -2890,66 +2889,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
28902889 . or_else ( || branch. sub_branches . last ( ) )
28912890 . unwrap ( ) ;
28922891
2893- match self . static_pattern_match_help ( constant , & pat. pat ) {
2892+ match self . static_pattern_match_inner ( valtree , & pat. pat ) {
28942893 true => return Some ( sub_branch. success_block ) ,
28952894 false => continue ,
28962895 }
28972896 }
2898- } else if self . static_pattern_match_help ( constant , & pat) {
2897+ } else if self . static_pattern_match_inner ( valtree , & pat) {
28992898 return Some ( branch. sub_branches [ 0 ] . success_block ) ;
29002899 }
29012900 }
29022901
29032902 None
29042903 }
29052904
2906- /// Based on `FunctionCx::eval_unevaluated_mir_constant_to_valtree`.
2907- fn eval_unevaluated_mir_constant_to_valtree (
2908- & self ,
2909- constant : ConstOperand < ' tcx > ,
2910- ) -> ( ty:: ValTree < ' tcx > , Ty < ' tcx > ) {
2911- assert ! ( !constant. const_. ty( ) . has_param( ) ) ;
2912- let ( uv, ty) = match constant. const_ {
2913- mir:: Const :: Unevaluated ( uv, ty) => ( uv. shrink ( ) , ty) ,
2914- mir:: Const :: Ty ( _, c) => match c. kind ( ) {
2915- // A constant that came from a const generic but was then used as an argument to
2916- // old-style simd_shuffle (passing as argument instead of as a generic param).
2917- ty:: ConstKind :: Value ( cv) => return ( cv. valtree , cv. ty ) ,
2918- other => span_bug ! ( constant. span, "{other:#?}" ) ,
2919- } ,
2920- mir:: Const :: Val ( mir:: ConstValue :: Scalar ( mir:: interpret:: Scalar :: Int ( val) ) , ty) => {
2921- return ( ValTree :: from_scalar_int ( self . tcx , val) , ty) ;
2922- }
2923- // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
2924- // a constant and write that value back into `Operand`s. This could happen, but is
2925- // unlikely. Also: all users of `simd_shuffle` are on unstable and already need to take
2926- // a lot of care around intrinsics. For an issue to happen here, it would require a
2927- // macro expanding to a `simd_shuffle` call without wrapping the constant argument in a
2928- // `const {}` block, but the user pass through arbitrary expressions.
2929-
2930- // FIXME(oli-obk): Replace the magic const generic argument of `simd_shuffle` with a
2931- // real const generic, and get rid of this entire function.
2932- other => span_bug ! ( constant. span, "{other:#?}" ) ,
2933- } ;
2934-
2935- match self . tcx . const_eval_resolve_for_typeck ( self . typing_env ( ) , uv, constant. span ) {
2936- Ok ( Ok ( valtree) ) => ( valtree, ty) ,
2937- Ok ( Err ( ty) ) => span_bug ! ( constant. span, "could not convert {ty:?} to a valtree" ) ,
2938- Err ( _) => span_bug ! ( constant. span, "unable to evaluate this constant" ) ,
2939- }
2940- }
2941-
2942- fn static_pattern_match_help (
2905+ /// Helper for [`Self::static_pattern_match`]. It does not recurse, meaning that it does not
2906+ /// handle or-patterns, or patterns for types with fields.
2907+ fn static_pattern_match_inner (
29432908 & self ,
2944- constant : ConstOperand < ' tcx > ,
2909+ valtree : ty :: ValTree < ' tcx > ,
29452910 pat : & DeconstructedPat < ' _ , ' tcx > ,
29462911 ) -> bool {
29472912 use rustc_pattern_analysis:: constructor:: { IntRange , MaybeInfiniteInt } ;
29482913 use rustc_pattern_analysis:: rustc:: Constructor ;
29492914
2950- let ( valtree, ty) = self . eval_unevaluated_mir_constant_to_valtree ( constant) ;
2951- assert ! ( !ty. has_param( ) ) ;
2952-
29532915 match pat. ctor ( ) {
29542916 Constructor :: Variant ( variant_index) => {
29552917 let ValTreeKind :: Branch ( box [ actual_variant_idx] ) = * valtree else {
0 commit comments