From 3b0e27cc74d61e229aeaf0a710d3a018f7104ffc Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 8 May 2016 00:28:52 +0300 Subject: [PATCH] trans: handle string literal reborrows. --- src/librustc_trans/mir/constant.rs | 10 ++++++++++ src/test/run-pass/mir_constval_adts.rs | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 0097bca2306ac..9320617983772 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -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) } @@ -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)) @@ -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() { @@ -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 }; diff --git a/src/test/run-pass/mir_constval_adts.rs b/src/test/run-pass/mir_constval_adts.rs index 8a1f68dbea3ee..4e9c0bce646e6 100644 --- a/src/test/run-pass/mir_constval_adts.rs +++ b/src/test/run-pass/mir_constval_adts.rs @@ -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"); @@ -26,7 +27,19 @@ fn mir() -> (Point, (i32, i32), (&'static str, &'static str)){ (struct1, tuple1, tuple2) } +#[derive(PartialEq, Eq, Debug)] +struct Newtype(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(); }