rustc: Allow consts to refer to other consts

This commit is contained in:
Brian Anderson 2012-04-04 15:02:25 -07:00
parent 1ad62def6a
commit 38ed2ea096
4 changed files with 50 additions and 6 deletions

View file

@ -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)}; }

View file

@ -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");

View file

@ -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"); }
}

View file

@ -0,0 +1,6 @@
const a: int = 1;
const b: int = a + 2;
fn main() {
assert b == 3;
}