diff --git a/src/rustc/middle/borrowck/preserve.rs b/src/rustc/middle/borrowck/preserve.rs index 99bdc44eb5d7..0b7601f59d2c 100644 --- a/src/rustc/middle/borrowck/preserve.rs +++ b/src/rustc/middle/borrowck/preserve.rs @@ -74,8 +74,16 @@ impl private_methods for &preserve_ctxt { // when we borrow an rvalue, we can keep it rooted but only // up to the root_ub point + // When we're in a 'const &x = ...' context, self.root_ub is + // zero and the rvalue is static, not bound to a scope. + let scope_region = if self.root_ub == 0 { + ty::re_static + } else { + ty::re_scope(self.root_ub) + }; + // FIXME(#2977)--need to update trans! - self.compare_scope(cmt, ty::re_scope(self.root_ub)) + self.compare_scope(cmt, scope_region) } cat_stack_upvar(cmt) { self.preserve(cmt) diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs index 7f1fd250c919..dbf60edca8e9 100644 --- a/src/rustc/middle/check_const.rs +++ b/src/rustc/middle/check_const.rs @@ -101,8 +101,15 @@ fn check_expr(sess: session, def_map: resolve3::DefMap, } } } + expr_addr_of(m_imm, _) | expr_tup(*) | expr_rec(*) { } + expr_addr_of(*) { + sess.span_err( + e.span, + ~"borrowed pointers in constants may only refer to \ + immutable values"); + } _ { sess.span_err(e.span, ~"constant contains unimplemented expression type"); diff --git a/src/rustc/middle/trans/consts.rs b/src/rustc/middle/trans/consts.rs index aeb8c8ce74af..8a8e284b5c04 100644 --- a/src/rustc/middle/trans/consts.rs +++ b/src/rustc/middle/trans/consts.rs @@ -130,6 +130,17 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { } } } + ast::expr_addr_of(ast::m_imm, sub) { + let cv = const_expr(cx, sub); + let subty = ty::expr_ty(cx.tcx, sub), + llty = type_of::type_of(cx, subty); + let gv = do str::as_c_str("const") |name| { + llvm::LLVMAddGlobal(cx.llmod, llty, name) + }; + llvm::LLVMSetInitializer(gv, cv); + llvm::LLVMSetGlobalConstant(gv, True); + gv + } ast::expr_tup(es) { C_struct(es.map(|e| const_expr(cx, e))) } diff --git a/src/rustc/middle/typeck/rscope.rs b/src/rustc/middle/typeck/rscope.rs index d76f62e17a96..812354f97a22 100644 --- a/src/rustc/middle/typeck/rscope.rs +++ b/src/rustc/middle/typeck/rscope.rs @@ -8,7 +8,7 @@ trait region_scope { enum empty_rscope { empty_rscope } impl of region_scope for empty_rscope { fn anon_region() -> result { - result::err(~"region types are not allowed here") + result::ok(ty::re_static) } fn named_region(id: ast::ident) -> result { if *id == ~"static" { result::ok(ty::re_static) } diff --git a/src/test/run-pass/const-rec-and-tup.rs b/src/test/run-pass/const-rec-and-tup.rs index 9f4b1785b7ce..1881c771203f 100644 --- a/src/test/run-pass/const-rec-and-tup.rs +++ b/src/test/run-pass/const-rec-and-tup.rs @@ -1,5 +1,5 @@ -const x : (int,int) = (0xfeedf00dd,0xca11ab1e); -const y : { x: (int, int), +const x : (i32,i32) = (0xfeedf00dd,0xca11ab1e); +const y : { x: (i64, i64), y: { a: float, b: float } } = { x: (0xf0f0f0f0_f0f0f0f0, 0xabababab_abababab), diff --git a/src/test/run-pass/const-region-ptrs.rs b/src/test/run-pass/const-region-ptrs.rs new file mode 100644 index 000000000000..2ce212c158dd --- /dev/null +++ b/src/test/run-pass/const-region-ptrs.rs @@ -0,0 +1,9 @@ + +const x: &int = &10; + +const y: &{a: int, b: &int} = &{a: 15, b: x}; + +fn main() { + io::println(fmt!("x = %?", x)); + io::println(fmt!("y = {a: %?, b: %?}", y.a, *(y.b))); +}