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 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; diff --git a/src/test/compile-fail/static-vec-repeat-not-constant.rs b/src/test/compile-fail/static-vec-repeat-not-constant.rs new file mode 100644 index 00000000000..7721e18537e --- /dev/null +++ b/src/test/compile-fail/static-vec-repeat-not-constant.rs @@ -0,0 +1,15 @@ +// 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. + +fn foo() -> int { 23 } + +static a: [int, ..2] = [foo(), ..2]; //~ ERROR: function calls in constants are limited to struct and enum constructors + +fn main() {} diff --git a/src/test/run-pass/repeat-expr-in-static.rs b/src/test/run-pass/repeat-expr-in-static.rs new file mode 100644 index 00000000000..d060db2bb07 --- /dev/null +++ b/src/test/run-pass/repeat-expr-in-static.rs @@ -0,0 +1,16 @@ +// 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. + +static FOO: [int, ..4] = [32, ..4]; +static BAR: [int, ..4] = [32, 32, 32, 32]; + +pub fn main() { + assert_eq!(FOO, BAR); +}