@@ -22,6 +22,7 @@ use syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat, walk_pat};
2222use syntax:: codemap:: span;
2323use syntax:: print:: pprust:: pat_to_str;
2424use syntax:: visit;
25+ use std:: sort;
2526
2627struct AltCheckCtxt {
2728 tcx : ty:: ctxt ,
@@ -146,6 +147,12 @@ fn check_exhaustive(cx: @AltCheckCtxt, sp: span, pats: ~[@pat]) {
146147 None => fail ~"check_exhaustive: bad variant in ctor"
147148 }
148149 }
150+ ty:: ty_unboxed_vec( * ) | ty:: ty_evec( * ) => {
151+ match ( * ctor) {
152+ vec( n) => Some ( fmt ! ( "vectors of length %u" , n) ) ,
153+ _ => None
154+ }
155+ }
149156 _ => None
150157 }
151158 }
@@ -166,6 +173,8 @@ enum ctor {
166173 variant( def_id ) ,
167174 val( const_val ) ,
168175 range( const_val , const_val ) ,
176+ vec( uint ) ,
177+ vec_with_tail( uint )
169178}
170179
171180impl ctor : cmp:: Eq {
@@ -179,7 +188,12 @@ impl ctor : cmp::Eq {
179188 range( ref cv0_other, ref cv1_other) ) => {
180189 ( * cv0_self) == ( * cv0_other) && ( * cv1_self) == ( * cv1_other)
181190 }
182- ( single, _) | ( variant( _) , _) | ( val( _) , _) | ( range( * ) , _) => {
191+ ( vec( n_self) , vec( n_other) ) => n_self == n_other,
192+ ( vec_with_tail( n_self) , vec_with_tail( n_other) ) => {
193+ n_self == n_other
194+ }
195+ ( single, _) | ( variant( _) , _) | ( val( _) , _) |
196+ ( range( * ) , _) | ( vec( * ) , _) | ( vec_with_tail( * ) , _) => {
183197 false
184198 }
185199 }
@@ -236,6 +250,21 @@ fn is_useful(cx: @AltCheckCtxt, m: matrix, v: ~[@pat]) -> useful {
236250 }
237251 not_useful
238252 }
253+ ty:: ty_unboxed_vec( * ) | ty:: ty_evec( * ) => {
254+ let max_len = do m. foldr ( 0 ) |r, max_len| {
255+ match r[ 0 ] . node {
256+ pat_vec( elems, _) => uint:: max ( elems. len ( ) , max_len) ,
257+ _ => max_len
258+ }
259+ } ;
260+ for uint:: range( 0 , max_len + 1 ) |n| {
261+ match is_useful_specialized( cx, m, v, vec( n) , n, left_ty) {
262+ not_useful => ( ) ,
263+ ref u => return ( * u)
264+ }
265+ }
266+ not_useful
267+ }
239268 _ => {
240269 let arity = ctor_arity ( cx, single, left_ty) ;
241270 is_useful_specialized ( cx, m, v, single, arity, left_ty)
@@ -297,6 +326,12 @@ fn pat_ctor_id(cx: @AltCheckCtxt, p: @pat) -> Option<ctor> {
297326 pat_region( * ) => {
298327 Some ( single)
299328 }
329+ pat_vec( elems, tail) => {
330+ match tail {
331+ Some ( _) => Some ( vec_with_tail ( elems. len ( ) ) ) ,
332+ None => Some ( vec ( elems. len ( ) ) )
333+ }
334+ }
300335 }
301336}
302337
@@ -360,6 +395,56 @@ fn missing_ctor(cx: @AltCheckCtxt,
360395 else if true_found { Some ( val ( const_bool ( false ) ) ) }
361396 else { Some ( val ( const_bool ( true ) ) ) }
362397 }
398+ ty:: ty_unboxed_vec ( * ) | ty:: ty_evec ( * ) => {
399+ let max_len = do m. foldr ( 0 ) |r, max_len| {
400+ match r[ 0 ] . node {
401+ pat_vec( elems, _) => uint:: max ( elems. len ( ) , max_len) ,
402+ _ => max_len
403+ }
404+ } ;
405+ let min_len_with_tail = do m. foldr ( max_len + 1 ) |r, min_len| {
406+ match r[ 0 ] . node {
407+ pat_vec( elems, tail) => {
408+ if tail. is_some ( ) && elems. len ( ) < min_len {
409+ elems. len ( )
410+ } else {
411+ min_len
412+ }
413+ }
414+ _ => min_len
415+ }
416+ } ;
417+ let vec_lens = do m. filter_map |r| {
418+ match r[ 0 ] . node {
419+ pat_vec( elems, tail) => {
420+ match tail {
421+ None if elems. len ( ) < min_len_with_tail => Some ( elems. len ( ) ) ,
422+ _ => None
423+ }
424+ }
425+ _ => None
426+ }
427+ } ;
428+ let mut sorted_vec_lens = do sort:: merge_sort ( vec_lens) |a, b| {
429+ a < b
430+ } ;
431+ vec:: dedup ( & mut sorted_vec_lens) ;
432+
433+ let mut missing = None ;
434+ for uint:: range( 0 , min_len_with_tail) |i| {
435+ if i >= sorted_vec_lens. len ( ) || i != sorted_vec_lens[ i] {
436+ missing = Some ( i) ;
437+ break ;
438+ }
439+ } ;
440+ if missing. is_none ( ) && min_len_with_tail > max_len {
441+ missing = Some ( min_len_with_tail) ;
442+ }
443+ match missing {
444+ Some ( k) => Some ( vec ( k) ) ,
445+ None => None
446+ }
447+ }
363448 _ => Some ( single)
364449 }
365450}
@@ -378,6 +463,12 @@ fn ctor_arity(cx: @AltCheckCtxt, ctor: ctor, ty: ty::t) -> uint {
378463 }
379464 }
380465 ty:: ty_struct ( cid, _) => ty:: lookup_struct_fields ( cx. tcx , cid) . len ( ) ,
466+ ty:: ty_unboxed_vec ( * ) | ty:: ty_evec ( * ) => {
467+ match ctor {
468+ vec( n) | vec_with_tail( n) => n,
469+ _ => 0 u
470+ }
471+ }
381472 _ => 0 u
382473 }
383474}
@@ -521,6 +612,32 @@ fn specialize(cx: @AltCheckCtxt, r: ~[@pat], ctor_id: ctor, arity: uint,
521612 compare_const_vals ( c_hi, v_hi) <= 0 ;
522613 if match_ { Some ( vec:: tail ( r) ) } else { None }
523614 }
615+ pat_vec( elems, tail) => {
616+ match ctor_id {
617+ vec_with_tail( _) => {
618+ if elems. len ( ) >= arity {
619+ Some ( vec:: append ( elems. slice ( 0 , arity) , vec:: tail ( r) ) )
620+ } else {
621+ None
622+ }
623+ }
624+ vec( _) => {
625+ if elems. len ( ) < arity && tail. is_some ( ) {
626+ Some ( vec:: append (
627+ vec:: append ( elems, vec:: from_elem (
628+ arity - elems. len ( ) , wild ( ) )
629+ ) ,
630+ vec:: tail ( r)
631+ ) )
632+ } else if elems. len ( ) == arity {
633+ Some ( vec:: append ( elems, vec:: tail ( r) ) )
634+ } else {
635+ None
636+ }
637+ }
638+ _ => None
639+ }
640+ }
524641 }
525642}
526643
@@ -593,6 +710,7 @@ fn is_refutable(cx: @AltCheckCtxt, pat: &pat) -> bool {
593710 args. any ( |a| is_refutable ( cx, * a) )
594711 }
595712 pat_enum( _, _) => { false }
713+ pat_vec( * ) => { true }
596714 }
597715}
598716
0 commit comments