diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index b390be59f900..1d1fb13db0c6 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -182,8 +182,10 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef { } Some(@ty::AutoDerefRef(ref adj)) => { let mut ty = ety; + let mut maybe_ptr = None; for adj.autoderefs.times { let (dv, dt) = const_deref(cx, llconst, ty, false); + maybe_ptr = Some(llconst); llconst = dv; ty = dt; } @@ -193,17 +195,21 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef { Some(ref autoref) => { fail_unless!(autoref.region == ty::re_static); fail_unless!(autoref.mutbl != ast::m_mutbl); + // Don't copy data to do a deref+ref. + let llptr = match maybe_ptr { + Some(ptr) => ptr, + None => const_addr_of(cx, llconst) + }; match autoref.kind { ty::AutoPtr => { - llconst = const_addr_of(cx, llconst); + llconst = llptr; } ty::AutoBorrowVec => { - let base = const_addr_of(cx, llconst); let size = machine::llsize_of(cx, val_ty(llconst)); fail_unless!(abi::slice_elt_base == 0); fail_unless!(abi::slice_elt_len == 1); - llconst = C_struct(~[base, size]); + llconst = C_struct(~[llptr, size]); } _ => { cx.sess.span_bug(e.span, diff --git a/src/test/run-pass/const-region-ptrs-noncopy.rs b/src/test/run-pass/const-region-ptrs-noncopy.rs new file mode 100644 index 000000000000..078ae7661cff --- /dev/null +++ b/src/test/run-pass/const-region-ptrs-noncopy.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +type Big = [u64 * 8]; +struct Pair { a: int, b: &'self Big } +const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]); +const y: &'static Pair<'static> = &Pair {a: 15, b: x}; + +pub fn main() { + fail_unless!(ptr::addr_of(x) == ptr::addr_of(y.b)); +}