@@ -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} ;
@@ -2872,14 +2870,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
28722870 pub ( crate ) fn static_pattern_match (
28732871 & self ,
28742872 cx : & RustcPatCtxt < ' _ , ' tcx > ,
2875- constant : ConstOperand < ' tcx > ,
2873+ valtree : ValTree < ' tcx > ,
28762874 arms : & [ ArmId ] ,
28772875 built_match_tree : & BuiltMatchTree < ' tcx > ,
28782876 ) -> Option < BasicBlock > {
28792877 let it = arms. iter ( ) . zip ( built_match_tree. branches . iter ( ) ) ;
28802878 for ( & arm_id, branch) in it {
28812879 let pat = cx. lower_pat ( & * self . thir . arms [ arm_id] . pattern ) ;
28822880
2881+ // Peel off or-patterns if they exist.
28832882 if let rustc_pattern_analysis:: rustc:: Constructor :: Or = pat. ctor ( ) {
28842883 for pat in pat. iter_fields ( ) {
28852884 // For top-level or-patterns (the only ones we accept right now), when the
@@ -2891,66 +2890,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
28912890 . or_else ( || branch. sub_branches . last ( ) )
28922891 . unwrap ( ) ;
28932892
2894- match self . static_pattern_match_help ( constant , & pat. pat ) {
2893+ match self . static_pattern_match_inner ( valtree , & pat. pat ) {
28952894 true => return Some ( sub_branch. success_block ) ,
28962895 false => continue ,
28972896 }
28982897 }
2899- } else if self . static_pattern_match_help ( constant , & pat) {
2898+ } else if self . static_pattern_match_inner ( valtree , & pat) {
29002899 return Some ( branch. sub_branches [ 0 ] . success_block ) ;
29012900 }
29022901 }
29032902
29042903 None
29052904 }
29062905
2907- /// Based on `FunctionCx::eval_unevaluated_mir_constant_to_valtree`.
2908- fn eval_unevaluated_mir_constant_to_valtree (
2909- & self ,
2910- constant : ConstOperand < ' tcx > ,
2911- ) -> ( ty:: ValTree < ' tcx > , Ty < ' tcx > ) {
2912- assert ! ( !constant. const_. ty( ) . has_param( ) ) ;
2913- let ( uv, ty) = match constant. const_ {
2914- mir:: Const :: Unevaluated ( uv, ty) => ( uv. shrink ( ) , ty) ,
2915- mir:: Const :: Ty ( _, c) => match c. kind ( ) {
2916- // A constant that came from a const generic but was then used as an argument to
2917- // old-style simd_shuffle (passing as argument instead of as a generic param).
2918- ty:: ConstKind :: Value ( cv) => return ( cv. valtree , cv. ty ) ,
2919- other => span_bug ! ( constant. span, "{other:#?}" ) ,
2920- } ,
2921- mir:: Const :: Val ( mir:: ConstValue :: Scalar ( mir:: interpret:: Scalar :: Int ( val) ) , ty) => {
2922- return ( ValTree :: from_scalar_int ( self . tcx , val) , ty) ;
2923- }
2924- // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
2925- // a constant and write that value back into `Operand`s. This could happen, but is
2926- // unlikely. Also: all users of `simd_shuffle` are on unstable and already need to take
2927- // a lot of care around intrinsics. For an issue to happen here, it would require a
2928- // macro expanding to a `simd_shuffle` call without wrapping the constant argument in a
2929- // `const {}` block, but the user pass through arbitrary expressions.
2930-
2931- // FIXME(oli-obk): Replace the magic const generic argument of `simd_shuffle` with a
2932- // real const generic, and get rid of this entire function.
2933- other => span_bug ! ( constant. span, "{other:#?}" ) ,
2934- } ;
2935-
2936- match self . tcx . const_eval_resolve_for_typeck ( self . typing_env ( ) , uv, constant. span ) {
2937- Ok ( Ok ( valtree) ) => ( valtree, ty) ,
2938- Ok ( Err ( ty) ) => span_bug ! ( constant. span, "could not convert {ty:?} to a valtree" ) ,
2939- Err ( _) => span_bug ! ( constant. span, "unable to evaluate this constant" ) ,
2940- }
2941- }
2942-
2943- fn static_pattern_match_help (
2906+ /// Helper for [`Self::static_pattern_match`]. It does not recurse, meaning that it does not
2907+ /// handle or-patterns, or patterns for types with fields.
2908+ fn static_pattern_match_inner (
29442909 & self ,
2945- constant : ConstOperand < ' tcx > ,
2910+ valtree : ty :: ValTree < ' tcx > ,
29462911 pat : & DeconstructedPat < ' _ , ' tcx > ,
29472912 ) -> bool {
29482913 use rustc_pattern_analysis:: constructor:: { IntRange , MaybeInfiniteInt } ;
29492914 use rustc_pattern_analysis:: rustc:: Constructor ;
29502915
2951- let ( valtree, ty) = self . eval_unevaluated_mir_constant_to_valtree ( constant) ;
2952- assert ! ( !ty. has_param( ) ) ;
2953-
29542916 match pat. ctor ( ) {
29552917 Constructor :: Variant ( variant_index) => {
29562918 let ValTreeKind :: Branch ( box [ actual_variant_idx] ) = * valtree else {
0 commit comments