@@ -2390,7 +2390,10 @@ fn specialize_one_pattern<'p, 'tcx>(
23902390) -> Option < Fields < ' p , ' tcx > > {
23912391 if let NonExhaustive = constructor {
23922392 // Only a wildcard pattern can match the special extra constructor
2393- return if pat. is_wildcard ( ) { Some ( Fields :: empty ( ) ) } else { None } ;
2393+ if !pat. is_wildcard ( ) {
2394+ return None ;
2395+ }
2396+ return Some ( Fields :: empty ( ) ) ;
23942397 }
23952398
23962399 let result = match * pat. kind {
@@ -2400,12 +2403,11 @@ fn specialize_one_pattern<'p, 'tcx>(
24002403
24012404 PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
24022405 let variant = & adt_def. variants [ variant_index] ;
2406+ if constructor != & Variant ( variant. def_id ) {
2407+ return None ;
2408+ }
24032409 let is_non_exhaustive = cx. is_foreign_non_exhaustive_variant ( pat. ty , variant) ;
2404- Some ( Variant ( variant. def_id ) )
2405- . filter ( |variant_constructor| variant_constructor == constructor)
2406- . map ( |_| {
2407- patterns_for_variant ( cx, subpatterns, ctor_wild_subpatterns, is_non_exhaustive)
2408- } )
2410+ Some ( patterns_for_variant ( cx, subpatterns, ctor_wild_subpatterns, is_non_exhaustive) )
24092411 }
24102412
24112413 PatKind :: Leaf { ref subpatterns } => {
@@ -2425,11 +2427,10 @@ fn specialize_one_pattern<'p, 'tcx>(
24252427 // Shortcut for `n == 0` where no matter what `alloc` and `offset` we produce,
24262428 // the result would be exactly what we early return here.
24272429 if n == 0 {
2428- if ctor_wild_subpatterns. len ( ) as u64 == 0 {
2429- return Some ( Fields :: empty ( ) ) ;
2430- } else {
2430+ if ctor_wild_subpatterns. len ( ) as u64 != n {
24312431 return None ;
24322432 }
2433+ return Some ( Fields :: empty ( ) ) ;
24332434 }
24342435 match value. val {
24352436 ty:: ConstKind :: Value ( ConstValue :: ByRef { offset, alloc, .. } ) => {
@@ -2463,76 +2464,66 @@ fn specialize_one_pattern<'p, 'tcx>(
24632464 constructor,
24642465 ) ,
24652466 } ;
2466- if ctor_wild_subpatterns. len ( ) as u64 == n {
2467- // convert a constant slice/array pattern to a list of patterns.
2468- let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
2469- let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
2470- let pats = ( 0 ..n)
2471- . map ( |i| {
2472- let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
2473- let scalar = alloc. read_scalar ( & cx. tcx , ptr, layout. size ) . ok ( ) ?;
2474- let scalar = scalar. not_undef ( ) . ok ( ) ?;
2475- let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
2476- let pattern =
2477- Pat { ty, span : pat. span , kind : box PatKind :: Constant { value } } ;
2478- Some ( & * cx. pattern_arena . alloc ( pattern) )
2479- } )
2480- . collect :: < Option < _ > > ( ) ?;
2481- Some ( Fields :: from_vec ( pats) )
2482- } else {
2483- None
2467+ if ctor_wild_subpatterns. len ( ) as u64 != n {
2468+ return None ;
24842469 }
2470+ // Convert a constant slice/array pattern to a list of patterns.
2471+ let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
2472+ let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
2473+ let pats = ( 0 ..n)
2474+ . map ( |i| {
2475+ let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
2476+ let scalar = alloc. read_scalar ( & cx. tcx , ptr, layout. size ) . ok ( ) ?;
2477+ let scalar = scalar. not_undef ( ) . ok ( ) ?;
2478+ let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
2479+ let pattern = Pat { ty, span : pat. span , kind : box PatKind :: Constant { value } } ;
2480+ Some ( & * cx. pattern_arena . alloc ( pattern) )
2481+ } )
2482+ . collect :: < Option < _ > > ( ) ?;
2483+ Some ( Fields :: from_vec ( pats) )
24852484 }
24862485
24872486 PatKind :: Constant { .. } | PatKind :: Range { .. } => {
24882487 // If the constructor is a:
24892488 // - Single value: add a row if the pattern contains the constructor.
24902489 // - Range: add a row if the constructor intersects the pattern.
24912490 if let IntRange ( ctor) = constructor {
2492- match IntRange :: from_pat ( cx. tcx , cx. param_env , pat) {
2493- Some ( pat) => ctor. intersection ( cx. tcx , & pat) . map ( |_| {
2494- // Constructor splitting should ensure that all intersections we encounter
2495- // are actually inclusions.
2496- assert ! ( ctor. is_subrange( & pat) ) ;
2497- Fields :: empty ( )
2498- } ) ,
2499- _ => None ,
2500- }
2491+ let pat = IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ?;
2492+ ctor. intersection ( cx. tcx , & pat) ?;
2493+ // Constructor splitting should ensure that all intersections we encounter
2494+ // are actually inclusions.
2495+ assert ! ( ctor. is_subrange( & pat) ) ;
25012496 } else {
25022497 // Fallback for non-ranges and ranges that involve
25032498 // floating-point numbers, which are not conveniently handled
25042499 // by `IntRange`. For these cases, the constructor may not be a
25052500 // range so intersection actually devolves into being covered
25062501 // by the pattern.
2507- constructor_covered_by_range ( cx. tcx , cx. param_env , constructor, pat)
2508- . map ( |( ) | Fields :: empty ( ) )
2502+ constructor_covered_by_range ( cx. tcx , cx. param_env , constructor, pat) ?;
25092503 }
2504+ Some ( Fields :: empty ( ) )
25102505 }
25112506
25122507 PatKind :: Array { ref prefix, ref slice, ref suffix }
25132508 | PatKind :: Slice { ref prefix, ref slice, ref suffix } => match * constructor {
25142509 Slice ( _) => {
2510+ // Number of subpatterns for this pattern
25152511 let pat_len = prefix. len ( ) + suffix. len ( ) ;
2516- if let Some ( slice_count) = ctor_wild_subpatterns. len ( ) . checked_sub ( pat_len) {
2517- if slice_count == 0 || slice. is_some ( ) {
2518- Some ( Fields :: from_vec (
2519- prefix
2520- . iter ( )
2521- . chain (
2522- ctor_wild_subpatterns
2523- . iter ( )
2524- . skip ( prefix. len ( ) )
2525- . take ( slice_count)
2526- . chain ( suffix. iter ( ) ) ,
2527- )
2528- . collect ( ) ,
2529- ) )
2530- } else {
2531- None
2532- }
2533- } else {
2534- None
2512+ // Number of subpatterns for this constructor
2513+ let arity = ctor_wild_subpatterns. len ( ) ;
2514+
2515+ if slice. is_none ( ) && arity != pat_len {
2516+ return None ;
25352517 }
2518+
2519+ // Number of subpatterns matched by the `..` subslice pattern (is 0 for a slice
2520+ // pattern of fixed length).
2521+ let subslice_count = arity. checked_sub ( pat_len) ?;
2522+ let subslice_pats =
2523+ ctor_wild_subpatterns. iter ( ) . skip ( prefix. len ( ) ) . take ( subslice_count) ;
2524+ Some ( Fields :: from_vec (
2525+ prefix. iter ( ) . chain ( subslice_pats) . chain ( suffix. iter ( ) ) . collect ( ) ,
2526+ ) )
25362527 }
25372528 ConstantValue ( cv) => {
25382529 match slice_pat_covered_by_const (
0 commit comments