Skip to content

Commit 38ed2ea

Browse files
committed
rustc: Allow consts to refer to other consts
1 parent 1ad62de commit 38ed2ea

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

src/rustc/driver/driver.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
149149
time(time_passes, "typechecking",
150150
bind typeck::check_crate(ty_cx, impl_map, crate));
151151
time(time_passes, "const checking",
152-
bind middle::check_const::check_crate(sess, crate, method_map,
153-
ty_cx));
152+
bind middle::check_const::check_crate(sess, crate, def_map,
153+
method_map, ty_cx));
154154

155155
if upto == cu_typeck { ret {crate: crate, tcx: some(ty_cx)}; }
156156

src/rustc/middle/check_const.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import syntax::{visit, ast_util};
33
import driver::session::session;
44
import std::map::hashmap;
55

6-
fn check_crate(sess: session, crate: @crate, method_map: typeck::method_map,
7-
tcx: ty::ctxt) {
6+
fn check_crate(sess: session, crate: @crate, def_map: resolve::def_map,
7+
method_map: typeck::method_map, tcx: ty::ctxt) {
88
visit::visit_crate(*crate, false, visit::mk_vt(@{
99
visit_item: check_item,
1010
visit_pat: check_pat,
11-
visit_expr: bind check_expr(sess, method_map, tcx, _, _, _)
11+
visit_expr: bind check_expr(sess, def_map, method_map, tcx, _, _, _)
1212
with *visit::default_visitor()
1313
}));
1414
sess.abort_if_errors();
@@ -43,7 +43,8 @@ fn check_pat(p: @pat, &&_is_const: bool, v: visit::vt<bool>) {
4343
}
4444
}
4545

46-
fn check_expr(sess: session, method_map: typeck::method_map, tcx: ty::ctxt,
46+
fn check_expr(sess: session, def_map: resolve::def_map,
47+
method_map: typeck::method_map, tcx: ty::ctxt,
4748
e: @expr, &&is_const: bool, v: visit::vt<bool>) {
4849
if is_const {
4950
alt e.node {
@@ -72,6 +73,21 @@ fn check_expr(sess: session, method_map: typeck::method_map, tcx: ty::ctxt,
7273
"` in a constant expression");
7374
}
7475
}
76+
expr_path(path) {
77+
alt def_map.find(e.id) {
78+
some(def_const(def_id)) {
79+
if !ast_util::is_local(def_id) {
80+
sess.span_err(
81+
e.span, "paths in constants may only refer to \
82+
crate-local constants");
83+
}
84+
}
85+
_ {
86+
sess.span_err(
87+
e.span, "paths in constants may only refer to constants");
88+
}
89+
}
90+
}
7591
_ {
7692
sess.span_err(e.span,
7793
"constant contains unimplemented expression type");

src/rustc/middle/trans/base.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4245,6 +4245,28 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
42454245
}
42464246
}
42474247
}
4248+
ast::expr_path(path) {
4249+
alt cx.tcx.def_map.find(e.id) {
4250+
some(ast::def_const(def_id)) {
4251+
// Don't know how to handle external consts
4252+
assert ast_util::is_local(def_id);
4253+
alt cx.tcx.items.get(def_id.node) {
4254+
ast_map::node_item(@{
4255+
node: ast::item_const(_, subexpr), _
4256+
}, _) {
4257+
// FIXME: Instead of recursing here to regenerate the values
4258+
// for other constants, we should just look up the
4259+
// already-defined value
4260+
trans_const_expr(cx, subexpr)
4261+
}
4262+
_ {
4263+
cx.sess.span_bug(e.span, "expected item");
4264+
}
4265+
}
4266+
}
4267+
_ { cx.sess.span_bug(e.span, "expected to find a const def") }
4268+
}
4269+
}
42484270
_ { cx.sess.span_bug(e.span,
42494271
"bad constant expression type in trans_const_expr"); }
42504272
}

src/test/run-pass/const-const.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const a: int = 1;
2+
const b: int = a + 2;
3+
4+
fn main() {
5+
assert b == 3;
6+
}

0 commit comments

Comments
 (0)