fn const_to_pat(
        &self,
        instance: ty::Instance<'tcx>,
        cv: &'tcx ty::Const<'tcx>,
        id: hir::HirId,
        span: Span,
    ) -> Pattern<'tcx> {
        debug!("const_to_pat: cv={:#?}", cv);
        let adt_subpattern = |i, variant_opt| {
            let field = Field::new(i);
            let val = const_val_field(
                self.tcx, self.param_env, instance,
                variant_opt, field, cv,
            ).expect("field access failed");
            self.const_to_pat(instance, val, id, span)
        };
        let adt_subpatterns = |n, variant_opt| {
            (0..n).map(|i| {
                let field = Field::new(i);
                FieldPattern {
                    field,
                    pattern: adt_subpattern(i, variant_opt),
                }
            }).collect::<Vec<_>>()
        };
        let kind = match cv.ty.sty {
            ty::TyFloat(_) => {
                let id = self.tcx.hir.hir_to_node_id(id);
                self.tcx.lint_node(
                    ::rustc::lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                    id,
                    span,
                    "floating-point types cannot be used in patterns",
                );
                PatternKind::Constant {
                    value: cv,
                }
            },
            ty::TyAdt(adt_def, _) if adt_def.is_union() => {
                // Matching on union fields is unsafe, we can't hide it in constants
                self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
                PatternKind::Wild
            }
            ty::TyAdt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
                let msg = format!("to use a constant of type `{}` in a pattern, \
                                    `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
                                    self.tcx.item_path_str(adt_def.did),
                                    self.tcx.item_path_str(adt_def.did));
                self.tcx.sess.span_err(span, &msg);
                PatternKind::Wild
            },
            ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
                let variant_index = const_variant_index(
                    self.tcx, self.param_env, instance, cv
                ).expect("const_variant_index failed");
                let subpatterns = adt_subpatterns(
                    adt_def.variants[variant_index].fields.len(),
                    Some(variant_index),
                );
                PatternKind::Variant {
                    adt_def,
                    substs,
                    variant_index,
                    subpatterns,
                }
            },
            ty::TyAdt(adt_def, _) => {
                let struct_var = adt_def.non_enum_variant();
                PatternKind::Leaf {
                    subpatterns: adt_subpatterns(struct_var.fields.len(), None),
                }
            }
            ty::TyTuple(fields) => {
                PatternKind::Leaf {
                    subpatterns: adt_subpatterns(fields.len(), None),
                }
            }
            ty::TyArray(_, n) => {
                PatternKind::Array {
                    prefix: (0..n.unwrap_usize(self.tcx))
                        .map(|i| adt_subpattern(i as usize, None))
                        .collect(),
                    slice: None,
                    suffix: Vec::new(),
                }
            }
            _ => {
                PatternKind::Constant {
                    value: cv,
                }
            },
        };

        Pattern {
            span,
            ty: cv.ty,
            kind: Box::new(kind),
        }
    }
/// Converts an evaluated constant to a pattern (if possible).
/// This means aggregate values (like structs and enums) are converted
/// to a pattern that matches the value (as if you'd compare via eq).
Converts an evaluated constant to a pattern (if possible).
This means aggregate values (like structs and enums) are converted
to a pattern that matches the value (as if you'd compare via eq).
Converts an evaluated constant to a pattern ( if possible ) . This means aggregate values ( like structs and enums ) are converted to a pattern that matches the value ( as if you ' d compare via eq ) .
fn const_to_pat(
        &self,
        instance: ty::Instance<'tcx>,
        cv: &'tcx ty::Const<'tcx>,
        id: hir::HirId,
        span: Span,
    ) -> Pattern<'tcx> {
        debug!("const_to_pat: cv={:#?}", cv);
        let adt_subpattern = |i, variant_opt| {
            let field = Field::new(i);
            let val = const_val_field(
                self.tcx, self.param_env, instance,
                variant_opt, field, cv,
            ).expect("field access failed");
            self.const_to_pat(instance, val, id, span)
        };
        let adt_subpatterns = |n, variant_opt| {
            (0..n).map(|i| {
                let field = Field::new(i);
                FieldPattern {
                    field,
                    pattern: adt_subpattern(i, variant_opt),
                }
            }).collect::<Vec<_>>()
        };
        let kind = match cv.ty.sty {
            ty::TyFloat(_) => {
                let id = self.tcx.hir.hir_to_node_id(id);
                self.tcx.lint_node(
                    ::rustc::lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                    id,
                    span,
                    "floating-point types cannot be used in patterns",
                );
                PatternKind::Constant {
                    value: cv,
                }
            },
            ty::TyAdt(adt_def, _) if adt_def.is_union() => {
                // Matching on union fields is unsafe, we can't hide it in constants
                self.tcx.sess.span_err(span, "cannot use unions in constant patterns");
                PatternKind::Wild
            }
            ty::TyAdt(adt_def, _) if !self.tcx.has_attr(adt_def.did, "structural_match") => {
                let msg = format!("to use a constant of type `{}` in a pattern, \
                                    `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
                                    self.tcx.item_path_str(adt_def.did),
                                    self.tcx.item_path_str(adt_def.did));
                self.tcx.sess.span_err(span, &msg);
                PatternKind::Wild
            },
            ty::TyAdt(adt_def, substs) if adt_def.is_enum() => {
                let variant_index = const_variant_index(
                    self.tcx, self.param_env, instance, cv
                ).expect("const_variant_index failed");
                let subpatterns = adt_subpatterns(
                    adt_def.variants[variant_index].fields.len(),
                    Some(variant_index),
                );
                PatternKind::Variant {
                    adt_def,
                    substs,
                    variant_index,
                    subpatterns,
                }
            },
            ty::TyAdt(adt_def, _) => {
                let struct_var = adt_def.non_enum_variant();
                PatternKind::Leaf {
                    subpatterns: adt_subpatterns(struct_var.fields.len(), None),
                }
            }
            ty::TyTuple(fields) => {
                PatternKind::Leaf {
                    subpatterns: adt_subpatterns(fields.len(), None),
                }
            }
            ty::TyArray(_, n) => {
                PatternKind::Array {
                    prefix: (0..n.unwrap_usize(self.tcx))
                        .map(|i| adt_subpattern(i as usize, None))
                        .collect(),
                    slice: None,
                    suffix: Vec::new(),
                }
            }
            _ => {
                PatternKind::Constant {
                    value: cv,
                }
            },
        };
        Pattern {
            span,
            ty: cv.ty,
            kind: Box::new(kind),
        }
    }
fn const_to_pat ( & self , instance : ty :: Instance < ' tcx > , cv : & ' tcx ty :: Const < ' tcx > , id : hir :: HirId , span : Span , ) -> Pattern < ' tcx > { debug ! ( " " cv ) ; let adt_subpattern = | i , variant_opt | { let field = Field :: new ( i ) ; let val = const_val_field ( self . tcx , self . param_env , instance , variant_opt , field , cv , ) . expect ( " " ) ; self . const_to_pat ( instance , val , id , span ) } ; let adt_subpatterns = | n , variant_opt | { ( 0 .. n ) . map ( | i | { let field = Field :: new ( i ) ; FieldPattern { field , pattern : adt_subpattern ( i , variant_opt ) , } } ) . collect :: < Vec < _ > > ( ) } ; let kind = match cv . ty . sty { ty :: TyFloat ( _ ) => { let id = self . tcx . hir . hir_to_node_id ( id ) ; self . tcx . lint_node ( :: rustc :: lint :: builtin :: ILLEGAL_FLOATING_POINT_LITERAL_PATTERN , id , span , " " , ) ; PatternKind :: Constant { value : cv , } } , ty :: TyAdt ( adt_def , _ ) if adt_def . is_union ( ) => { // Matching on union fields is unsafe, we can't hide it in constants self . tcx . sess . span_err ( span , " " ) ; PatternKind :: Wild } ty :: TyAdt ( adt_def , _ ) if ! self . tcx . has_attr ( adt_def . did , " " ) => { let msg = format ! ( " \
 " self tcx item_path_str ( adt_def did ) self tcx item_path_str ( adt_def did ) ) ; self . tcx . sess . span_err ( span , & msg ) ; PatternKind :: Wild } , ty :: TyAdt ( adt_def , substs ) if adt_def . is_enum ( ) => { let variant_index = const_variant_index ( self . tcx , self . param_env , instance , cv ) . expect ( " " ) ; let subpatterns = adt_subpatterns ( adt_def . variants [ variant_index ] . fields . len ( ) , Some ( variant_index ) , ) ; PatternKind :: Variant { adt_def , substs , variant_index , subpatterns , } } , ty :: TyAdt ( adt_def , _ ) => { let struct_var = adt_def . non_enum_variant ( ) ; PatternKind :: Leaf { subpatterns : adt_subpatterns ( struct_var . fields . len ( ) , None ) , } } ty :: TyTuple ( fields ) => { PatternKind :: Leaf { subpatterns : adt_subpatterns ( fields . len ( ) , None ) , } } ty :: TyArray ( _ , n ) => { PatternKind :: Array { prefix : ( 0 .. n . unwrap_usize ( self . tcx ) ) . map ( | i | adt_subpattern ( i as usize , None ) ) . collect ( ) , slice : None , suffix : Vec :: new ( ) , } } _ => { PatternKind :: Constant { value : cv , } } , } ; Pattern { span , ty : cv . ty , kind : Box :: new ( kind ) , } }
Converts an evaluated constant to a pattern (if possible).
Converts an evaluated constant to a pattern ( if possible ) .
&self
instance
ty::Instance<'tcx>
cv
&'tcx ty::Const<'tcx>
id
hir::HirId
span
Span