@@ -284,10 +284,9 @@ use super::{FieldPat, Pat, PatKind, PatRange};
284
284
285
285
use rustc_arena:: TypedArena ;
286
286
use rustc_attr:: { SignedInt , UnsignedInt } ;
287
- use rustc_errors:: ErrorReported ;
288
287
use rustc_hir:: def_id:: DefId ;
289
288
use rustc_hir:: { HirId , RangeEnd } ;
290
- use rustc_middle:: mir:: interpret:: { truncate, AllocId , ConstValue , Pointer , Scalar } ;
289
+ use rustc_middle:: mir:: interpret:: { truncate, ConstValue } ;
291
290
use rustc_middle:: mir:: Field ;
292
291
use rustc_middle:: ty:: layout:: IntegerExt ;
293
292
use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
@@ -296,84 +295,21 @@ use rustc_span::{Span, DUMMY_SP};
296
295
use rustc_target:: abi:: { Integer , Size , VariantIdx } ;
297
296
298
297
use smallvec:: { smallvec, SmallVec } ;
299
- use std:: borrow:: Cow ;
300
298
use std:: cmp:: { self , max, min, Ordering } ;
301
- use std:: convert:: TryInto ;
302
299
use std:: fmt;
303
300
use std:: iter:: { FromIterator , IntoIterator } ;
304
301
use std:: ops:: RangeInclusive ;
305
302
306
- crate fn expand_pattern < ' a , ' tcx > ( cx : & MatchCheckCtxt < ' a , ' tcx > , pat : Pat < ' tcx > ) -> Pat < ' tcx > {
307
- LiteralExpander { tcx : cx . tcx } . fold_pattern ( & pat)
303
+ crate fn expand_pattern < ' tcx > ( pat : Pat < ' tcx > ) -> Pat < ' tcx > {
304
+ LiteralExpander . fold_pattern ( & pat)
308
305
}
309
306
310
- struct LiteralExpander < ' tcx > {
311
- tcx : TyCtxt < ' tcx > ,
312
- }
307
+ struct LiteralExpander ;
313
308
314
- impl < ' tcx > LiteralExpander < ' tcx > {
315
- /// Derefs `val` and potentially unsizes the value if `crty` is an array and `rty` a slice.
316
- ///
317
- /// `crty` and `rty` can differ because you can use array constants in the presence of slice
318
- /// patterns. So the pattern may end up being a slice, but the constant is an array. We convert
319
- /// the array to a slice in that case.
320
- fn fold_const_value_deref (
321
- & mut self ,
322
- val : ConstValue < ' tcx > ,
323
- // the pattern's pointee type
324
- rty : Ty < ' tcx > ,
325
- // the constant's pointee type
326
- crty : Ty < ' tcx > ,
327
- ) -> ConstValue < ' tcx > {
328
- debug ! ( "fold_const_value_deref {:?} {:?} {:?}" , val, rty, crty) ;
329
- match ( val, & crty. kind ( ) , & rty. kind ( ) ) {
330
- // unsize array to slice if pattern is array but match value or other patterns are slice
331
- ( ConstValue :: Scalar ( Scalar :: Ptr ( p) ) , ty:: Array ( t, n) , ty:: Slice ( u) ) => {
332
- assert_eq ! ( t, u) ;
333
- assert_eq ! ( p. offset, Size :: ZERO ) ;
334
- ConstValue :: Slice {
335
- data : self . tcx . global_alloc ( p. alloc_id ) . unwrap_memory ( ) ,
336
- start : 0 ,
337
- end : n. eval_usize ( self . tcx , ty:: ParamEnv :: empty ( ) ) . try_into ( ) . unwrap ( ) ,
338
- }
339
- }
340
- _ => val,
341
- }
342
- }
343
- }
344
-
345
- impl < ' tcx > PatternFolder < ' tcx > for LiteralExpander < ' tcx > {
309
+ impl < ' tcx > PatternFolder < ' tcx > for LiteralExpander {
346
310
fn fold_pattern ( & mut self , pat : & Pat < ' tcx > ) -> Pat < ' tcx > {
347
311
debug ! ( "fold_pattern {:?} {:?} {:?}" , pat, pat. ty. kind( ) , pat. kind) ;
348
312
match ( pat. ty . kind ( ) , & * pat. kind ) {
349
- ( & ty:: Ref ( _, rty, _) , & PatKind :: Constant { value : Const { val, ty : const_ty } } )
350
- if const_ty. is_ref ( ) =>
351
- {
352
- let crty =
353
- if let ty:: Ref ( _, crty, _) = const_ty. kind ( ) { crty } else { unreachable ! ( ) } ;
354
- if let ty:: ConstKind :: Value ( val) = val {
355
- Pat {
356
- ty : pat. ty ,
357
- span : pat. span ,
358
- kind : box PatKind :: Deref {
359
- subpattern : Pat {
360
- ty : rty,
361
- span : pat. span ,
362
- kind : box PatKind :: Constant {
363
- value : Const :: from_value (
364
- self . tcx ,
365
- self . fold_const_value_deref ( * val, rty, crty) ,
366
- rty,
367
- ) ,
368
- } ,
369
- } ,
370
- } ,
371
- }
372
- } else {
373
- bug ! ( "cannot deref {:#?}, {} -> {}" , val, crty, rty)
374
- }
375
- }
376
-
377
313
( _, & PatKind :: Binding { subpattern : Some ( ref s) , .. } ) => s. fold_with ( self ) ,
378
314
( _, & PatKind :: AscribeUserType { subpattern : ref s, .. } ) => s. fold_with ( self ) ,
379
315
_ => pat. super_fold_with ( self ) ,
@@ -941,8 +877,6 @@ impl<'tcx> Constructor<'tcx> {
941
877
. iter ( )
942
878
. filter_map ( |c : & Constructor < ' _ > | match c {
943
879
Slice ( slice) => Some ( * slice) ,
944
- // FIXME(oli-obk): implement `deref` for `ConstValue`
945
- ConstantValue ( ..) => None ,
946
880
_ => bug ! ( "bad slice pattern constructor {:?}" , c) ,
947
881
} )
948
882
. map ( Slice :: value_kind) ;
@@ -1162,12 +1096,6 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1162
1096
Fields :: Slice ( std:: slice:: from_ref ( pat) )
1163
1097
}
1164
1098
1165
- /// Construct a new `Fields` from the given patterns. You must be sure those patterns can't
1166
- /// contain fields that need to be filtered out. When in doubt, prefer `replace_fields`.
1167
- fn from_slice_unfiltered ( pats : & ' p [ Pat < ' tcx > ] ) -> Self {
1168
- Fields :: Slice ( pats)
1169
- }
1170
-
1171
1099
/// Convenience; internal use.
1172
1100
fn wildcards_from_tys (
1173
1101
cx : & MatchCheckCtxt < ' p , ' tcx > ,
@@ -2183,19 +2111,7 @@ fn pat_constructor<'tcx>(
2183
2111
if let Some ( int_range) = IntRange :: from_const ( tcx, param_env, value, pat. span ) {
2184
2112
Some ( IntRange ( int_range) )
2185
2113
} else {
2186
- match ( value. val , & value. ty . kind ( ) ) {
2187
- ( _, ty:: Array ( _, n) ) => {
2188
- let len = n. eval_usize ( tcx, param_env) ;
2189
- Some ( Slice ( Slice { array_len : Some ( len) , kind : FixedLen ( len) } ) )
2190
- }
2191
- ( ty:: ConstKind :: Value ( ConstValue :: Slice { start, end, .. } ) , ty:: Slice ( _) ) => {
2192
- let len = ( end - start) as u64 ;
2193
- Some ( Slice ( Slice { array_len : None , kind : FixedLen ( len) } ) )
2194
- }
2195
- // FIXME(oli-obk): implement `deref` for `ConstValue`
2196
- // (ty::ConstKind::Value(ConstValue::ByRef { .. }), ty::Slice(_)) => { ... }
2197
- _ => Some ( ConstantValue ( value) ) ,
2198
- }
2114
+ Some ( ConstantValue ( value) )
2199
2115
}
2200
2116
}
2201
2117
PatKind :: Range ( PatRange { lo, hi, end } ) => {
@@ -2230,75 +2146,6 @@ fn pat_constructor<'tcx>(
2230
2146
}
2231
2147
}
2232
2148
2233
- // checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
2234
- // meaning all other types will compare unequal and thus equal patterns often do not cause the
2235
- // second pattern to lint about unreachable match arms.
2236
- fn slice_pat_covered_by_const < ' tcx > (
2237
- tcx : TyCtxt < ' tcx > ,
2238
- _span : Span ,
2239
- const_val : & ' tcx ty:: Const < ' tcx > ,
2240
- prefix : & [ Pat < ' tcx > ] ,
2241
- slice : & Option < Pat < ' tcx > > ,
2242
- suffix : & [ Pat < ' tcx > ] ,
2243
- param_env : ty:: ParamEnv < ' tcx > ,
2244
- ) -> Result < bool , ErrorReported > {
2245
- let const_val_val = if let ty:: ConstKind :: Value ( val) = const_val. val {
2246
- val
2247
- } else {
2248
- bug ! (
2249
- "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}" ,
2250
- const_val,
2251
- prefix,
2252
- slice,
2253
- suffix,
2254
- )
2255
- } ;
2256
-
2257
- let data: & [ u8 ] = match ( const_val_val, & const_val. ty . kind ( ) ) {
2258
- ( ConstValue :: ByRef { offset, alloc, .. } , ty:: Array ( t, n) ) => {
2259
- assert_eq ! ( * t, tcx. types. u8 ) ;
2260
- let n = n. eval_usize ( tcx, param_env) ;
2261
- let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
2262
- alloc. get_bytes ( & tcx, ptr, Size :: from_bytes ( n) ) . unwrap ( )
2263
- }
2264
- ( ConstValue :: Slice { data, start, end } , ty:: Slice ( t) ) => {
2265
- assert_eq ! ( * t, tcx. types. u8 ) ;
2266
- let ptr = Pointer :: new ( AllocId ( 0 ) , Size :: from_bytes ( start) ) ;
2267
- data. get_bytes ( & tcx, ptr, Size :: from_bytes ( end - start) ) . unwrap ( )
2268
- }
2269
- // FIXME(oli-obk): create a way to extract fat pointers from ByRef
2270
- ( _, ty:: Slice ( _) ) => return Ok ( false ) ,
2271
- _ => bug ! (
2272
- "slice_pat_covered_by_const: {:#?}, {:#?}, {:#?}, {:#?}" ,
2273
- const_val,
2274
- prefix,
2275
- slice,
2276
- suffix,
2277
- ) ,
2278
- } ;
2279
-
2280
- let pat_len = prefix. len ( ) + suffix. len ( ) ;
2281
- if data. len ( ) < pat_len || ( slice. is_none ( ) && data. len ( ) > pat_len) {
2282
- return Ok ( false ) ;
2283
- }
2284
-
2285
- for ( ch, pat) in data[ ..prefix. len ( ) ]
2286
- . iter ( )
2287
- . zip ( prefix)
2288
- . chain ( data[ data. len ( ) - suffix. len ( ) ..] . iter ( ) . zip ( suffix) )
2289
- {
2290
- if let box PatKind :: Constant { value } = pat. kind {
2291
- let b = value. eval_bits ( tcx, param_env, pat. ty ) ;
2292
- assert_eq ! ( b as u8 as u128 , b) ;
2293
- if b as u8 != * ch {
2294
- return Ok ( false ) ;
2295
- }
2296
- }
2297
- }
2298
-
2299
- Ok ( true )
2300
- }
2301
-
2302
2149
/// For exhaustive integer matching, some constructors are grouped within other constructors
2303
2150
/// (namely integer typed values are grouped within ranges). However, when specialising these
2304
2151
/// constructors, we want to be specialising for the underlying constructors (the integers), not
@@ -2670,73 +2517,7 @@ fn specialize_one_pattern<'p, 'tcx>(
2670
2517
PatKind :: Deref { ref subpattern } => Some ( Fields :: from_single_pattern ( subpattern) ) ,
2671
2518
2672
2519
PatKind :: Constant { value } if constructor. is_slice ( ) => {
2673
- // We extract an `Option` for the pointer because slices of zero
2674
- // elements don't necessarily point to memory, they are usually
2675
- // just integers. The only time they should be pointing to memory
2676
- // is when they are subslices of nonzero slices.
2677
- let ( alloc, offset, n, ty) = match value. ty . kind ( ) {
2678
- ty:: Array ( t, n) => {
2679
- let n = n. eval_usize ( cx. tcx , cx. param_env ) ;
2680
- // Shortcut for `n == 0` where no matter what `alloc` and `offset` we produce,
2681
- // the result would be exactly what we early return here.
2682
- if n == 0 {
2683
- if ctor_wild_subpatterns. len ( ) as u64 != n {
2684
- return None ;
2685
- }
2686
- return Some ( Fields :: empty ( ) ) ;
2687
- }
2688
- match value. val {
2689
- ty:: ConstKind :: Value ( ConstValue :: ByRef { offset, alloc, .. } ) => {
2690
- ( Cow :: Borrowed ( alloc) , offset, n, t)
2691
- }
2692
- _ => span_bug ! ( pat. span, "array pattern is {:?}" , value, ) ,
2693
- }
2694
- }
2695
- ty:: Slice ( t) => {
2696
- match value. val {
2697
- ty:: ConstKind :: Value ( ConstValue :: Slice { data, start, end } ) => {
2698
- let offset = Size :: from_bytes ( start) ;
2699
- let n = ( end - start) as u64 ;
2700
- ( Cow :: Borrowed ( data) , offset, n, t)
2701
- }
2702
- ty:: ConstKind :: Value ( ConstValue :: ByRef { .. } ) => {
2703
- // FIXME(oli-obk): implement `deref` for `ConstValue`
2704
- return None ;
2705
- }
2706
- _ => span_bug ! (
2707
- pat. span,
2708
- "slice pattern constant must be scalar pair but is {:?}" ,
2709
- value,
2710
- ) ,
2711
- }
2712
- }
2713
- _ => span_bug ! (
2714
- pat. span,
2715
- "unexpected const-val {:?} with ctor {:?}" ,
2716
- value,
2717
- constructor,
2718
- ) ,
2719
- } ;
2720
- if ctor_wild_subpatterns. len ( ) as u64 != n {
2721
- return None ;
2722
- }
2723
-
2724
- // Convert a constant slice/array pattern to a list of patterns.
2725
- let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
2726
- let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
2727
- let pats = cx. pattern_arena . alloc_from_iter ( ( 0 ..n) . filter_map ( |i| {
2728
- let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
2729
- let scalar = alloc. read_scalar ( & cx. tcx , ptr, layout. size ) . ok ( ) ?;
2730
- let scalar = scalar. check_init ( ) . ok ( ) ?;
2731
- let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
2732
- let pattern = Pat { ty, span : pat. span , kind : box PatKind :: Constant { value } } ;
2733
- Some ( pattern)
2734
- } ) ) ;
2735
- // Ensure none of the dereferences failed.
2736
- if pats. len ( ) as u64 != n {
2737
- return None ;
2738
- }
2739
- Some ( Fields :: from_slice_unfiltered ( pats) )
2520
+ span_bug ! ( pat. span, "unexpected const-val {:?} with ctor {:?}" , value, constructor)
2740
2521
}
2741
2522
2742
2523
PatKind :: Constant { .. } | PatKind :: Range { .. } => {
@@ -2778,21 +2559,7 @@ fn specialize_one_pattern<'p, 'tcx>(
2778
2559
let suffix = suffix. iter ( ) . enumerate ( ) . map ( |( i, p) | ( arity - suffix. len ( ) + i, p) ) ;
2779
2560
Some ( ctor_wild_subpatterns. replace_fields_indexed ( prefix. chain ( suffix) ) )
2780
2561
}
2781
- ConstantValue ( cv) => {
2782
- match slice_pat_covered_by_const (
2783
- cx. tcx ,
2784
- pat. span ,
2785
- cv,
2786
- prefix,
2787
- slice,
2788
- suffix,
2789
- cx. param_env ,
2790
- ) {
2791
- Ok ( true ) => Some ( Fields :: empty ( ) ) ,
2792
- Ok ( false ) => None ,
2793
- Err ( ErrorReported ) => None ,
2794
- }
2795
- }
2562
+ ConstantValue ( _) => None ,
2796
2563
_ => span_bug ! ( pat. span, "unexpected ctor {:?} for slice pat" , constructor) ,
2797
2564
} ,
2798
2565
0 commit comments