Skip to content

Don't ICE when dealing with the count expr for fixed array types in various places. #15804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
Expand Down Expand Up @@ -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 => {}
Expand Down Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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<String> {
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
Expand Down
5 changes: 4 additions & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}",
Expand Down Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
}
}
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 {
Expand Down
18 changes: 18 additions & 0 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, _: ()) { }
Expand Down Expand Up @@ -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) => {
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/middle/typeck/check/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, ())
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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,
Expand Down
95 changes: 95 additions & 0 deletions src/test/pretty/issue-4264.pp
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T>(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() { }
49 changes: 49 additions & 0 deletions src/test/pretty/issue-4264.rs
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T>(x: T) -> T { x }

pub fn use_id() {
let _ = id::<[int, ..3u]>([1,2,3]);
}


fn main() {}
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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!()];
}