From 42f95d055c2f22078f5c94c0d0ca229e1561ccb8 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 4 Mar 2013 18:03:21 -0800 Subject: [PATCH] Allow constant expressions in [Type * n]. --- src/librustc/middle/typeck/astconv.rs | 27 ++++++++++++++++++++++++--- src/libsyntax/ast.rs | 2 +- src/libsyntax/parse/parser.rs | 21 ++++----------------- src/libsyntax/print/pprust.rs | 6 +++--- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 8e0633c10cd..2a70ba7d4c1 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -54,6 +54,7 @@ use core::prelude::*; +use middle::const_eval; use middle::ty::{arg, field, substs}; use middle::ty::{ty_param_substs_and_ty}; use middle::ty; @@ -412,9 +413,29 @@ pub fn ast_ty_to_ty( } } } - ast::ty_fixed_length_vec(a_mt, u) => { - ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt), - ty::vstore_fixed(u)) + ast::ty_fixed_length_vec(a_mt, e) => { + match const_eval::eval_const_expr_partial(tcx, e) { + Ok(ref r) => { + match *r { + const_eval::const_int(i) => + ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt), + ty::vstore_fixed(i as uint)), + const_eval::const_uint(i) => + ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt), + ty::vstore_fixed(i as uint)), + _ => { + tcx.sess.span_fatal( + ast_ty.span, ~"expected constant expr for vector length"); + } + } + } + Err(ref r) => { + tcx.sess.span_fatal( + ast_ty.span, + fmt!("expected constant expr for vector length: %s", + *r)); + } + } } ast::ty_infer => { // ty_infer should only appear as the type of arguments or return diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e5fb2ad153c..e2e750e8903 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -916,7 +916,7 @@ pub enum ty_ { ty_box(mt), ty_uniq(mt), ty_vec(mt), - ty_fixed_length_vec(mt, uint), + ty_fixed_length_vec(mt, @expr), ty_ptr(mt), ty_rptr(Option<@Lifetime>, mt), ty_closure(@TyClosure), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8a883b73a64..c7e93635d4c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -642,7 +642,8 @@ pub impl Parser { self.obsolete(*self.last_span, ObsoleteMutVector); } - // Parse the `* 3` in `[ int * 3 ]` + // Parse the `* e` in `[ int * e ]` + // where `e` is a const expression let t = match self.maybe_parse_fixed_vstore_with_star() { None => ty_vec(mt), Some(suffix) => ty_fixed_length_vec(mt, suffix) @@ -814,23 +815,9 @@ pub impl Parser { }) } - fn maybe_parse_fixed_vstore_with_star(&self) -> Option { + fn maybe_parse_fixed_vstore_with_star(&self) -> Option<@ast::expr> { if self.eat(&token::BINOP(token::STAR)) { - match *self.token { - token::LIT_INT_UNSUFFIXED(i) if i >= 0i64 => { - self.bump(); - Some(i as uint) - } - _ => { - self.fatal( - fmt!( - "expected integral vector length \ - but found `%s`", - token_to_str(self.reader, © *self.token) - ) - ); - } - } + Some(self.parse_expr()) } else { None } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 71f3de17414..ab7fe8dc063 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -425,7 +425,7 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { } print_type(s, mt.ty); word(s.s, ~" * "); - word(s.s, fmt!("%u", v)); + word(s.s, fmt!("%?", v)); word(s.s, ~"]"); } ast::ty_mac(_) => { @@ -1015,7 +1015,7 @@ pub fn print_mac(s: @ps, m: ast::mac) { pub fn print_vstore(s: @ps, t: ast::vstore) { match t { - ast::vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)), + ast::vstore_fixed(Some(i)) => word(s.s, fmt!("%?", i)), ast::vstore_fixed(None) => word(s.s, ~"_"), ast::vstore_uniq => word(s.s, ~"~"), ast::vstore_box => word(s.s, ~"@"), @@ -1028,7 +1028,7 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { pub fn print_expr_vstore(s: @ps, t: ast::expr_vstore) { match t { - ast::expr_vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)), + ast::expr_vstore_fixed(Some(i)) => word(s.s, fmt!("%?", i)), ast::expr_vstore_fixed(None) => word(s.s, ~"_"), ast::expr_vstore_uniq => word(s.s, ~"~"), ast::expr_vstore_box => word(s.s, ~"@"),