(index<- )        ./librustc/middle/pat_util.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri Apr 25 22:40:04 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  
  12  use middle::resolve;
  13  
  14  use collections::HashMap;
  15  use syntax::ast::*;
  16  use syntax::ast_util::{path_to_ident, walk_pat};
  17  use syntax::codemap::Span;
  18  
  19  pub type PatIdMap = HashMap<Ident, NodeId>;
  20  
  21  // This is used because same-named variables in alternative patterns need to
  22  // use the NodeId of their namesake in the first pattern.
  23  pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
  24      let mut map = HashMap::new();
  25      pat_bindings(dm, pat, |_bm, p_id, _s, n| {
  26        map.insert(path_to_ident(n), p_id);
  27      });
  28      map
  29  }
  30  
  31  pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool {
  32      match pat.node {
  33          PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => {
  34              match dm.borrow().find(&pat.id) {
  35                  Some(&DefVariant(..)) | Some(&DefStruct(..)) => true,
  36                  _ => false
  37              }
  38          }
  39          _ => false
  40      }
  41  }
  42  
  43  pub fn pat_is_const(dm: &resolve::DefMap, pat: &Pat) -> bool {
  44      match pat.node {
  45          PatIdent(_, _, None) | PatEnum(..) => {
  46              match dm.borrow().find(&pat.id) {
  47                  Some(&DefStatic(_, false)) => true,
  48                  _ => false
  49              }
  50          }
  51          _ => false
  52      }
  53  }
  54  
  55  pub fn pat_is_binding(dm: &resolve::DefMap, pat: &Pat) -> bool {
  56      match pat.node {
  57          PatIdent(..) => {
  58              !pat_is_variant_or_struct(dm, pat) &&
  59              !pat_is_const(dm, pat)
  60          }
  61          _ => false
  62      }
  63  }
  64  
  65  pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &Pat) -> bool {
  66      match pat.node {
  67          PatIdent(..) => pat_is_binding(dm, pat),
  68          PatWild | PatWildMulti => true,
  69          _ => false
  70      }
  71  }
  72  
  73  /// Call `it` on every "binding" in a pattern, e.g., on `a` in
  74  /// `match foo() { Some(a) => (), None => () }`
  75  pub fn pat_bindings(dm: &resolve::DefMap,
  76                      pat: &Pat,
  77                      it: |BindingMode, NodeId, Span, &Path|) {
  78      walk_pat(pat, |p| {
  79          match p.node {
  80            PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
  81              it(binding_mode, p.id, p.span, pth);
  82            }
  83            _ => {}
  84          }
  85          true
  86      });
  87  }
  88  
  89  /// Checks if the pattern contains any patterns that bind something to
  90  /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
  91  pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &Pat) -> bool {
  92      let mut contains_bindings = false;
  93      walk_pat(pat, |p| {
  94          if pat_is_binding(dm, p) {
  95              contains_bindings = true;
  96              false // there's at least one binding, can short circuit now.
  97          } else {
  98              true
  99          }
 100      });
 101      contains_bindings
 102  }
 103  
 104  pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Path> {
 105      match pat.node {
 106          PatIdent(BindByValue(_), ref path, None) => {
 107              Some(path)
 108          }
 109          _ => {
 110              None
 111          }
 112      }
 113  }


librustc/middle/pat_util.rs:103:1-103:1 -fn- definition:
pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Path> {
    match pat.node {
        PatIdent(BindByValue(_), ref path, None) => {
references:- 2
librustc/middle/trans/_match.rs:
1995:             // it assumes it is matching against a valid value.
1996:             match simple_identifier(pat) {
1997:                 Some(path) => {
--
2062:     match simple_identifier(pat) {
2063:         Some(path) => {


librustc/middle/pat_util.rs:18:1-18:1 -NK_AS_STR_TODO- definition:
pub type PatIdMap = HashMap<Ident, NodeId>;
// This is used because same-named variables in alternative patterns need to
// use the NodeId of their namesake in the first pattern.
references:- 2
22: // use the NodeId of their namesake in the first pattern.
23: pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
24:     let mut map = HashMap::new();
librustc/middle/typeck/check/_match.rs:
106:     pub fcx: &'a FnCtxt<'a>,
107:     pub map: PatIdMap,
108: }


librustc/middle/pat_util.rs:42:1-42:1 -fn- definition:
pub fn pat_is_const(dm: &resolve::DefMap, pat: &Pat) -> bool {
    match pat.node {
        PatIdent(_, _, None) | PatEnum(..) => {
references:- 3
58:             !pat_is_variant_or_struct(dm, pat) &&
59:             !pat_is_const(dm, pat)
60:         }
librustc/middle/typeck/check/_match.rs:
469:       ast::PatEnum(..) |
470:       ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
471:         let const_did = ast_util::def_id_of_def(tcx.def_map.borrow()
librustc/middle/trans/_match.rs:
603:             ast::PatEnum(..) |
604:             ast::PatIdent(_, _, None) if pat_is_const(&tcx.def_map, p) => {
605:                 let const_def = tcx.def_map.borrow().get_copy(&p.id);


librustc/middle/pat_util.rs:22:58-22:58 -fn- definition:
// use the NodeId of their namesake in the first pattern.
pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
    let mut map = HashMap::new();
references:- 3
librustc/middle/typeck/check/mod.rs:
3344:         fcx: fcx,
3345:         map: pat_id_map(&tcx.def_map, local.pat),
3346:     };
librustc/middle/typeck/check/_match.rs:
42:             fcx: fcx,
43:             map: pat_id_map(&tcx.def_map, *arm.pats.get(0)),
44:         };
librustc/middle/typeck/check/mod.rs:
501:                 fcx: &fcx,
502:                 map: pat_id_map(&tcx.def_map, input.pat),
503:             };


librustc/middle/pat_util.rs:30:1-30:1 -fn- definition:
pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool {
    match pat.node {
        PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => {
references:- 2
57:         PatIdent(..) => {
58:             !pat_is_variant_or_struct(dm, pat) &&
59:             !pat_is_const(dm, pat)
librustc/middle/trans/_match.rs:
626:             ast::PatIdent(_, _, None)
627:                     if pat_is_variant_or_struct(&tcx.def_map, p) => {
628:                 if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {


librustc/middle/pat_util.rs:54:1-54:1 -fn- definition:
pub fn pat_is_binding(dm: &resolve::DefMap, pat: &Pat) -> bool {
    match pat.node {
        PatIdent(..) => {
references:- 13
66:     match pat.node {
67:         PatIdent(..) => pat_is_binding(dm, pat),
68:         PatWild | PatWildMulti => true,
--
79:         match p.node {
80:           PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
81:             it(binding_mode, p.id, p.span, pth);
--
93:     walk_pat(pat, |p| {
94:         if pat_is_binding(dm, p) {
95:             contains_bindings = true;
librustc/middle/expr_use_visitor.rs:
701:         return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
702:             if pat_util::pat_is_binding(def_map, pat) {
703:                 let tcx = typer.tcx();
librustc/middle/trans/_match.rs:
2164:         ast::PatIdent(pat_binding_mode, ref path, inner) => {
2165:             if pat_is_binding(&tcx.def_map, pat) {
2166:                 // Allocate the stack slot where the value of this
librustc/middle/trans/debuginfo.rs:
2508:                 // introduce an artificial scope
2509:                 if pat_util::pat_is_binding(def_map, pat) {
librustc/middle/typeck/check/mod.rs:
409:               ast::PatIdent(_, ref path, _)
410:                   if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => {
411:                 self.assign(p.id, None);
librustc/middle/typeck/check/writeback.rs:
55:         // Privacy needs the type for the whole pattern, not just each binding
56:         if !pat_util::pat_is_binding(&fcx.tcx().def_map, arg.pat) {
57:             wbcx.visit_node_id(ResolvingPattern(arg.pat.span),
librustc/middle/check_match.rs:
972:         walk_pat(*pat, |p| {
973:             if pat_is_binding(def_map, p) {
974:                 match p.node {
librustc/middle/lint.rs:
1372:         ast::PatIdent(ast::BindByValue(ast::MutMutable),
1373:                       ref path, _) if pat_util::pat_is_binding(&cx.tcx.def_map, p) => {
1374:             // `let mut _a = 1;` doesn't need a warning.
librustc/middle/typeck/check/_match.rs:
476:       }
477:       ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => {
478:         let typ = fcx.local_ty(pat.span, pat.id);


librustc/middle/pat_util.rs:74:48-74:48 -fn- definition:
/// `match foo() { Some(a) => (), None => () }`
pub fn pat_bindings(dm: &resolve::DefMap,
                    pat: &Pat,
references:- 16
24:     let mut map = HashMap::new();
25:     pat_bindings(dm, pat, |_bm, p_id, _s, n| {
26:       map.insert(path_to_ident(n), p_id);
librustc/middle/expr_use_visitor.rs:
461:                 let delegate = &mut self.delegate;
462:                 pat_util::pat_bindings(&self.typer.tcx().def_map, local.pat, |_, id, span, _| {
463:                     delegate.decl_without_init(id, span);
librustc/middle/trans/_match.rs:
1840:     let mut bindings_map = HashMap::new();
1841:     pat_bindings(&tcx.def_map, pat, |bm, p_id, span, path| {
1842:         let ident = path_to_ident(path);
--
2031:         let tcx = bcx.tcx();
2032:         pat_bindings(&tcx.def_map, pat, |_, p_id, _, path| {
2033:                 let scope = cleanup::var_scope(tcx, p_id);
librustc/middle/trans/debuginfo.rs:
2397:     for &arg_pat in arg_pats.iter() {
2398:         pat_util::pat_bindings(def_map, arg_pat, |_, _, _, path_ref| {
2399:             let ident = ast_util::path_to_ident(path_ref);
librustc/middle/resolve.rs:
4029:         let mut result = HashMap::new();
4030:         pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path| {
4031:             let name = mtwt::resolve(path_to_ident(path));
librustc/middle/typeck/check/mod.rs:
492:             // Create type variables for each argument.
493:             pat_util::pat_bindings(&tcx.def_map,
494:                                    input.pat,
librustc/middle/typeck/check/regionck.rs:
363:     debug!("regionck::visit_pat(pat={})", pat.repr(tcx));
364:     pat_util::pat_bindings(&tcx.def_map, pat, |_, id, span, _| {
365:         // If we have a variable that contains region'd data, that
librustc/middle/check_match.rs:
936:     for pat in pats.iter() {
937:         pat_bindings(def_map, *pat, |bm, _, span, _path| {
938:             match bm {
librustc/middle/liveness.rs:
400: fn visit_local(ir: &mut IrMaps, local: &Local) {
401:     pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |bm, p_id, sp, path| {
402:         debug!("adding local variable {}", p_id);
--
1541:         for arg in decl.inputs.iter() {
1542:             pat_util::pat_bindings(&self.ir.tcx.def_map,
1543:                                    arg.pat,
librustc/middle/trans/debuginfo.rs:
516:     pat_util::pat_bindings(def_map, arg.pat, |_, node_id, span, path_ref| {
517:         let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {