@@ -14,13 +14,11 @@ use rustc_abi::VariantIdx;
14
14
use rustc_data_structures:: fx:: FxIndexMap ;
15
15
use rustc_data_structures:: stack:: ensure_sufficient_stack;
16
16
use rustc_hir:: { BindingMode , ByRef , LetStmt , LocalSource , Node } ;
17
+ use rustc_middle:: bug;
17
18
use rustc_middle:: middle:: region;
18
19
use rustc_middle:: mir:: { self , * } ;
19
20
use 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 } ;
24
22
use rustc_pattern_analysis:: constructor:: RangeEnd ;
25
23
use rustc_pattern_analysis:: rustc:: { DeconstructedPat , RustcPatCtxt } ;
26
24
use rustc_span:: { BytePos , Pos , Span , Symbol , sym} ;
@@ -2871,14 +2869,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2871
2869
pub ( crate ) fn static_pattern_match (
2872
2870
& self ,
2873
2871
cx : & RustcPatCtxt < ' _ , ' tcx > ,
2874
- constant : ConstOperand < ' tcx > ,
2872
+ valtree : ValTree < ' tcx > ,
2875
2873
arms : & [ ArmId ] ,
2876
2874
built_match_tree : & BuiltMatchTree < ' tcx > ,
2877
2875
) -> Option < BasicBlock > {
2878
2876
let it = arms. iter ( ) . zip ( built_match_tree. branches . iter ( ) ) ;
2879
2877
for ( & arm_id, branch) in it {
2880
2878
let pat = cx. lower_pat ( & * self . thir . arms [ arm_id] . pattern ) ;
2881
2879
2880
+ // Peel off or-patterns if they exist.
2882
2881
if let rustc_pattern_analysis:: rustc:: Constructor :: Or = pat. ctor ( ) {
2883
2882
for pat in pat. iter_fields ( ) {
2884
2883
// For top-level or-patterns (the only ones we accept right now), when the
@@ -2890,66 +2889,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2890
2889
. or_else ( || branch. sub_branches . last ( ) )
2891
2890
. unwrap ( ) ;
2892
2891
2893
- match self . static_pattern_match_help ( constant , & pat. pat ) {
2892
+ match self . static_pattern_match_inner ( valtree , & pat. pat ) {
2894
2893
true => return Some ( sub_branch. success_block ) ,
2895
2894
false => continue ,
2896
2895
}
2897
2896
}
2898
- } else if self . static_pattern_match_help ( constant , & pat) {
2897
+ } else if self . static_pattern_match_inner ( valtree , & pat) {
2899
2898
return Some ( branch. sub_branches [ 0 ] . success_block ) ;
2900
2899
}
2901
2900
}
2902
2901
2903
2902
None
2904
2903
}
2905
2904
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 (
2943
2908
& self ,
2944
- constant : ConstOperand < ' tcx > ,
2909
+ valtree : ty :: ValTree < ' tcx > ,
2945
2910
pat : & DeconstructedPat < ' _ , ' tcx > ,
2946
2911
) -> bool {
2947
2912
use rustc_pattern_analysis:: constructor:: { IntRange , MaybeInfiniteInt } ;
2948
2913
use rustc_pattern_analysis:: rustc:: Constructor ;
2949
2914
2950
- let ( valtree, ty) = self . eval_unevaluated_mir_constant_to_valtree ( constant) ;
2951
- assert ! ( !ty. has_param( ) ) ;
2952
-
2953
2915
match pat. ctor ( ) {
2954
2916
Constructor :: Variant ( variant_index) => {
2955
2917
let ValTreeKind :: Branch ( box [ actual_variant_idx] ) = * valtree else {
0 commit comments