(index<- )        ./librustc/middle/borrowck/gather_loans/gather_moves.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012-2013 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   * Computes moves.
  13   */
  14  
  15  use mc = middle::mem_categorization;
  16  use middle::borrowck::*;
  17  use middle::borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
  18  use middle::borrowck::gather_loans::move_error::MoveSpanAndPath;
  19  use middle::borrowck::move_data::*;
  20  use euv = middle::expr_use_visitor;
  21  use middle::ty;
  22  use syntax::ast;
  23  use syntax::codemap::Span;
  24  use util::ppaux::Repr;
  25  
  26  use std::rc::Rc;
  27  
  28  struct GatherMoveInfo {
  29      id: ast::NodeId,
  30      kind: MoveKind,
  31      cmt: mc::cmt,
  32      span_path_opt: Option<MoveSpanAndPath>
  33  }
  34  
  35  pub fn gather_decl(bccx: &BorrowckCtxt,
  36                     move_data: &MoveData,
  37                     decl_idast::NodeId,
  38                     _decl_spanSpan,
  39                     var_idast::NodeId) {
  40      let loan_path = Rc::new(LpVar(var_id));
  41      move_data.add_move(bccx.tcx, loan_path, decl_id, Declared);
  42  }
  43  
  44  pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
  45                               move_data: &MoveData,
  46                               move_error_collector: &MoveErrorCollector,
  47                               move_expr_idast::NodeId,
  48                               cmtmc::cmt) {
  49      let move_info = GatherMoveInfo {
  50          id: move_expr_id,
  51          kind: MoveExpr,
  52          cmt: cmt,
  53          span_path_opt: None,
  54      };
  55      gather_move(bccx, move_data, move_error_collector, move_info);
  56  }
  57  
  58  pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
  59                              move_data: &MoveData,
  60                              move_error_collector: &MoveErrorCollector,
  61                              move_pat: &ast::Pat,
  62                              cmtmc::cmt) {
  63      let pat_span_path_opt = match move_pat.node {
  64          ast::PatIdent(_, ref path, _) => {
  65              Some(MoveSpanAndPath::with_span_and_path(move_pat.span,
  66                                                       (*path).clone()))
  67          },
  68          _ => None,
  69      };
  70      let move_info = GatherMoveInfo {
  71          id: move_pat.id,
  72          kind: MovePat,
  73          cmt: cmt,
  74          span_path_opt: pat_span_path_opt,
  75      };
  76      gather_move(bccx, move_data, move_error_collector, move_info);
  77  }
  78  
  79  fn gather_move(bccx: &BorrowckCtxt,
  80                 move_data: &MoveData,
  81                 move_error_collector: &MoveErrorCollector,
  82                 move_infoGatherMoveInfo) {
  83      debug!("gather_move(move_id={}, cmt={})",
  84             move_info.id, move_info.cmt.repr(bccx.tcx));
  85  
  86      let potentially_illegal_move =
  87                  check_and_get_illegal_move_origin(bccx, &move_info.cmt);
  88      match potentially_illegal_move {
  89          Some(illegal_move_origin) => {
  90              debug!("illegal_move_origin={}", illegal_move_origin.repr(bccx.tcx));
  91              let error = MoveError::with_move_info(illegal_move_origin,
  92                                                    move_info.span_path_opt);
  93              move_error_collector.add_error(error);
  94              return
  95          }
  96          None => ()
  97      }
  98  
  99      match opt_loan_path(&move_info.cmt) {
 100          Some(loan_path) => {
 101              move_data.add_move(bccx.tcx, loan_path,
 102                                 move_info.id, move_info.kind);
 103          }
 104          None => {
 105              // move from rvalue or unsafe pointer, hence ok
 106          }
 107      }
 108  }
 109  
 110  pub fn gather_assignment(bccx: &BorrowckCtxt,
 111                           move_data: &MoveData,
 112                           assignment_idast::NodeId,
 113                           assignment_spanSpan,
 114                           assignee_loan_pathRc<LoanPath>,
 115                           assignee_idast::NodeId,
 116                           modeeuv::MutateMode) {
 117      move_data.add_assignment(bccx.tcx,
 118                               assignee_loan_path,
 119                               assignment_id,
 120                               assignment_span,
 121                               assignee_id,
 122                               mode);
 123  }
 124  
 125  fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt,
 126                                       cmt: &mc::cmt) -> Option<mc::cmt> {
 127      match cmt.cat {
 128          mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
 129          mc::cat_deref(_, _, mc::GcPtr) |
 130          mc::cat_deref(_, _, mc::UnsafePtr(..)) |
 131          mc::cat_upvar(..) | mc::cat_static_item |
 132          mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
 133              Some(cmt.clone())
 134          }
 135  
 136          // Can move out of captured upvars only if the destination closure
 137          // type is 'once'. 1-shot stack closures emit the copied_upvar form
 138          // (see mem_categorization.rs).
 139          mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Once, .. }) => {
 140              None
 141          }
 142  
 143          mc::cat_rvalue(..) |
 144          mc::cat_local(..) |
 145          mc::cat_arg(..) => {
 146              None
 147          }
 148  
 149          mc::cat_downcast(ref b) |
 150          mc::cat_interior(ref b, _) => {
 151              match ty::get(b.ty).sty {
 152                  ty::ty_struct(did, _) | ty::ty_enum(did, _) => {
 153                      if ty::has_dtor(bccx.tcx, did) {
 154                          Some(cmt.clone())
 155                      } else {
 156                          check_and_get_illegal_move_origin(bccx, b)
 157                      }
 158                  }
 159                  _ => {
 160                      check_and_get_illegal_move_origin(bccx, b)
 161                  }
 162              }
 163          }
 164  
 165          mc::cat_deref(ref b, _, mc::OwnedPtr) |
 166          mc::cat_discr(ref b, _) => {
 167              check_and_get_illegal_move_origin(bccx, b)
 168          }
 169      }
 170  }


librustc/middle/borrowck/gather_loans/gather_moves.rs:78:1-78:1 -fn- definition:
fn gather_move(bccx: &BorrowckCtxt,
               move_data: &MoveData,
               move_error_collector: &MoveErrorCollector,
references:- 2
75:     };
76:     gather_move(bccx, move_data, move_error_collector, move_info);
77: }


librustc/middle/borrowck/gather_loans/gather_moves.rs:27:1-27:1 -struct- definition:
struct GatherMoveInfo {
    id: ast::NodeId,
    kind: MoveKind,
references:- 3
48:                              cmt: mc::cmt) {
49:     let move_info = GatherMoveInfo {
50:         id: move_expr_id,
--
81:                move_error_collector: &MoveErrorCollector,
82:                move_info: GatherMoveInfo) {
83:     debug!("gather_move(move_id={}, cmt={})",


librustc/middle/borrowck/gather_loans/gather_moves.rs:124:1-124:1 -fn- definition:
fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt,
                                     cmt: &mc::cmt) -> Option<mc::cmt> {
    match cmt.cat {
references:- 4
86:     let potentially_illegal_move =
87:                 check_and_get_illegal_move_origin(bccx, &move_info.cmt);
88:     match potentially_illegal_move {
--
155:                     } else {
156:                         check_and_get_illegal_move_origin(bccx, b)
157:                     }
--
166:         mc::cat_discr(ref b, _) => {
167:             check_and_get_illegal_move_origin(bccx, b)
168:         }