about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-04-04 15:02:25 -0700
committerBrian Anderson <banderson@mozilla.com>2012-04-04 15:03:39 -0700
commit38ed2ea0968db8dbcebb1d1c650b8693ffb8a1dd (patch)
treead47b45f5b7a8a86bcf698a398f601994c3d0876 /src/rustc
parent1ad62def6a550e2ac015bdf34bcf25b7a7b4b92c (diff)
downloadrust-38ed2ea0968db8dbcebb1d1c650b8693ffb8a1dd.tar.gz
rust-38ed2ea0968db8dbcebb1d1c650b8693ffb8a1dd.zip
rustc: Allow consts to refer to other consts
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/driver/driver.rs4
-rw-r--r--src/rustc/middle/check_const.rs24
-rw-r--r--src/rustc/middle/trans/base.rs22
3 files changed, 44 insertions, 6 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index cde545abfca..1b0b4a52b40 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -149,8 +149,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
         time(time_passes, "typechecking",
              bind typeck::check_crate(ty_cx, impl_map, crate));
     time(time_passes, "const checking",
-         bind middle::check_const::check_crate(sess, crate, method_map,
-                                               ty_cx));
+         bind middle::check_const::check_crate(sess, crate, def_map,
+                                               method_map, ty_cx));
 
     if upto == cu_typeck { ret {crate: crate, tcx: some(ty_cx)}; }
 
diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs
index 0284bbd4310..caae792581b 100644
--- a/src/rustc/middle/check_const.rs
+++ b/src/rustc/middle/check_const.rs
@@ -3,12 +3,12 @@ import syntax::{visit, ast_util};
 import driver::session::session;
 import std::map::hashmap;
 
-fn check_crate(sess: session, crate: @crate, method_map: typeck::method_map,
-               tcx: ty::ctxt) {
+fn check_crate(sess: session, crate: @crate, def_map: resolve::def_map,
+                method_map: typeck::method_map, tcx: ty::ctxt) {
     visit::visit_crate(*crate, false, visit::mk_vt(@{
         visit_item: check_item,
         visit_pat: check_pat,
-        visit_expr: bind check_expr(sess, method_map, tcx, _, _, _)
+        visit_expr: bind check_expr(sess, def_map, method_map, tcx, _, _, _)
         with *visit::default_visitor()
     }));
     sess.abort_if_errors();
@@ -43,7 +43,8 @@ fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
     }
 }
 
-fn check_expr(sess: session, method_map: typeck::method_map, tcx: ty::ctxt,
+fn check_expr(sess: session, def_map: resolve::def_map,
+              method_map: typeck::method_map, tcx: ty::ctxt,
               e: @expr, &&is_const: bool, v: visit::vt<bool>) {
     if is_const {
         alt e.node {
@@ -72,6 +73,21 @@ fn check_expr(sess: session, method_map: typeck::method_map, tcx: ty::ctxt,
                               "` in a constant expression");
             }
           }
+          expr_path(path) {
+            alt def_map.find(e.id) {
+              some(def_const(def_id)) {
+                if !ast_util::is_local(def_id) {
+                    sess.span_err(
+                        e.span, "paths in constants may only refer to \
+                                 crate-local constants");
+                }
+              }
+              _ {
+                sess.span_err(
+                    e.span, "paths in constants may only refer to constants");
+              }
+            }
+          }
           _ {
             sess.span_err(e.span,
                           "constant contains unimplemented expression type");
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 495622b4e52..7cd14b7af39 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -4245,6 +4245,28 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
           }
         }
       }
+      ast::expr_path(path) {
+        alt cx.tcx.def_map.find(e.id) {
+          some(ast::def_const(def_id)) {
+            // Don't know how to handle external consts
+            assert ast_util::is_local(def_id);
+            alt cx.tcx.items.get(def_id.node) {
+              ast_map::node_item(@{
+                node: ast::item_const(_, subexpr), _
+              }, _) {
+                // FIXME: Instead of recursing here to regenerate the values
+                // for other constants, we should just look up the
+                // already-defined value
+                trans_const_expr(cx, subexpr)
+              }
+              _ {
+                cx.sess.span_bug(e.span, "expected item");
+              }
+            }
+          }
+          _ { cx.sess.span_bug(e.span, "expected to find a const def") }
+        }
+      }
       _ { cx.sess.span_bug(e.span,
             "bad constant expression type in trans_const_expr"); }
     }