mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
rustc: Allow consts to refer to other consts
This commit is contained in:
parent
1ad62def6a
commit
38ed2ea096
@ -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)}; }
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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"); }
|
||||
}
|
||||
|
6
src/test/run-pass/const-const.rs
Normal file
6
src/test/run-pass/const-const.rs
Normal file
@ -0,0 +1,6 @@
|
||||
const a: int = 1;
|
||||
const b: int = a + 2;
|
||||
|
||||
fn main() {
|
||||
assert b == 3;
|
||||
}
|
Loading…
Reference in New Issue
Block a user