about summary refs log tree commit diff
path: root/src/rustc/middle
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-03-14 15:12:09 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-03-14 15:13:04 -0700
commit1ed768bc3b32f45626b1fb1c3dca83d4936bf33f (patch)
treebc7151f883624bcb66d59816eabb6566419cfc55 /src/rustc/middle
parent1600be2c3b1054e2fce59778e2f85d7fa582657f (diff)
downloadrust-1ed768bc3b32f45626b1fb1c3dca83d4936bf33f.tar.gz
rust-1ed768bc3b32f45626b1fb1c3dca83d4936bf33f.zip
rustc: Determine the region of pointer dereference expressions
Diffstat (limited to 'src/rustc/middle')
-rw-r--r--src/rustc/middle/typeck.rs22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index cee041c6f8b..c47a04ddb64 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -1933,8 +1933,8 @@ fn lookup_field_ty(cx: ty::ctxt, items:[@ast::class_item],
 
 /*
  * Returns the region that the value named by the given expression lives in.
- * If the expression is not an lvalue, reports an error and returns the block
- * region.
+ * The expression must have been typechecked. If the expression is not an
+ * lvalue, returns the block region.
  *
  * Note that borrowing is not detected here, because we would have to
  * immediately structurally resolve too many types otherwise. Thus the
@@ -1958,10 +1958,20 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
                 }
             }
         }
-        ast::expr_field(base, _, _) | ast::expr_index(base, _) |
-                ast::expr_unary(ast::deref, base) {
-            fcx.ccx.tcx.sess.span_unimpl(expr.span, "regions of field, " +
-                                         "index, or deref operations");
+        ast::expr_field(base, _, _) | ast::expr_index(base, _) {
+            fcx.ccx.tcx.sess.span_unimpl(expr.span, "regions of field or " +
+                                         "index operations");
+        }
+        ast::expr_unary(ast::deref, base) {
+            let expr_ty = ty::expr_ty(fcx.ccx.tcx, base);
+            let expr_ty = structurally_resolved_type(fcx, expr.span, expr_ty);
+            alt ty::get(expr_ty).struct {
+                ty::ty_rptr(region, _) { region }
+                ty::ty_box(_) | ty::ty_uniq(_) {
+                    fcx.ccx.tcx.sess.span_unimpl(expr.span, "borrowing");
+                }
+                _ { ret region_of(fcx, base); }
+            }
         }
         _ {
             let blk_id = fcx.ccx.tcx.region_map.rvalue_to_block.get(expr.id);