about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-12-07 19:34:57 -0800
committerPatrick Walton <pcwalton@mimiga.net>2012-12-07 19:34:57 -0800
commit98fdcb0b9d8b66a5feef1e45c06aeec93919d254 (patch)
treed1d01fe8cf77c4be5a2331b606a2de7774e380a4
parent184f5102b37c9a52342382fe9e88144a62cd9782 (diff)
downloadrust-98fdcb0b9d8b66a5feef1e45c06aeec93919d254.tar.gz
rust-98fdcb0b9d8b66a5feef1e45c06aeec93919d254.zip
librustc: De-mode pattern bindings. r=nmatsakis
-rw-r--r--src/librustc/driver/driver.rs6
-rw-r--r--src/librustc/middle/borrowck/gather_loans.rs17
-rw-r--r--src/librustc/middle/check_alt.rs16
-rw-r--r--src/librustc/middle/lint.rs23
-rw-r--r--src/librustc/middle/liveness.rs7
-rw-r--r--src/librustc/middle/mem_categorization.rs18
-rw-r--r--src/librustc/middle/mode.rs42
-rw-r--r--src/librustc/middle/pat_util.rs21
-rw-r--r--src/librustc/middle/resolve.rs1
-rw-r--r--src/librustc/middle/trans/alt.rs16
-rw-r--r--src/librustc/middle/typeck/check/alt.rs8
-rw-r--r--src/libstd/json.rs10
-rw-r--r--src/libsyntax/ast.rs8
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs2
-rw-r--r--src/libsyntax/parse/parser.rs10
-rw-r--r--src/libsyntax/print/pprust.rs2
16 files changed, 99 insertions, 108 deletions
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index f1f5cc1a84d..91c0d036577 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -248,12 +248,12 @@ fn compile_upto(sess: Session, cfg: ast::crate_cfg,
         time(time_passes, ~"loop checking", ||
              middle::check_loop::check_crate(ty_cx, crate));
 
-        time(time_passes, ~"alt checking", ||
-             middle::check_alt::check_crate(ty_cx, method_map, crate));
-
         time(time_passes, ~"mode computation", ||
              middle::mode::compute_modes(ty_cx, method_map, crate));
 
+        time(time_passes, ~"alt checking", ||
+             middle::check_alt::check_crate(ty_cx, method_map, crate));
+
         let last_use_map =
             time(time_passes, ~"liveness checking", ||
                  middle::liveness::check_crate(ty_cx, method_map, crate));
diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs
index a6dd65e4dc7..eafbe8b16ab 100644
--- a/src/librustc/middle/borrowck/gather_loans.rs
+++ b/src/librustc/middle/borrowck/gather_loans.rs
@@ -529,20 +529,9 @@ impl gather_loan_ctxt {
                         self.guarantee_valid(cmt, mutbl, scope_r);
                     }
                   }
-                  ast::bind_by_implicit_ref => {
-                    // Note: there is a discussion of the function of
-                    // cat_discr in the method preserve():
-                    let cmt1 = self.bccx.cat_discr(cmt, alt_id);
-                    let arm_scope = ty::re_scope(arm_id);
-
-                    // We used to remember the mutability of the location
-                    // that this binding refers to and use it later when
-                    // categorizing the binding.  This hack is being
-                    // removed in favor of ref mode bindings.
-                    //
-                    // self.bccx.binding_map.insert(pat.id, cmt1.mutbl);
-
-                    self.guarantee_valid(cmt1, m_const, arm_scope);
+                  ast::bind_infer => {
+                    // Nothing to do here; this is either a copy or a move;
+                    // thus either way there is nothing to check. Yay!
                   }
                 }
               }
diff --git a/src/librustc/middle/check_alt.rs b/src/librustc/middle/check_alt.rs
index f5a57c520d5..737b0892763 100644
--- a/src/librustc/middle/check_alt.rs
+++ b/src/librustc/middle/check_alt.rs
@@ -592,15 +592,25 @@ fn check_legality_of_move_bindings(cx: @AltCheckCtxt,
     let mut by_ref_span = None;
     let mut any_by_move = false;
     for pats.each |pat| {
-        do pat_bindings(def_map, *pat) |bm, _id, span, _path| {
+        do pat_bindings(def_map, *pat) |bm, id, span, _path| {
             match bm {
-                bind_by_ref(_) | bind_by_implicit_ref => {
+                bind_by_ref(_) => {
                     by_ref_span = Some(span);
                 }
                 bind_by_move => {
                     any_by_move = true;
                 }
-                _ => { }
+                bind_by_value => {}
+                bind_infer => {
+                    match cx.tcx.value_modes.find(id) {
+                        Some(MoveValue) => any_by_move = true,
+                        Some(CopyValue) | Some(ReadValue) => {}
+                        None => {
+                            cx.tcx.sess.span_bug(span, ~"no mode for pat \
+                                                         binding");
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 4341409996f..1b007c8c4b7 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -767,27 +767,6 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) {
     }
 }
 
-fn check_pat(tcx: ty::ctxt, pat: @ast::pat) {
-    debug!("lint check_pat pat=%s", pat_to_str(pat, tcx.sess.intr()));
-
-    do pat_bindings(tcx.def_map, pat) |binding_mode, id, span, path| {
-        match binding_mode {
-          ast::bind_by_ref(_) | ast::bind_by_value | ast::bind_by_move => {}
-          ast::bind_by_implicit_ref => {
-            let pat_ty = ty::node_id_to_type(tcx, id);
-            let kind = ty::type_kind(tcx, pat_ty);
-            if !ty::kind_is_safe_for_default_mode(kind) {
-                tcx.sess.span_lint(
-                    deprecated_pattern, id, id,
-                    span,
-                    fmt!("binding `%s` should use ref or copy mode",
-                         tcx.sess.str_of(path_to_ident(path))));
-            }
-          }
-        }
-    }
-}
-
 fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl,
             _body: ast::blk, span: span, id: ast::node_id) {
     debug!("lint check_fn fk=%? id=%?", fk, id);
@@ -904,8 +883,6 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {
             check_item(it, tcx),
         visit_fn: |fk, decl, body, span, id|
             check_fn(tcx, fk, decl, body, span, id),
-        visit_pat: |pat|
-            check_pat(tcx, pat),
         .. *visit::default_simple_visitor()
     });
     visit::visit_crate(*crate, (), v);
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 636a24f7ed7..e8fcbf12356 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -390,9 +390,7 @@ impl IrMaps {
           Arg(id, _, by_copy) |
           Local(LocalInfo {id: id, kind: FromLetNoInitializer, _}) |
           Local(LocalInfo {id: id, kind: FromLetWithInitializer, _}) |
-          Local(LocalInfo {id: id, kind: FromMatch(bind_by_value), _}) |
-          Local(LocalInfo {id: id, kind: FromMatch(bind_by_ref(_)), _}) |
-          Local(LocalInfo {id: id, kind: FromMatch(bind_by_move), _}) => {
+          Local(LocalInfo {id: id, kind: FromMatch(_), _}) => {
             let v = match self.last_use_map.find(expr_id) {
               Some(v) => v,
               None => {
@@ -405,8 +403,7 @@ impl IrMaps {
             (*v).push(id);
           }
           Arg(_, _, by_ref) |
-          Arg(_, _, by_val) | Self | ImplicitRet |
-          Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
+          Arg(_, _, by_val) | Self | ImplicitRet => {
             debug!("--but it is not owned");
           }
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index f202a81f049..9f06cf6c7ce 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -636,28 +636,12 @@ impl &mem_categorization_ctxt {
               mutbl:m, ty:expr_ty}
           }
 
-          ast::def_binding(vid, ast::bind_by_value) |
-          ast::def_binding(vid, ast::bind_by_move)  |
-          ast::def_binding(vid, ast::bind_by_ref(_)) => {
+          ast::def_binding(vid, _) => {
             // by-value/by-ref bindings are local variables
             @{id:id, span:span,
               cat:cat_local(vid), lp:Some(@lp_local(vid)),
               mutbl:m_imm, ty:expr_ty}
           }
-
-          ast::def_binding(pid, ast::bind_by_implicit_ref) => {
-            // implicit-by-ref bindings are "special" since they are
-            // implicit pointers.
-
-            // Technically, the mutability is not always imm, but we
-            // (choose to be) unsound for the moment since these
-            // implicit refs are going away and it reduces external
-            // dependencies.
-
-            @{id:id, span:span,
-              cat:cat_binding(pid), lp:None,
-              mutbl:m_imm, ty:expr_ty}
-          }
         }
     }
 
diff --git a/src/librustc/middle/mode.rs b/src/librustc/middle/mode.rs
index e1bea7714b3..91ec4b8ffba 100644
--- a/src/librustc/middle/mode.rs
+++ b/src/librustc/middle/mode.rs
@@ -1,14 +1,16 @@
+use middle::pat_util;
 use middle::ty;
 use middle::ty::{CopyValue, MoveValue, ReadValue, ValueMode, ctxt};
 use middle::typeck::{method_map, method_map_entry};
 
 use core::vec;
 use std::map::HashMap;
-use syntax::ast::{box, by_copy, by_move, by_ref, by_val, crate, deref, expr};
-use syntax::ast::{expr_addr_of, expr_assign, expr_assign_op, expr_binary};
-use syntax::ast::{expr_call, expr_copy, expr_field, expr_index, expr_match};
-use syntax::ast::{expr_method_call, expr_paren, expr_path, expr_swap};
-use syntax::ast::{expr_unary, neg, node_id, not, sty_uniq, sty_value, uniq};
+use syntax::ast::{bind_infer, box, by_copy, by_move, by_ref, by_val, crate};
+use syntax::ast::{deref, expr, expr_addr_of, expr_assign, expr_assign_op};
+use syntax::ast::{expr_binary, expr_call, expr_copy, expr_field, expr_index};
+use syntax::ast::{expr_match, expr_method_call, expr_paren, expr_path};
+use syntax::ast::{expr_swap, expr_unary, neg, node_id, not, pat, pat_ident};
+use syntax::ast::{sty_uniq, sty_value, uniq};
 use syntax::visit;
 use syntax::visit::vt;
 
@@ -166,8 +168,14 @@ fn compute_modes_for_expr(expr: @expr,
             record_mode_for_expr(expr, cx);
         }
         expr_match(head, ref arms) => {
+            // We must do this first so that `arms_have_by_move_bindings`
+            // below knows which bindings are moves.
+            for arms.each |arm| {
+                (v.visit_arm)(*arm, cx, v);
+            }
+
             let by_move_bindings_present =
-                pat_util::arms_have_by_move_bindings(cx.tcx.def_map, *arms);
+                pat_util::arms_have_by_move_bindings(cx.tcx, *arms);
             if by_move_bindings_present {
                 // Propagate the current mode flag downward.
                 visit::visit_expr(expr, cx, v);
@@ -175,9 +183,6 @@ fn compute_modes_for_expr(expr: @expr,
                 // We aren't moving into any pattern, so this is just a read.
                 let head_cx = VisitContext { mode: ReadValue, ..cx };
                 compute_modes_for_expr(head, head_cx, v);
-                for arms.each |arm| {
-                    (v.visit_arm)(*arm, cx, v);
-                }
             }
         }
         _ => {
@@ -188,9 +193,28 @@ fn compute_modes_for_expr(expr: @expr,
     }
 }
 
+fn compute_modes_for_pat(pat: @pat,
+                         &&cx: VisitContext,
+                         v: vt<VisitContext>) {
+    match pat.node {
+        pat_ident(bind_infer, _, _)
+                if pat_util::pat_is_binding(cx.tcx.def_map, pat) => {
+            if ty::type_implicitly_moves(cx.tcx, ty::pat_ty(cx.tcx, pat)) {
+                cx.tcx.value_modes.insert(pat.id, MoveValue);
+            } else {
+                cx.tcx.value_modes.insert(pat.id, CopyValue);
+            }
+        }
+        _ => {}
+    }
+
+    visit::visit_pat(pat, cx, v);
+}
+
 pub fn compute_modes(tcx: ctxt, method_map: method_map, crate: @crate) {
     let visitor = visit::mk_vt(@{
         visit_expr: compute_modes_for_expr,
+        visit_pat: compute_modes_for_pat,
         .. *visit::default_visitor()
     });
     let callee_cx = VisitContext {
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 467897db9d9..68210f19438 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use middle::ty::{CopyValue, MoveValue, ReadValue};
+
 use syntax::ast::*;
 use syntax::ast_util;
 use syntax::ast_util::{path_to_ident, respan, walk_pat};
@@ -93,16 +95,25 @@ fn pat_binding_ids(dm: resolve::DefMap, pat: @pat) -> ~[node_id] {
     return found;
 }
 
-fn arms_have_by_move_bindings(dm: resolve::DefMap, +arms: &[arm]) -> bool {
+fn arms_have_by_move_bindings(tcx: ty::ctxt, +arms: &[arm]) -> bool {
     for arms.each |arm| {
         for arm.pats.each |pat| {
             let mut found = false;
-            do pat_bindings(dm, *pat) |binding_mode, _node_id, _span, _path| {
+            do pat_bindings(tcx.def_map, *pat)
+                    |binding_mode, node_id, span, _path| {
                 match binding_mode {
                     bind_by_move => found = true,
-                    bind_by_implicit_ref |
-                    bind_by_ref(*) |
-                    bind_by_value => {}
+                    bind_infer => {
+                        match tcx.value_modes.find(node_id) {
+                            Some(MoveValue) => found = true,
+                            Some(CopyValue) | Some(ReadValue) => {}
+                            None => {
+                                tcx.sess.span_bug(span, ~"pat binding not in \
+                                                          value mode map");
+                            }
+                        }
+                    }
+                    bind_by_ref(*) | bind_by_value => {}
                 }
             }
             if found { return true; }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5a12bea526e..1e72e9dfff9 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -17,7 +17,6 @@ use middle::lang_items::LanguageItems;
 use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
 use middle::pat_util::{pat_bindings};
 use syntax::ast::{_mod, add, arm};
-use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
 use syntax::ast::{bitand, bitor, bitxor};
 use syntax::ast::{binding_mode, blk, capture_clause, class_ctor, class_dtor};
 use syntax::ast::{crate, crate_num, decl_item};
diff --git a/src/librustc/middle/trans/alt.rs b/src/librustc/middle/trans/alt.rs
index 90ac9a9ce3c..fbb51df39f7 100644
--- a/src/librustc/middle/trans/alt.rs
+++ b/src/librustc/middle/trans/alt.rs
@@ -154,6 +154,7 @@ use syntax::ast::def_id;
 use syntax::codemap::span;
 use syntax::print::pprust::pat_to_str;
 use middle::resolve::DefMap;
+use middle::ty::{CopyValue, MoveValue, ReadValue};
 use back::abi;
 use std::map::HashMap;
 use dvec::DVec;
@@ -1394,7 +1395,7 @@ fn trans_alt_inner(scope_cx: block,
         // Note that we use the names because each binding will have many ids
         // from the various alternatives.
         let bindings_map = std::map::HashMap();
-        do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, _s, path| {
+        do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, s, path| {
             let ident = path_to_ident(path);
             let variable_ty = node_id_type(bcx, p_id);
             let llvariable_ty = type_of::type_of(bcx.ccx(), variable_ty);
@@ -1408,9 +1409,18 @@ fn trans_alt_inner(scope_cx: block,
                     llmatch = alloca(bcx, T_ptr(llvariable_ty));
                     trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
                 }
-                ast::bind_by_implicit_ref => {
+                ast::bind_infer => {
+                    // in this case also, the type of the variable will be T,
+                    // but we need to store a *T
+                    let is_move = match tcx.value_modes.find(p_id) {
+                        None => {
+                            tcx.sess.span_bug(s, ~"no value mode");
+                        }
+                        Some(MoveValue) => true,
+                        Some(CopyValue) | Some(ReadValue) => false
+                    };
                     llmatch = alloca(bcx, T_ptr(llvariable_ty));
-                    trmode = TrByImplicitRef;
+                    trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
                 }
                 ast::bind_by_ref(_) => {
                     llmatch = alloca(bcx, llvariable_ty);
diff --git a/src/librustc/middle/typeck/check/alt.rs b/src/librustc/middle/typeck/check/alt.rs
index 46d618aeb50..48c6aa3bf73 100644
--- a/src/librustc/middle/typeck/check/alt.rs
+++ b/src/librustc/middle/typeck/check/alt.rs
@@ -358,13 +358,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
             demand::eqtype(fcx, pat.span, region_ty, typ);
           }
           // otherwise the type of x is the expected type T
-          ast::bind_by_value => {
-            demand::eqtype(fcx, pat.span, expected, typ);
-          }
-          ast::bind_by_move => {
-            demand::eqtype(fcx, pat.span, expected, typ);
-          }
-          ast::bind_by_implicit_ref => {
+          ast::bind_by_value | ast::bind_by_move | ast::bind_infer => {
             demand::eqtype(fcx, pat.span, expected, typ);
           }
         }
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 1cfda4947e2..eb96e074a82 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -291,7 +291,7 @@ pub impl<
             Number(v) => v.serialize(s),
             String(ref v) => v.serialize(s),
             Boolean(v) => v.serialize(s),
-            List(v) => v.serialize(s),
+            List(ref v) => v.serialize(s),
             Object(ref v) => {
                 do s.emit_rec || {
                     let mut idx = 0;
@@ -927,8 +927,8 @@ impl Json : Eq {
                 match *other { Boolean(b1) => b0 == b1, _ => false },
             Null =>
                 match *other { Null => true, _ => false },
-            List(v0) =>
-                match *other { List(v1) => v0 == v1, _ => false },
+            List(ref v0) =>
+                match *other { List(ref v1) => v0 == v1, _ => false },
             Object(ref d0) => {
                 match *other {
                     Object(ref d1) => {
@@ -981,10 +981,10 @@ impl Json : Ord {
                 }
             }
 
-            List(l0) => {
+            List(ref l0) => {
                 match *other {
                     Number(_) | String(_) | Boolean(_) => false,
-                    List(l1) => l0 < l1,
+                    List(ref l1) => (*l0) < (*l1),
                     Object(_) | Null => true
                 }
             }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index da80bd489b5..aeb76037535 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -309,7 +309,7 @@ enum binding_mode {
     bind_by_value,
     bind_by_move,
     bind_by_ref(ast::mutability),
-    bind_by_implicit_ref
+    bind_infer
 }
 
 impl binding_mode : to_bytes::IterBytes {
@@ -322,7 +322,7 @@ impl binding_mode : to_bytes::IterBytes {
           bind_by_ref(ref m) =>
           to_bytes::iter_bytes_2(&2u8, m, lsb0, f),
 
-          bind_by_implicit_ref =>
+          bind_infer =>
           3u8.iter_bytes(lsb0, f),
         }
     }
@@ -349,9 +349,9 @@ impl binding_mode : cmp::Eq {
                     _ => false
                 }
             }
-            bind_by_implicit_ref => {
+            bind_infer => {
                 match (*other) {
-                    bind_by_implicit_ref => true,
+                    bind_infer => true,
                     _ => false
                 }
             }
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 7e5a267c008..66d9e44ba2e 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -134,7 +134,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
             @{node: {is_mutbl: false,
                      ty: self.ty_infer(),
                      pat: @{id: self.next_id(),
-                            node: ast::pat_ident(ast::bind_by_implicit_ref,
+                            node: ast::pat_ident(ast::bind_infer,
                                                  path(~[ident],
                                                       dummy_sp()),
                                                  None),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8e354f7017d..1bd3f970573 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -23,7 +23,7 @@ use obsolete::{
     ObsoleteModeInFnType, ObsoleteMoveInit, ObsoleteBinaryMove,
 };
 use ast::{_mod, add, arg, arm, attribute,
-             bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
+             bind_by_ref, bind_infer, bind_by_value, bind_by_move,
              bitand, bitor, bitxor, blk, blk_check_mode, box, by_copy,
              by_move, by_ref, by_val, capture_clause,
              capture_item, class_immutable, class_mutable,
@@ -1925,9 +1925,7 @@ impl Parser {
             } else {
                 subpat = @{
                     id: self.get_id(),
-                    node: pat_ident(bind_by_implicit_ref,
-                                    fieldpath,
-                                    None),
+                    node: pat_ident(bind_infer, fieldpath, None),
                     span: self.last_span
                 };
             }
@@ -2054,9 +2052,7 @@ impl Parser {
                 } else if self.eat_keyword(~"move") {
                     binding_mode = bind_by_move;
                 } else if refutable {
-                    // XXX: Should be bind_by_value, but that's not
-                    // backward compatible.
-                    binding_mode = bind_by_implicit_ref;
+                    binding_mode = bind_infer;
                 } else {
                     binding_mode = bind_by_value;
                 }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5b0663f0b44..d9642e08475 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1573,7 +1573,7 @@ fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
                   ast::bind_by_value => {
                       word_nbsp(s, ~"copy");
                   }
-                  ast::bind_by_implicit_ref => {}
+                  ast::bind_infer => {}
               }
           }
           print_path(s, path, true);