From ccc85b1ac790c7505068bec83a601c09be2b18bf Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 12 Aug 2013 21:10:29 -0400 Subject: [PATCH] librustc: Allow vector repeat exprs in statics. --- src/librustc/middle/check_const.rs | 1 + src/librustc/middle/const_eval.rs | 2 ++ src/librustc/middle/trans/consts.rs | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index f9ef6dabcd6..160cc23bd19 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -160,6 +160,7 @@ pub fn check_expr(sess: Session, expr_field(*) | expr_index(*) | expr_tup(*) | + expr_repeat(*) | expr_struct(*) => { } expr_addr_of(*) => { sess.span_err( diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 2de94cdbf4c..68e3dfd63be 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -153,6 +153,8 @@ pub fn classify(e: &expr, lookup_constness(tcx, e) } + ast::expr_repeat(*) => general_const, + _ => non_const }; tcx.ccache.insert(did, cn); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 1992d71427f..b362ba396f1 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -32,6 +32,7 @@ use middle::trans::type_::Type; use std::c_str::ToCStr; use std::libc::c_uint; +use std::vec; use syntax::{ast, ast_util, ast_map}; pub fn const_lit(cx: &mut CrateContext, e: &ast::expr, lit: ast::lit) @@ -540,6 +541,23 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { _ => cx.sess.span_bug(e.span, "bad const-slice expr") } } + ast::expr_repeat(elem, count, _) => { + let vec_ty = ty::expr_ty(cx.tcx, e); + let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty); + let llunitty = type_of::type_of(cx, unit_ty); + let n = match const_eval::eval_const_expr(cx.tcx, count) { + const_eval::const_int(i) => i as uint, + const_eval::const_uint(i) => i as uint, + _ => cx.sess.span_bug(count.span, "count must be integral const expression.") + }; + let vs = vec::from_elem(n, const_expr(cx, elem)); + let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { + C_struct(vs) + } else { + C_array(llunitty, vs) + }; + v + } ast::expr_path(ref pth) => { assert_eq!(pth.types.len(), 0); let tcx = cx.tcx;