Skip to content

Commit

Permalink
trans: handle string literal reborrows.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed May 8, 2016
1 parent 3001626 commit 3b0e27c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/librustc_trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ enum Base {
/// A constant value without an unique address.
Value(ValueRef),

/// String literal base pointer (cast from array).
Str(ValueRef),

/// The address of a static.
Static(ValueRef)
}
Expand All @@ -156,6 +159,10 @@ impl<'tcx> ConstLvalue<'tcx> {
fn to_const(&self, span: Span) -> Const<'tcx> {
match self.base {
Base::Value(val) => Const::new(val, self.ty),
Base::Str(ptr) => {
span_bug!(span, "loading from `str` ({:?}) in constant",
Value(ptr))
}
Base::Static(val) => {
span_bug!(span, "loading from `static` ({:?}) in constant",
Value(val))
Expand Down Expand Up @@ -375,6 +382,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
};
if self.ccx.statics().borrow().contains_key(&base) {
(Base::Static(base), extra)
} else if let ty::TyStr = projected_ty.sty {
(Base::Str(base), extra)
} else {
let val = consts::load_const(self.ccx, base, projected_ty);
if val.is_null() {
Expand Down Expand Up @@ -669,6 +678,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
consts::addr_of(self.ccx, llval, align, "ref")
}
}
Base::Str(llval) |
Base::Static(llval) => llval
};

Expand Down
13 changes: 13 additions & 0 deletions src/test/run-pass/mir_constval_adts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct Point {
_x: i32,
_y: i32,
}

const STRUCT: Point = Point { _x: 42, _y: 42 };
const TUPLE1: (i32, i32) = (42, 42);
const TUPLE2: (&'static str, &'static str) = ("hello","world");
Expand All @@ -26,7 +27,19 @@ fn mir() -> (Point, (i32, i32), (&'static str, &'static str)){
(struct1, tuple1, tuple2)
}

#[derive(PartialEq, Eq, Debug)]
struct Newtype<T>(T);

const NEWTYPE: Newtype<&'static str> = Newtype("foobar");

#[rustc_mir]
fn test_promoted_newtype_str_ref() {
let x = &NEWTYPE;
assert_eq!(x, &Newtype("foobar"));
}

fn main(){
assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2));
test_promoted_newtype_str_ref();
}

0 comments on commit 3b0e27c

Please sign in to comment.