@@ -207,7 +207,9 @@ pub enum const_val {
207
207
const_binary( Rc < Vec < u8 > > ) ,
208
208
const_bool( bool ) ,
209
209
Struct ( ast:: NodeId ) ,
210
- Tuple ( ast:: NodeId )
210
+ Tuple ( ast:: NodeId ) ,
211
+ Array ( Vec < P < Expr > > ) ,
212
+ Repeat ( P < Expr > , u64 ) ,
211
213
}
212
214
213
215
pub fn const_expr_to_pat ( tcx : & ty:: ctxt , expr : & Expr , span : Span ) -> P < ast:: Pat > {
@@ -294,11 +296,15 @@ pub enum ErrKind {
294
296
NegateOnBinary ,
295
297
NegateOnStruct ,
296
298
NegateOnTuple ,
299
+ NegateOnArray ,
300
+ NegateOnRepeat ,
297
301
NotOnFloat ,
298
302
NotOnString ,
299
303
NotOnBinary ,
300
304
NotOnStruct ,
301
305
NotOnTuple ,
306
+ NotOnArray ,
307
+ NotOnRepeat ,
302
308
303
309
NegateWithOverflow ( i64 ) ,
304
310
AddiWithOverflow ( i64 , i64 ) ,
@@ -318,6 +324,12 @@ pub enum ErrKind {
318
324
ExpectedConstTuple ,
319
325
ExpectedConstStruct ,
320
326
TupleIndexOutOfBounds ,
327
+ IndexedNonVec ,
328
+ IndexNotNatural ,
329
+ IndexNotInt ,
330
+ IndexOutOfBounds ,
331
+ RepeatCountNotNatural ,
332
+ RepeatCountNotInt ,
321
333
322
334
MiscBinaryOp ,
323
335
MiscCatchAll ,
@@ -339,11 +351,15 @@ impl ConstEvalErr {
339
351
NegateOnBinary => "negate on binary literal" . into_cow ( ) ,
340
352
NegateOnStruct => "negate on struct" . into_cow ( ) ,
341
353
NegateOnTuple => "negate on tuple" . into_cow ( ) ,
354
+ NegateOnArray => "negate on array" . into_cow ( ) ,
355
+ NegateOnRepeat => "negate on repeat" . into_cow ( ) ,
342
356
NotOnFloat => "not on float or string" . into_cow ( ) ,
343
357
NotOnString => "not on float or string" . into_cow ( ) ,
344
358
NotOnBinary => "not on binary literal" . into_cow ( ) ,
345
359
NotOnStruct => "not on struct" . into_cow ( ) ,
346
360
NotOnTuple => "not on tuple" . into_cow ( ) ,
361
+ NotOnArray => "not on array" . into_cow ( ) ,
362
+ NotOnRepeat => "not on repeat" . into_cow ( ) ,
347
363
348
364
NegateWithOverflow ( ..) => "attempted to negate with overflow" . into_cow ( ) ,
349
365
AddiWithOverflow ( ..) => "attempted to add with overflow" . into_cow ( ) ,
@@ -363,6 +379,12 @@ impl ConstEvalErr {
363
379
ExpectedConstTuple => "expected constant tuple" . into_cow ( ) ,
364
380
ExpectedConstStruct => "expected constant struct" . into_cow ( ) ,
365
381
TupleIndexOutOfBounds => "tuple index out of bounds" . into_cow ( ) ,
382
+ IndexedNonVec => "indexing is only supported for arrays" . into_cow ( ) ,
383
+ IndexNotNatural => "indices must be a natural number" . into_cow ( ) ,
384
+ IndexNotInt => "indices must be integers" . into_cow ( ) ,
385
+ IndexOutOfBounds => "array index out of bounds" . into_cow ( ) ,
386
+ RepeatCountNotNatural => "repeat count must be a natural number" . into_cow ( ) ,
387
+ RepeatCountNotInt => "repeat count must be integers" . into_cow ( ) ,
366
388
367
389
MiscBinaryOp => "bad operands for binary" . into_cow ( ) ,
368
390
MiscCatchAll => "unsupported constant expr" . into_cow ( ) ,
@@ -672,6 +694,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
672
694
const_binary( _) => signal ! ( e, NegateOnBinary ) ,
673
695
const_val:: Tuple ( _) => signal ! ( e, NegateOnTuple ) ,
674
696
const_val:: Struct ( ..) => signal ! ( e, NegateOnStruct ) ,
697
+ const_val:: Array ( _) => signal ! ( e, NegateOnArray ) ,
698
+ const_val:: Repeat ( ..) => signal ! ( e, NegateOnRepeat ) ,
675
699
}
676
700
}
677
701
ast:: ExprUnary ( ast:: UnNot , ref inner) => {
@@ -684,6 +708,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
684
708
const_binary( _) => signal ! ( e, NotOnBinary ) ,
685
709
const_val:: Tuple ( _) => signal ! ( e, NotOnTuple ) ,
686
710
const_val:: Struct ( ..) => signal ! ( e, NotOnStruct ) ,
711
+ const_val:: Array ( _) => signal ! ( e, NotOnArray ) ,
712
+ const_val:: Repeat ( ..) => signal ! ( e, NotOnRepeat ) ,
687
713
}
688
714
}
689
715
ast:: ExprBinary ( op, ref a, ref b) => {
@@ -873,6 +899,33 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
873
899
ast:: ExprTup ( _) => {
874
900
const_val:: Tuple ( e. id )
875
901
}
902
+ ast:: ExprIndex ( ref arr, ref idx) => {
903
+ let arr = try!( eval_const_expr_partial ( tcx, arr, None ) ) ;
904
+ let idx = try!( eval_const_expr_partial ( tcx, idx, None ) ) ;
905
+ let idx = match idx {
906
+ const_int( i) if i >= 0 => i as u64 ,
907
+ const_int( _) => signal ! ( e, IndexNotNatural ) ,
908
+ const_uint( i) => i,
909
+ _ => signal ! ( e, IndexNotInt ) ,
910
+ } ;
911
+ match arr {
912
+ const_val:: Array ( ref v) if idx as usize >= v. len ( ) => signal ! ( e, IndexOutOfBounds ) ,
913
+ const_val:: Array ( v) => try!( eval_const_expr_partial ( tcx, & * v[ idx as usize ] , None ) ) ,
914
+ const_val:: Repeat ( _, n) if idx >= n => signal ! ( e, IndexOutOfBounds ) ,
915
+ const_val:: Repeat ( elem, _) => try!( eval_const_expr_partial ( tcx, & * elem, None ) ) ,
916
+ _ => signal ! ( e, IndexedNonVec ) ,
917
+ }
918
+ }
919
+ ast:: ExprVec ( ref arr) => const_val:: Array ( arr. clone ( ) ) , // FIXME: eval elements?
920
+ ast:: ExprRepeat ( ref elem, ref n) => const_val:: Repeat (
921
+ elem. clone ( ) ,
922
+ match try!( eval_const_expr_partial ( tcx, & * * n, None ) ) {
923
+ const_int( i) if i >= 0 => i as u64 ,
924
+ const_int( _) => signal ! ( e, RepeatCountNotNatural ) ,
925
+ const_uint( i) => i,
926
+ _ => signal ! ( e, RepeatCountNotInt ) ,
927
+ } ,
928
+ ) ,
876
929
ast:: ExprStruct ( ..) => {
877
930
const_val:: Struct ( e. id )
878
931
}
0 commit comments