diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 6ef2a52086e2f..aa96f3e272712 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -36,6 +36,10 @@ pub struct TestProps { pub no_prefer_dynamic: bool, // Don't run --pretty expanded when running pretty printing tests pub no_pretty_expanded: bool, + // Which pretty mode are we testing with, default to 'normal' + pub pretty_mode: String, + // Only compare pretty output and don't try compiling + pub pretty_compare_only: bool, } // Load any test directives embedded in the file @@ -51,6 +55,8 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut check_stdout = false; let mut no_prefer_dynamic = false; let mut no_pretty_expanded = false; + let mut pretty_mode = None; + let mut pretty_compare_only = false; iter_header(testfile, |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), @@ -85,6 +91,14 @@ pub fn load_props(testfile: &Path) -> TestProps { no_pretty_expanded = parse_no_pretty_expanded(ln); } + if pretty_mode.is_none() { + pretty_mode = parse_pretty_mode(ln); + } + + if !pretty_compare_only { + pretty_compare_only = parse_pretty_compare_only(ln); + } + match parse_aux_build(ln) { Some(ab) => { aux_builds.push(ab); } None => {} @@ -115,6 +129,8 @@ pub fn load_props(testfile: &Path) -> TestProps { check_stdout: check_stdout, no_prefer_dynamic: no_prefer_dynamic, no_pretty_expanded: no_pretty_expanded, + pretty_mode: pretty_mode.unwrap_or("normal".to_string()), + pretty_compare_only: pretty_compare_only } } @@ -205,6 +221,14 @@ fn parse_no_pretty_expanded(line: &str) -> bool { parse_name_directive(line, "no-pretty-expanded") } +fn parse_pretty_mode(line: &str) -> Option { + parse_name_value_directive(line, "pretty-mode") +} + +fn parse_pretty_compare_only(line: &str) -> bool { + parse_name_directive(line, "pretty-compare-only") +} + fn parse_exec_env(line: &str) -> Option<(String, String)> { parse_name_value_directive(line, "exec-env").map(|nv| { // nv is either FOO or FOO=BAR diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 6720b9a530f23..b8a55fb234dfa 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -168,7 +168,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { props, testfile, srcs[round].to_string(), - "normal"); + props.pretty_mode.as_slice()); if !proc_res.status.success() { fatal_proc_rec(format!("pretty-printing failed in round {}", @@ -200,6 +200,9 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { compare_source(expected.as_slice(), actual.as_slice()); + // If we're only making sure that the output matches then just stop here + if props.pretty_compare_only { return; } + // Finally, let's make sure it actually appears to remain valid code let proc_res = typecheck_source(config, props, testfile, actual); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d202e61abf332..5e7426f3ae749 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -877,6 +877,7 @@ pub fn ast_ty_to_ty( } } ast::TyFixedLengthVec(ty, e) => { + typeck::write_ty_to_tcx(tcx, e.id, ty::mk_uint()); match const_eval::eval_const_expr_partial(tcx, &*e) { Ok(ref r) => { match *r { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 747ba26f5909f..83d042b1044dc 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -429,6 +429,18 @@ impl<'a> Visitor<()> for GatherLocalsVisitor<'a> { self.fcx.with_region_lb(b.id, || visit::walk_block(self, b, ())); } + // Since an expr occurs as part of the type fixed size arrays we + // need to record the type for that node + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + match t.node { + ast::TyFixedLengthVec(ref ty, ref count_expr) => { + self.visit_ty(&**ty, ()); + check_expr_with_hint(self.fcx, &**count_expr, ty::mk_uint()); + } + _ => visit::walk_ty(self, t, ()) + } + } + // Don't descend into fns and items fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId, _: ()) { } @@ -3353,6 +3365,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } } ast::ExprCast(ref e, ref t) => { + match t.node { + ast::TyFixedLengthVec(_, ref count_expr) => { + check_expr_with_hint(fcx, &**count_expr, ty::mk_uint()); + } + _ => {} + } check_cast(fcx, &**e, &**t, id, expr.span); } ast::ExprVec(ref args) => { diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index c3e7d06f3f896..d94ac103ceb73 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -181,8 +181,14 @@ impl<'cx> Visitor<()> for WritebackCx<'cx> { visit::walk_local(self, l, ()); } - fn visit_ty(&mut self, _t: &ast::Ty, _: ()) { - // ignore + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + match t.node { + ast::TyFixedLengthVec(ref ty, ref count_expr) => { + self.visit_ty(&**ty, ()); + write_ty_to_tcx(self.tcx(), count_expr.id, ty::mk_uint()); + } + _ => visit::walk_ty(self, t, ()) + } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 123dcf366f440..c9d0f987e3938 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -626,13 +626,16 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) } => { // take it apart: let Local { - ty: _, + ty: ty, pat: pat, init: init, id: id, span: span, source: source, } = **local; + // expand the ty since TyFixedLengthVec contains an Expr + // and thus may have a macro use + let expanded_ty = fld.fold_ty(ty); // expand the pat (it might contain macro uses): let expanded_pat = fld.fold_pat(pat); // find the PatIdents in the pattern: @@ -656,7 +659,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) let new_init_opt = init.map(|e| fld.fold_expr(e)); let rewritten_local = box(GC) Local { - ty: local.ty, + ty: expanded_ty, pat: rewritten_pat, init: new_init_opt, id: id, diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp new file mode 100644 index 0000000000000..910e3ec5ff829 --- /dev/null +++ b/src/test/pretty/issue-4264.pp @@ -0,0 +1,95 @@ +#![feature(phase)] +#![no_std] +#![feature(globs)] +#[phase(plugin, link)] +extern crate std = "std"; +extern crate native; +use std::prelude::*; +// Copyright 2014 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. + +// pretty-compare-only +// pretty-mode:typed +// pp-exact:issue-4264.pp + +// #4264 fixed-length vector types + +pub fn foo(_: [int, ..(3 as uint)]) { } + +pub fn bar() { + static FOO: uint = ((5u as uint) - (4u as uint) as uint); + let _: [(), ..(FOO as uint)] = ([(() as ())] as [(), .. 1]); + + let _: [(), ..(1u as uint)] = ([(() as ())] as [(), .. 1]); + + let _ = + (((&((([(1i as int), (2 as int), (3 as int)] as [int, .. 3])) as + [int, .. 3]) as &[int, .. 3]) as *const _ as + *const [int, .. 3]) as *const [int, ..(3u as uint)] as + *const [int, .. 3]); + (match (() as ()) { + () => { + #[inline] + #[allow(dead_code)] + static __STATIC_FMTSTR: + [::std::fmt::rt::Piece<'static>, ..(1u as uint)] = + ([((::std::fmt::rt::String as + fn(&'static str) -> core::fmt::rt::Piece<'static>)(("test" + as + &'static str)) + as core::fmt::rt::Piece<'static>)] as + [core::fmt::rt::Piece<'static>, .. 1]); + let __args_vec = + (&([] as &'static [core::fmt::Argument<'static>]) as + &'static [core::fmt::Argument<'static>]); + let __args = + (unsafe { + ((::std::fmt::Arguments::new as + unsafe fn(&'static [core::fmt::rt::Piece<'static>], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR + as + [core::fmt::rt::Piece<'static>, .. 1]), + (__args_vec + as + &'static [core::fmt::Argument<'static>])) + as core::fmt::Arguments<'static>) + } as core::fmt::Arguments<'static>); + + + + + + + + + ((::std::fmt::format as + fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&(__args + as + core::fmt::Arguments<'static>) + as + &core::fmt::Arguments<'static>)) + as collections::string::String) + } + } as collections::string::String); +} +pub type Foo = [int, ..(3u as uint)]; +pub struct Bar { + pub x: [int, ..(3u as uint)], +} +pub struct TupleBar([int, ..(4u as uint)]); +pub enum Baz { BazVariant([int, ..(5u as uint)]), } +pub fn id(x: T) -> T { (x as T) } +pub fn use_id() { + let _ = + ((id::<[int, ..(3u as uint)]> as + fn([int, .. 3]) -> [int, .. 3])(([(1 as int), (2 as int), + (3 as int)] as [int, .. 3])) as + [int, .. 3]); +} +fn main() { } diff --git a/src/test/pretty/issue-4264.rs b/src/test/pretty/issue-4264.rs new file mode 100644 index 0000000000000..ad407f48a7ae3 --- /dev/null +++ b/src/test/pretty/issue-4264.rs @@ -0,0 +1,49 @@ +// Copyright 2014 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. + +// pretty-compare-only +// pretty-mode:typed +// pp-exact:issue-4264.pp + +// #4264 fixed-length vector types + +pub fn foo(_: [int, ..3]) {} + +pub fn bar() { + static FOO: uint = 5u - 4u; + let _: [(), ..FOO] = [()]; + + let _ : [(), ..1u] = [()]; + + let _ = &([1i,2,3]) as *const _ as *const [int, ..3u]; + + format!("test"); +} + +pub type Foo = [int, ..3u]; + +pub struct Bar { + pub x: [int, ..3u] +} + +pub struct TupleBar([int, ..4u]); + +pub enum Baz { + BazVariant([int, ..5u]) +} + +pub fn id(x: T) -> T { x } + +pub fn use_id() { + let _ = id::<[int, ..3u]>([1,2,3]); +} + + +fn main() {} diff --git a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs new file mode 100644 index 0000000000000..847024d42baca --- /dev/null +++ b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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. + +#![feature(macro_rules)] + +macro_rules! four ( + () => (4) +) +fn main() { + let _x: [u16, ..four!()]; +}