@@ -397,7 +397,11 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
397397 ' a : ' q ,
398398 ' p : ' q ,
399399 {
400- specialize ( cx, self , constructor, ctor_wild_subpatterns)
400+ let new_heads = specialize_one_pattern ( cx, self . head ( ) , constructor, ctor_wild_subpatterns) ;
401+ new_heads. map ( |mut new_head| {
402+ new_head. 0 . extend_from_slice ( & self . 0 [ 1 ..] ) ;
403+ new_head
404+ } )
401405 }
402406}
403407
@@ -2018,26 +2022,24 @@ fn patterns_for_variant<'p, 'a: 'p, 'tcx>(
20182022 PatStack :: from_vec ( result)
20192023}
20202024
2021- /// This is the main specialization step. It expands the first pattern in the given row
2025+ /// This is the main specialization step. It expands the pattern
20222026/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
20232027/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
2028+ /// Returns `None` if the pattern does not have the given constructor.
20242029///
20252030/// OTOH, slice patterns with a subslice pattern (tail @ ..) can be expanded into multiple
20262031/// different patterns.
20272032/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
20282033/// fields filled with wild patterns.
2029- fn specialize < ' p , ' a : ' p , ' q : ' p , ' tcx > (
2034+ fn specialize_one_pattern < ' p , ' a : ' p , ' q : ' p , ' tcx > (
20302035 cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
2031- r : & PatStack < ' q , ' tcx > ,
2036+ pat : & ' q Pat < ' tcx > ,
20322037 constructor : & Constructor < ' tcx > ,
20332038 ctor_wild_subpatterns : & [ & ' p Pat < ' tcx > ] ,
20342039) -> Option < PatStack < ' p , ' tcx > > {
2035- let pat = r. head ( ) ;
2036-
2037- let new_head = match * pat. kind {
2038- PatKind :: AscribeUserType { ref subpattern, .. } => {
2039- specialize ( cx, & PatStack :: from_pattern ( subpattern) , constructor, ctor_wild_subpatterns)
2040- }
2040+ let result = match * pat. kind {
2041+ PatKind :: AscribeUserType { ref subpattern, .. } => PatStack :: from_pattern ( subpattern)
2042+ . specialize_constructor ( cx, constructor, ctor_wild_subpatterns) ,
20412043
20422044 PatKind :: Binding { .. } | PatKind :: Wild => {
20432045 Some ( PatStack :: from_slice ( ctor_wild_subpatterns) )
@@ -2192,11 +2194,7 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>(
21922194 bug ! ( "support for or-patterns has not been fully implemented yet." ) ;
21932195 }
21942196 } ;
2195- debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , r . head ( ) , ctor_wild_subpatterns, new_head ) ;
2197+ debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , pat , ctor_wild_subpatterns, result ) ;
21962198
2197- new_head. map ( |head| {
2198- let mut head = head. 0 ;
2199- head. extend_from_slice ( & r. 0 [ 1 ..] ) ;
2200- PatStack :: from_vec ( head)
2201- } )
2199+ result
22022200}
0 commit comments