Skip to content

Commit 81c7382

Browse files
Oliver SchneiderOliver Schneider
Oliver Schneider
authored and
Oliver Schneider
committed
static ref special case for indexing
all other indexing is by-val in const_eval_partial
1 parent 5eb7d70 commit 81c7382

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

src/librustc_trans/trans/consts.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use middle::ty::{self, Ty};
3434
use util::ppaux::{Repr, ty_to_string};
3535

3636
use std::iter::repeat;
37+
use libc::c_uint;
3738
use syntax::{ast, ast_util};
3839
use syntax::parse::token;
3940
use syntax::ptr::P;
@@ -673,14 +674,40 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
673674
_ => break,
674675
}
675676
}
676-
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
677-
if let Some(def::DefStatic(def_id, _)) = opt_def {
678-
get_static_val(cx, def_id, ety)
679-
} else {
680-
// If this isn't the address of a static, then keep going through
681-
// normal constant evaluation.
682-
let (v, _) = const_expr(cx, &**sub, param_substs);
677+
if let ast::ExprIndex(ref base, ref index) = cur.node {
678+
let (bv, bt) = const_expr(cx, &**base, param_substs);
679+
let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
680+
Ok(const_eval::const_int(i)) => i as u64,
681+
Ok(const_eval::const_uint(u)) => u,
682+
_ => unreachable!(),
683+
};
684+
let arr = match bt.sty {
685+
ty::ty_vec(_, Some(_)) => bv,
686+
ty::ty_vec(_, None) | ty::ty_str => {
687+
let e1 = const_get_elt(cx, bv, &[0]);
688+
const_deref_ptr(cx, e1)
689+
},
690+
ty::ty_rptr(_, mt) => if let ty::ty_vec(_, Some(_)) = mt.ty.sty {
691+
const_deref_ptr(cx,bv)
692+
} else {
693+
unreachable!()
694+
},
695+
_ => unreachable!(),
696+
};
697+
// UB if const_eval wasn't called on this
698+
// since no len check happening here
699+
let v = const_get_elt(cx, arr, &[iv as c_uint]);
683700
addr_of(cx, v, "ref")
701+
} else {
702+
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
703+
if let Some(def::DefStatic(def_id, _)) = opt_def {
704+
get_static_val(cx, def_id, ety)
705+
} else {
706+
// If this isn't the address of a static, then keep going through
707+
// normal constant evaluation.
708+
let (v, _) = const_expr(cx, &**sub, param_substs);
709+
addr_of(cx, v, "ref")
710+
}
684711
}
685712
}
686713
ast::ExprAddrOf(ast::MutMutable, ref sub) => {

0 commit comments

Comments
 (0)