Inline constants across crates.

This commit is contained in:
Josh Matthews 2013-03-07 01:30:20 -05:00
parent 50277ec555
commit 7bb03345cf
7 changed files with 133 additions and 26 deletions

View File

@ -616,7 +616,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
let must_write =
match item.node {
item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) |
item_mod(*) | item_foreign_mod(*) => true,
item_mod(*) | item_foreign_mod(*) | item_const(*) => true,
_ => false
};
if !must_write && !reachable(ecx, item.id) { return; }
@ -639,6 +639,7 @@ fn encode_info_for_item(ecx: @EncodeContext, ebml_w: writer::Encoder,
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_symbol(ecx, ebml_w, item.id);
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
ebml_w.end_tag();
}
item_fn(_, purity, ref generics, _) => {

View File

@ -124,17 +124,11 @@ pub fn check_expr(sess: Session,
items without type parameters");
}
match def_map.find(&e.id) {
Some(def_variant(_, _)) |
Some(def_struct(_)) => { }
Some(def_const(_)) |
Some(def_fn(_, _)) |
Some(def_variant(_, _)) |
Some(def_struct(_)) => { }
Some(def_const(def_id)) |
Some(def_fn(def_id, _)) => {
if !ast_util::is_local(def_id) {
sess.span_err(
e.span, ~"paths in constants may only refer to \
crate-local constants or functions");
}
}
Some(def) => {
debug!("(checking const) found bad def: %?", def);
sess.span_err(
@ -246,11 +240,13 @@ pub fn check_item_recursion(sess: Session,
expr_path(*) => {
match env.def_map.find(&e.id) {
Some(def_const(def_id)) => {
match env.ast_map.get(&def_id.node) {
ast_map::node_item(it, _) => {
(v.visit_item)(it, env, v);
if ast_util::is_local(def_id) {
match env.ast_map.get(&def_id.node) {
ast_map::node_item(it, _) => {
(v.visit_item)(it, env, v);
}
_ => fail!(~"const not bound to an item")
}
_ => fail!(~"const not bound to an item")
}
}
_ => ()

View File

@ -11,6 +11,7 @@
use core::prelude::*;
use lib::llvm::{llvm, ValueRef, TypeRef, Bool, True, False};
use metadata::csearch;
use middle::const_eval;
use middle::trans::adt;
use middle::trans::base;
@ -18,6 +19,7 @@ use middle::trans::base::get_insn_ctxt;
use middle::trans::common::*;
use middle::trans::consts;
use middle::trans::expr;
use middle::trans::inline;
use middle::trans::machine;
use middle::trans::type_of;
use middle::ty;
@ -121,10 +123,12 @@ pub fn const_autoderef(cx: @CrateContext, ty: ty::t, v: ValueRef)
}
pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
if !ast_util::is_local(def_id) {
cx.tcx.sess.bug(~"cross-crate constants");
}
if !cx.const_values.contains_key(&def_id.node) {
let mut def_id = def_id;
if !ast_util::is_local(def_id) ||
!cx.const_values.contains_key(&def_id.node) {
if !ast_util::is_local(def_id) {
def_id = inline::maybe_instantiate_inline(cx, def_id, true);
}
match cx.tcx.items.get(&def_id.node) {
ast_map::node_item(@ast::item {
node: ast::item_const(_, subexpr), _
@ -419,8 +423,13 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
assert pth.types.len() == 0;
match cx.tcx.def_map.find(&e.id) {
Some(ast::def_fn(def_id, _purity)) => {
assert ast_util::is_local(def_id);
let f = base::get_item_val(cx, def_id.node);
let f = if !ast_util::is_local(def_id) {
let ty = csearch::get_type(cx.tcx, def_id).ty;
base::trans_external_path(cx, def_id, ty)
} else {
assert ast_util::is_local(def_id);
base::get_item_val(cx, def_id.node)
};
let ety = ty::expr_ty_adjusted(cx.tcx, e);
match ty::get(ety).sty {
ty::ty_bare_fn(*) | ty::ty_ptr(*) => {

View File

@ -138,6 +138,7 @@ use middle::trans::consts;
use middle::trans::controlflow;
use middle::trans::datum::*;
use middle::trans::debuginfo;
use middle::trans::inline;
use middle::trans::machine;
use middle::trans::meth;
use middle::trans::tvec;
@ -984,15 +985,54 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
match def {
ast::def_const(did) => {
let const_ty = expr_ty(bcx, ref_expr);
let val = if did.crate == ast::local_crate {
#[cfg(stage0)]
fn get_did(_ccx: @CrateContext, did: ast::def_id)
-> ast::def_id {
did
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get_did(ccx: @CrateContext, did: ast::def_id)
-> ast::def_id {
if did.crate != ast::local_crate {
inline::maybe_instantiate_inline(ccx, did, true)
} else {
did
}
}
#[cfg(stage0)]
fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
-> ValueRef {
let ccx = bcx.ccx();
if did.crate == ast::local_crate {
// The LLVM global has the type of its initializer,
// which may not be equal to the enum's type for
// non-C-like enums.
PointerCast(bcx, base::get_item_val(ccx, did.node),
T_ptr(type_of(bcx.ccx(), const_ty)))
} else {
base::trans_external_path(ccx, did, const_ty)
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
-> ValueRef {
// The LLVM global has the type of its initializer,
// which may not be equal to the enum's type for
// non-C-like enums.
PointerCast(bcx, base::get_item_val(ccx, did.node),
PointerCast(bcx, base::get_item_val(bcx.ccx(), did.node),
T_ptr(type_of(bcx.ccx(), const_ty)))
} else {
base::trans_external_path(ccx, did, const_ty)
};
}
let did = get_did(ccx, did);
let val = get_val(bcx, did, const_ty);
DatumBlock {
bcx: bcx,
datum: Datum {val: val,

View File

@ -0,0 +1,16 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub extern fn bar() {
}
pub const foopy: &static/str = "hi there";
pub const uint_val: uint = 12;
pub const uint_expr: uint = (1 << uint_val) - 1;

View File

@ -0,0 +1,25 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-fast
// aux-build:cci_const.rs
extern mod cci_const;
const foo: &static/str = cci_const::foopy;
const a: uint = cci_const::uint_val;
const b: uint = cci_const::uint_expr + 5;
fn main() {
assert a == 12;
let foo2 = a;
assert foo2 == cci_const::uint_val;
assert b == cci_const::uint_expr + 5;
assert foo == cci_const::foopy;
}

View File

@ -0,0 +1,20 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-fast
// aux-build:cci_const.rs
extern mod cci_const;
use cci_const::bar;
const foo: *u8 = bar;
fn main() {
assert foo == cci_const::bar;
}