Change:
Minimal test case: If 1024 doesn’t do it for you, try bumping it upwards. ought to do it. Just don’t try numbers like a million or you’ll be waiting a while before it crashes. And if you have anything like systemd-coredump start automatically, it’ll be busy for a while as well… I guess there are a few areas where [T, ..N] is not handled well for large N. (Additional keywords: sized array.)
Running it under GDB shows that it’s flipping back and forth between two functions recursively: Whatever this recursive algorithm is needs to be made non-recursive.
There is a slight difference between this minimal test case, and the original issue . If I reduce the size of the array to 10 bytes in , compilation never completes (no error is raised). If I reduce the size of the array in this test case to 10 bytes, it compiles.
could you try to narrow down the test from , in the manner that chris-morgan has done here, but preserving the behavioral difference you are observing?
I will try my best (this lunchtime), but I only have three hours experience with Rust so far. Every few lines of code written or modified requires 15 minutes of Googling the docs. (This learning curve is still much less steep than Haskell's was.)
feel free to drop by , you’ll get any help you need there quickly.
I was mistaken. I had a subsequent, chained, command on the command line which produced no output and hung. I mistook this for the compiler hanging.
okay, great, thanks for the update! (I now feel better about asking you to do the narrowing rather than attempting to do it myself.) ;)

Discussion:
PatEnum(..) => match cx.tcx.def_map.borrow().find(&pat.id) { Some(&DefConst(..)) => <del> cx.tcx.sess.span_bug(pat.span, "static pattern should've  </del> <ins> cx.tcx.sess.span_bug(pat.span, "const pattern should've  </ins> been rewritten"), Some(&DefVariant(_, id, _)) => vec!(Variant(id)), _ => vec!(Single)

PatStruct(..) => match cx.tcx.def_map.borrow().find(&pat.id) { Some(&DefConst(..)) => <del> cx.tcx.sess.span_bug(pat.span, "static pattern should've  </del> <ins> cx.tcx.sess.span_bug(pat.span, "const pattern should've  </ins> been rewritten"), Some(&DefVariant(_, id, _)) => vec!(Variant(id)), _ => vec!(Single)

pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap { let mut map = HashMap::new(); pat_bindings(dm, pat, |_bm, p_id, _s, path1| { <del> map.insert(path1.node, p_id); </del> <ins> map.insert(path1.node, p_id); </ins> }); map } <ins> pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatLit(_) | PatRange(_, _) => true, PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => { match dm.borrow().find(&pat.id) { Some(&DefVariant(..)) => true, _ => false } } PatVec(_, _, _) => true, _ => false } } </ins> pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => {

use std; use std::collections::HashMap; <ins> use std::iter::AdditiveIterator; </ins> use std::rc::Rc; use syntax::ast; use syntax::ast::{DUMMY_NODE_ID, Ident};

} } <del> fn pick_col(m: &[Match]) -> uint { fn score(p: &ast::Pat) -> uint { match p.node { ast::PatLit(_) | ast::PatEnum(_, _) | ast::PatRange(_, _) => 1u, ast::PatIdent(_, _, Some(ref p)) => score(&**p), _ => 0u </del> <ins> fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> { fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> uint { match pat.node { ast::PatIdent(_, _, Some(ref inner)) => pat_score(def_map, &**inner), _ if pat_is_refutable(def_map, pat) => 1u, _ => 0u </ins> } } <del> let mut scores = Vec::from_elem(m[0].pats.len(), 0u); for br in m.iter() { for (i, ref p) in br.pats.iter().enumerate() { *scores.get_mut(i) += score(&***p); </del> <ins> let column_score: |&[Match], uint| -> uint = |m, col| { let total_score = m.iter() .map(|row| row.pats[col]) .map(|pat| pat_score(def_map, pat)) .sum(); // Irrefutable columns always go first, they'd only be duplicated in the branches. if total_score == 0 { std::uint::MAX } else { total_score </ins> } <del> } let mut max_score = 0u; let mut best_col = 0u; for (i, score) in scores.iter().enumerate() { let score = *score; // Irrefutable columns always go first, they'd only be duplicated in // the branches. if score == 0u { return i; } // If no irrefutable ones are found, we pick the one with the biggest // branching factor. if score > max_score { max_score = score; best_col = i; } } return best_col; </del> <ins> }; let column_contains_any_nonwild_patterns: |&uint| -> bool = |&col| { m.iter().any(|row| match row.pats[col].node { ast::PatWild(_) => false, _ => true }) }; range(0, m[0].pats.len()) .filter(column_contains_any_nonwild_patterns) .map(|col| (col, column_score(m, col))) .max_by(|&(_, score)| score) .map(|(col, _)| col) </ins> } // Compiles a comparison between two things.

return; } <del> let col_count = m[0].pats.len(); if col_count == 0u { let data = &m[0].data; for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() { let llmatch = data.bindings_map.get(ident).llmatch; call_lifetime_start(bcx, llmatch); Store(bcx, *value_ptr, llmatch); </del> <ins> let tcx = bcx.tcx(); let def_map = &tcx.def_map; match pick_column_to_specialize(def_map, m) { Some(col) => { let val = vals[col]; if has_nested_bindings(m, col) { let expanded = expand_nested_bindings(bcx, m, col, val); compile_submatch_continue(bcx, expanded.as_slice(), vals, chk, col, val, has_genuine_default) } else { compile_submatch_continue(bcx, m, vals, chk, col, val, has_genuine_default) } </ins> } <del> match data.arm.guard { Some(ref guard_expr) => { bcx = compile_guard(bcx, &**guard_expr, m[0].data, m[1..m.len()], vals, chk, has_genuine_default); </del> <ins> None => { let data = &m[0].data; for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() { let llmatch = data.bindings_map.get(ident).llmatch; call_lifetime_start(bcx, llmatch); Store(bcx, *value_ptr, llmatch); </ins> } <del> _ => () </del> <ins> match data.arm.guard { Some(ref guard_expr) => { bcx = compile_guard(bcx, &**guard_expr, m[0].data, m[1..m.len()], vals, chk, has_genuine_default); } _ => () } Br(bcx, data.bodycx.llbb); </ins> } <del> Br(bcx, data.bodycx.llbb); return; } let col = pick_col(m); let val = vals[col]; if has_nested_bindings(m, col) { let expanded = expand_nested_bindings(bcx, m, col, val); compile_submatch_continue(bcx, expanded.as_slice(), vals, chk, col, val, has_genuine_default) } else { compile_submatch_continue(bcx, m, vals, chk, col, val, has_genuine_default) </del> } }

<ins> // 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. fn main() { assert_eq!(match [0u8, ..1024] { _ => 42u, }, 42u); assert_eq!(match [0u8, ..1024] { [1, _..] => 0u, [0, _..] => 1u, _ => 2u }, 1u); } </ins>