about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-08-03 18:07:45 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-08-03 18:07:58 -0700
commit488ece05b59b68a7d25c1fc59388438a78bb0b52 (patch)
tree31f07c8930bad13792194849498e0be401c7aabc /src/rustc
parente02b1b1ec8696715c08fc970b67d9eaa6c91b15e (diff)
downloadrust-488ece05b59b68a7d25c1fc59388438a78bb0b52.tar.gz
rust-488ece05b59b68a7d25c1fc59388438a78bb0b52.zip
Implement &-expressions in consts. Part of #2317.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/borrowck/preserve.rs10
-rw-r--r--src/rustc/middle/check_const.rs7
-rw-r--r--src/rustc/middle/trans/consts.rs11
-rw-r--r--src/rustc/middle/typeck/rscope.rs2
4 files changed, 28 insertions, 2 deletions
diff --git a/src/rustc/middle/borrowck/preserve.rs b/src/rustc/middle/borrowck/preserve.rs
index 99bdc44eb5d..0b7601f59d2 100644
--- a/src/rustc/middle/borrowck/preserve.rs
+++ b/src/rustc/middle/borrowck/preserve.rs
@@ -74,8 +74,16 @@ impl private_methods for &preserve_ctxt {
             // when we borrow an rvalue, we can keep it rooted but only
             // up to the root_ub point
 
+            // When we're in a 'const &x = ...' context, self.root_ub is
+            // zero and the rvalue is static, not bound to a scope.
+            let scope_region = if self.root_ub == 0 {
+                ty::re_static
+            } else {
+                ty::re_scope(self.root_ub)
+            };
+
             // FIXME(#2977)--need to update trans!
-            self.compare_scope(cmt, ty::re_scope(self.root_ub))
+            self.compare_scope(cmt, scope_region)
           }
           cat_stack_upvar(cmt) {
             self.preserve(cmt)
diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs
index 7f1fd250c91..dbf60edca8e 100644
--- a/src/rustc/middle/check_const.rs
+++ b/src/rustc/middle/check_const.rs
@@ -101,8 +101,15 @@ fn check_expr(sess: session, def_map: resolve3::DefMap,
               }
             }
           }
+          expr_addr_of(m_imm, _) |
           expr_tup(*) |
           expr_rec(*) { }
+          expr_addr_of(*) {
+                sess.span_err(
+                    e.span,
+                    ~"borrowed pointers in constants may only refer to \
+                      immutable values");
+          }
           _ {
             sess.span_err(e.span,
                           ~"constant contains unimplemented expression type");
diff --git a/src/rustc/middle/trans/consts.rs b/src/rustc/middle/trans/consts.rs
index aeb8c8ce74a..8a8e284b5c0 100644
--- a/src/rustc/middle/trans/consts.rs
+++ b/src/rustc/middle/trans/consts.rs
@@ -130,6 +130,17 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
           }
         }
       }
+      ast::expr_addr_of(ast::m_imm, sub) {
+        let cv = const_expr(cx, sub);
+        let subty = ty::expr_ty(cx.tcx, sub),
+        llty = type_of::type_of(cx, subty);
+        let gv = do str::as_c_str("const") |name| {
+            llvm::LLVMAddGlobal(cx.llmod, llty, name)
+        };
+        llvm::LLVMSetInitializer(gv, cv);
+        llvm::LLVMSetGlobalConstant(gv, True);
+        gv
+      }
       ast::expr_tup(es) {
         C_struct(es.map(|e| const_expr(cx, e)))
       }
diff --git a/src/rustc/middle/typeck/rscope.rs b/src/rustc/middle/typeck/rscope.rs
index d76f62e17a9..812354f97a2 100644
--- a/src/rustc/middle/typeck/rscope.rs
+++ b/src/rustc/middle/typeck/rscope.rs
@@ -8,7 +8,7 @@ trait region_scope {
 enum empty_rscope { empty_rscope }
 impl of region_scope for empty_rscope {
     fn anon_region() -> result<ty::region, ~str> {
-        result::err(~"region types are not allowed here")
+        result::ok(ty::re_static)
     }
     fn named_region(id: ast::ident) -> result<ty::region, ~str> {
         if *id == ~"static" { result::ok(ty::re_static) }