fn specialize<'p, 'a: 'p, 'tcx: 'a>(
    cx: &mut MatchCheckCtxt<'a, 'tcx>,
    r: &[&'p Pattern<'tcx>],
    constructor: &Constructor<'tcx>,
    wild_patterns: &[&'p Pattern<'tcx>])
    -> Option<Vec<&'p Pattern<'tcx>>>
{
    let pat = &r[0];

    let head: Option<Vec<&Pattern>> = match *pat.kind {
        PatternKind::Binding { .. } | PatternKind::Wild => {
            Some(wild_patterns.to_owned())
        },

        PatternKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
            let ref variant = adt_def.variants[variant_index];
            if *constructor == Variant(variant.did) {
                Some(patterns_for_variant(subpatterns, wild_patterns))
            } else {
                None
            }
        }

        PatternKind::Leaf { ref subpatterns } => {
            Some(patterns_for_variant(subpatterns, wild_patterns))
        }
        PatternKind::Deref { ref subpattern } => {
            Some(vec![subpattern])
        }

        PatternKind::Constant { value } => {
            match *constructor {
                Slice(..) => {
                    if let Some(ptr) = value.to_ptr() {
                        let is_array_ptr = value.ty
                            .builtin_deref(true)
                            .and_then(|t| t.ty.builtin_index())
                            .map_or(false, |t| t == cx.tcx.types.u8);
                        assert!(is_array_ptr);
                        let data_len = cx.tcx
                            .alloc_map
                            .lock()
                            .unwrap_memory(ptr.alloc_id)
                            .bytes
                            .len();
                        if wild_patterns.len() == data_len {
                            Some(cx.lower_byte_str_pattern(pat))
                        } else {
                            None
                        }
                    } else {
                        span_bug!(pat.span,
                        "unexpected const-val {:?} with ctor {:?}", value, constructor)
                    }
                },
                _ => {
                    match constructor_covered_by_range(
                        cx.tcx,
                        constructor, value, value, RangeEnd::Included,
                        value.ty,
                            ) {
                        Ok(true) => Some(vec![]),
                        Ok(false) => None,
                        Err(ErrorReported) => None,
                    }
                }
            }
        }

        PatternKind::Range { lo, hi, ref end } => {
            match constructor_covered_by_range(
                cx.tcx,
                constructor, lo, hi, end.clone(), lo.ty,
            ) {
                Ok(true) => Some(vec![]),
                Ok(false) => None,
                Err(ErrorReported) => None,
            }
        }

        PatternKind::Array { ref prefix, ref slice, ref suffix } |
        PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
            match *constructor {
                Slice(..) => {
                    let pat_len = prefix.len() + suffix.len();
                    if let Some(slice_count) = wild_patterns.len().checked_sub(pat_len) {
                        if slice_count == 0 || slice.is_some() {
                            Some(
                                prefix.iter().chain(
                                wild_patterns.iter().map(|p| *p)
                                                    .skip(prefix.len())
                                                    .take(slice_count)
                                                    .chain(
                                suffix.iter()
                            )).collect())
                        } else {
                            None
                        }
                    } else {
                        None
                    }
                }
                ConstantValue(..) => {
                    match slice_pat_covered_by_constructor(
                        cx.tcx, pat.span, constructor, prefix, slice, suffix
                            ) {
                        Ok(true) => Some(vec![]),
                        Ok(false) => None,
                        Err(ErrorReported) => None
                    }
                }
                _ => span_bug!(pat.span,
                    "unexpected ctor {:?} for slice pat", constructor)
            }
        }
    };
    debug!("specialize({:#?}, {:#?}) = {:#?}", r[0], wild_patterns, head);

    head.map(|mut head| {
        head.extend_from_slice(&r[1 ..]);
        head
    })
}
/// This is the main specialization step. It expands the first pattern in the given row
/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
///
/// OTOH, slice patterns with a subslice pattern (..tail) can be expanded into multiple
/// different patterns.
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
/// fields filled with wild patterns.
This is the main specialization step. It expands the first pattern in the given row
into `arity` patterns based on the constructor. For most patterns, the step is trivial,
for instance tuple patterns are flattened and box patterns expand into their inner pattern.

OTOH, slice patterns with a subslice pattern (..tail) can be expanded into multiple
different patterns.
Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
fields filled with wild patterns.
This is the main specialization step . It expands the first pattern in the given row into ` arity ` patterns based on the constructor . For most patterns the step is trivial for instance tuple patterns are flattened and box patterns expand into their inner pattern . OTOH slice patterns with a subslice pattern ( .. tail ) can be expanded into multiple different patterns . Structure patterns with a partial wild pattern ( Foo { a : 42 .. } ) have their missing fields filled with wild patterns .
fn specialize<'p, 'a: 'p, 'tcx: 'a>(
    cx: &mut MatchCheckCtxt<'a, 'tcx>,
    r: &[&'p Pattern<'tcx>],
    constructor: &Constructor<'tcx>,
    wild_patterns: &[&'p Pattern<'tcx>])
    -> Option<Vec<&'p Pattern<'tcx>>>
{
    let pat = &r[0];
    let head: Option<Vec<&Pattern>> = match *pat.kind {
        PatternKind::Binding { .. } | PatternKind::Wild => {
            Some(wild_patterns.to_owned())
        },
        PatternKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
            let ref variant = adt_def.variants[variant_index];
            if *constructor == Variant(variant.did) {
                Some(patterns_for_variant(subpatterns, wild_patterns))
            } else {
                None
            }
        }
        PatternKind::Leaf { ref subpatterns } => {
            Some(patterns_for_variant(subpatterns, wild_patterns))
        }
        PatternKind::Deref { ref subpattern } => {
            Some(vec![subpattern])
        }
        PatternKind::Constant { value } => {
            match *constructor {
                Slice(..) => {
                    if let Some(ptr) = value.to_ptr() {
                        let is_array_ptr = value.ty
                            .builtin_deref(true)
                            .and_then(|t| t.ty.builtin_index())
                            .map_or(false, |t| t == cx.tcx.types.u8);
                        assert!(is_array_ptr);
                        let data_len = cx.tcx
                            .alloc_map
                            .lock()
                            .unwrap_memory(ptr.alloc_id)
                            .bytes
                            .len();
                        if wild_patterns.len() == data_len {
                            Some(cx.lower_byte_str_pattern(pat))
                        } else {
                            None
                        }
                    } else {
                        span_bug!(pat.span,
                        "unexpected const-val {:?} with ctor {:?}", value, constructor)
                    }
                },
                _ => {
                    match constructor_covered_by_range(
                        cx.tcx,
                        constructor, value, value, RangeEnd::Included,
                        value.ty,
                            ) {
                        Ok(true) => Some(vec![]),
                        Ok(false) => None,
                        Err(ErrorReported) => None,
                    }
                }
            }
        }
        PatternKind::Range { lo, hi, ref end } => {
            match constructor_covered_by_range(
                cx.tcx,
                constructor, lo, hi, end.clone(), lo.ty,
            ) {
                Ok(true) => Some(vec![]),
                Ok(false) => None,
                Err(ErrorReported) => None,
            }
        }
        PatternKind::Array { ref prefix, ref slice, ref suffix } |
        PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
            match *constructor {
                Slice(..) => {
                    let pat_len = prefix.len() + suffix.len();
                    if let Some(slice_count) = wild_patterns.len().checked_sub(pat_len) {
                        if slice_count == 0 || slice.is_some() {
                            Some(
                                prefix.iter().chain(
                                wild_patterns.iter().map(|p| *p)
                                                    .skip(prefix.len())
                                                    .take(slice_count)
                                                    .chain(
                                suffix.iter()
                            )).collect())
                        } else {
                            None
                        }
                    } else {
                        None
                    }
                }
                ConstantValue(..) => {
                    match slice_pat_covered_by_constructor(
                        cx.tcx, pat.span, constructor, prefix, slice, suffix
                            ) {
                        Ok(true) => Some(vec![]),
                        Ok(false) => None,
                        Err(ErrorReported) => None
                    }
                }
                _ => span_bug!(pat.span,
                    "unexpected ctor {:?} for slice pat", constructor)
            }
        }
    };
    debug!("specialize({:#?}, {:#?}) = {:#?}", r[0], wild_patterns, head);
    head.map(|mut head| {
        head.extend_from_slice(&r[1 ..]);
        head
    })
}
fn specialize < ' p , ' a : ' p , ' tcx : ' a > ( cx : & mut MatchCheckCtxt < ' a , ' tcx > , r : & [ & ' p Pattern < ' tcx > ] , constructor : & Constructor < ' tcx > , wild_patterns : & [ & ' p Pattern < ' tcx > ] ) -> Option < Vec < & ' p Pattern < ' tcx > > > { let pat = & r [ 0 ] ; let head : Option < Vec < & Pattern > > = match * pat . kind { PatternKind :: Binding { .. } | PatternKind :: Wild => { Some ( wild_patterns . to_owned ( ) ) } , PatternKind :: Variant { adt_def , variant_index , ref subpatterns , .. } => { let ref variant = adt_def . variants [ variant_index ] ; if * constructor == Variant ( variant . did ) { Some ( patterns_for_variant ( subpatterns , wild_patterns ) ) } else { None } } PatternKind :: Leaf { ref subpatterns } => { Some ( patterns_for_variant ( subpatterns , wild_patterns ) ) } PatternKind :: Deref { ref subpattern } => { Some ( vec ! [ subpattern ] ) } PatternKind :: Constant { value } => { match * constructor { Slice ( .. ) => { if let Some ( ptr ) = value . to_ptr ( ) { let is_array_ptr = value . ty . builtin_deref ( true ) . and_then ( | t | t . ty . builtin_index ( ) ) . map_or ( false , | t | t == cx . tcx . types . u8 ) ; assert ! ( is_array_ptr ) ; let data_len = cx . tcx . alloc_map . lock ( ) . unwrap_memory ( ptr . alloc_id ) . bytes . len ( ) ; if wild_patterns . len ( ) == data_len { Some ( cx . lower_byte_str_pattern ( pat ) ) } else { None } } else { span_bug ! ( pat span " " value constructor ) } } , _ => { match constructor_covered_by_range ( cx . tcx , constructor , value , value , RangeEnd :: Included , value . ty , ) { Ok ( true ) => Some ( vec ! [ ] ) , Ok ( false ) => None , Err ( ErrorReported ) => None , } } } } PatternKind :: Range { lo , hi , ref end } => { match constructor_covered_by_range ( cx . tcx , constructor , lo , hi , end . clone ( ) , lo . ty , ) { Ok ( true ) => Some ( vec ! [ ] ) , Ok ( false ) => None , Err ( ErrorReported ) => None , } } PatternKind :: Array { ref prefix , ref slice , ref suffix } | PatternKind :: Slice { ref prefix , ref slice , ref suffix } => { match * constructor { Slice ( .. ) => { let pat_len = prefix . len ( ) + suffix . len ( ) ; if let Some ( slice_count ) = wild_patterns . len ( ) . checked_sub ( pat_len ) { if slice_count == 0 || slice . is_some ( ) { Some ( prefix . iter ( ) . chain ( wild_patterns . iter ( ) . map ( | p | * p ) . skip ( prefix . len ( ) ) . take ( slice_count ) . chain ( suffix . iter ( ) ) ) . collect ( ) ) } else { None } } else { None } } ConstantValue ( .. ) => { match slice_pat_covered_by_constructor ( cx . tcx , pat . span , constructor , prefix , slice , suffix ) { Ok ( true ) => Some ( vec ! [ ] ) , Ok ( false ) => None , Err ( ErrorReported ) => None } } _ => span_bug ! ( pat span " " constructor ) } } } ; debug ! ( " " r [ 0 ] wild_patterns head ) ; head . map ( | mut head | { head . extend_from_slice ( & r [ 1 .. ] ) ; head } ) }
This is the main specialization step.
This is the main specialization step .
cx
&mut MatchCheckCtxt<'a, 'tcx>
r
&[&'p Pattern<'tcx>]
constructor
&Constructor<'tcx>
wild_patterns
&[&'p Pattern<'tcx>]