@@ -207,7 +207,10 @@ 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 ( ast:: NodeId , u64 ) ,
212
+ Repeat ( ast:: NodeId , u64 ) ,
213
+ Ref ( Box < const_val > ) ,
211
214
}
212
215
213
216
pub fn const_expr_to_pat ( tcx : & ty:: ctxt , expr : & Expr , span : Span ) -> P < ast:: Pat > {
@@ -294,11 +297,28 @@ pub enum ErrKind {
294
297
NegateOnBinary ,
295
298
NegateOnStruct ,
296
299
NegateOnTuple ,
300
+ NegateOnArray ,
301
+ NegateOnRepeat ,
302
+ NegateOnRef ,
297
303
NotOnFloat ,
298
304
NotOnString ,
299
305
NotOnBinary ,
300
306
NotOnStruct ,
301
307
NotOnTuple ,
308
+ NotOnArray ,
309
+ NotOnRepeat ,
310
+ NotOnRef ,
311
+
312
+ DerefInt ,
313
+ DerefUInt ,
314
+ DerefBool ,
315
+ DerefString ,
316
+ DerefFloat ,
317
+ DerefBinary ,
318
+ DerefTuple ,
319
+ DerefStruct ,
320
+ DerefArray ,
321
+ DerefRepeat ,
302
322
303
323
NegateWithOverflow ( i64 ) ,
304
324
AddiWithOverflow ( i64 , i64 ) ,
@@ -318,6 +338,13 @@ pub enum ErrKind {
318
338
ExpectedConstTuple ,
319
339
ExpectedConstStruct ,
320
340
TupleIndexOutOfBounds ,
341
+ IndexedNonVec ,
342
+ IndexNotNatural ,
343
+ IndexNotInt ,
344
+ IndexOutOfBounds ,
345
+ RepeatCountNotNatural ,
346
+ RepeatCountNotInt ,
347
+ MutableRef ,
321
348
322
349
MiscBinaryOp ,
323
350
MiscCatchAll ,
@@ -339,11 +366,28 @@ impl ConstEvalErr {
339
366
NegateOnBinary => "negate on binary literal" . into_cow ( ) ,
340
367
NegateOnStruct => "negate on struct" . into_cow ( ) ,
341
368
NegateOnTuple => "negate on tuple" . into_cow ( ) ,
369
+ NegateOnArray => "negate on array" . into_cow ( ) ,
370
+ NegateOnRepeat => "negate on repeat" . into_cow ( ) ,
371
+ NegateOnRef => "negate on ref" . into_cow ( ) ,
342
372
NotOnFloat => "not on float or string" . into_cow ( ) ,
343
373
NotOnString => "not on float or string" . into_cow ( ) ,
344
374
NotOnBinary => "not on binary literal" . into_cow ( ) ,
345
375
NotOnStruct => "not on struct" . into_cow ( ) ,
346
376
NotOnTuple => "not on tuple" . into_cow ( ) ,
377
+ NotOnArray => "not on array" . into_cow ( ) ,
378
+ NotOnRepeat => "not on repeat" . into_cow ( ) ,
379
+ NotOnRef => "not on ref" . into_cow ( ) ,
380
+
381
+ DerefInt => "deref on int" . into_cow ( ) ,
382
+ DerefUInt => "deref on unsigned int" . into_cow ( ) ,
383
+ DerefBool => "deref on float" . into_cow ( ) ,
384
+ DerefFloat => "deref on float" . into_cow ( ) ,
385
+ DerefString => "deref on string" . into_cow ( ) ,
386
+ DerefBinary => "deref on binary literal" . into_cow ( ) ,
387
+ DerefStruct => "deref on struct" . into_cow ( ) ,
388
+ DerefTuple => "deref on tuple" . into_cow ( ) ,
389
+ DerefArray => "deref on array" . into_cow ( ) ,
390
+ DerefRepeat => "deref on repeat" . into_cow ( ) ,
347
391
348
392
NegateWithOverflow ( ..) => "attempted to negate with overflow" . into_cow ( ) ,
349
393
AddiWithOverflow ( ..) => "attempted to add with overflow" . into_cow ( ) ,
@@ -363,6 +407,13 @@ impl ConstEvalErr {
363
407
ExpectedConstTuple => "expected constant tuple" . into_cow ( ) ,
364
408
ExpectedConstStruct => "expected constant struct" . into_cow ( ) ,
365
409
TupleIndexOutOfBounds => "tuple index out of bounds" . into_cow ( ) ,
410
+ IndexedNonVec => "indexing is only supported for arrays" . into_cow ( ) ,
411
+ IndexNotNatural => "indices must be a natural number" . into_cow ( ) ,
412
+ IndexNotInt => "indices must be integers" . into_cow ( ) ,
413
+ IndexOutOfBounds => "array index out of bounds" . into_cow ( ) ,
414
+ RepeatCountNotNatural => "repeat count must be a natural number" . into_cow ( ) ,
415
+ RepeatCountNotInt => "repeat count must be integers" . into_cow ( ) ,
416
+ MutableRef => "cannot get a mutable reference to a constant" . into_cow ( ) ,
366
417
367
418
MiscBinaryOp => "bad operands for binary" . into_cow ( ) ,
368
419
MiscCatchAll => "unsupported constant expr" . into_cow ( ) ,
@@ -682,6 +733,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
682
733
const_binary( _) => signal ! ( e, NegateOnBinary ) ,
683
734
const_val:: Tuple ( _) => signal ! ( e, NegateOnTuple ) ,
684
735
const_val:: Struct ( ..) => signal ! ( e, NegateOnStruct ) ,
736
+ const_val:: Array ( ..) => signal ! ( e, NegateOnArray ) ,
737
+ const_val:: Repeat ( ..) => signal ! ( e, NegateOnRepeat ) ,
738
+ const_val:: Ref ( _) => signal ! ( e, NegateOnRef ) ,
685
739
}
686
740
}
687
741
ast:: ExprUnary ( ast:: UnNot , ref inner) => {
@@ -694,6 +748,24 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
694
748
const_binary( _) => signal ! ( e, NotOnBinary ) ,
695
749
const_val:: Tuple ( _) => signal ! ( e, NotOnTuple ) ,
696
750
const_val:: Struct ( ..) => signal ! ( e, NotOnStruct ) ,
751
+ const_val:: Array ( ..) => signal ! ( e, NotOnArray ) ,
752
+ const_val:: Repeat ( ..) => signal ! ( e, NotOnRepeat ) ,
753
+ const_val:: Ref ( _) => signal ! ( e, NotOnRef ) ,
754
+ }
755
+ }
756
+ ast:: ExprUnary ( ast:: UnDeref , ref inner) => {
757
+ match try!( eval_const_expr_partial ( tcx, & * * inner, ety) ) {
758
+ const_int( _) => signal ! ( e, DerefInt ) ,
759
+ const_uint( _) => signal ! ( e, DerefUInt ) ,
760
+ const_bool( _) => signal ! ( e, DerefBool ) ,
761
+ const_str( _) => signal ! ( e, DerefString ) ,
762
+ const_float( _) => signal ! ( e, DerefFloat ) ,
763
+ const_binary( _) => signal ! ( e, DerefBinary ) ,
764
+ const_val:: Tuple ( _) => signal ! ( e, DerefTuple ) ,
765
+ const_val:: Struct ( ..) => signal ! ( e, DerefStruct ) ,
766
+ const_val:: Array ( ..) => signal ! ( e, DerefArray ) ,
767
+ const_val:: Repeat ( ..) => signal ! ( e, DerefRepeat ) ,
768
+ const_val:: Ref ( inner) => * inner,
697
769
}
698
770
}
699
771
ast:: ExprBinary ( op, ref a, ref b) => {
@@ -877,12 +949,54 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
877
949
ast:: ExprBlock ( ref block) => {
878
950
match block. expr {
879
951
Some ( ref expr) => try!( eval_const_expr_partial ( tcx, & * * expr, ety) ) ,
880
- None => const_int ( 0 )
952
+ None => const_int ( 0 ) // huh???
881
953
}
882
954
}
883
955
ast:: ExprTup ( _) => {
884
956
const_val:: Tuple ( e. id )
885
957
}
958
+ ast:: ExprIndex ( ref arr, ref idx) => {
959
+ let mut arr = try!( eval_const_expr_partial ( tcx, arr, None ) ) ;
960
+ while let const_val:: Ref ( inner) = arr {
961
+ arr = * inner;
962
+ }
963
+ let idx = try!( eval_const_expr_partial ( tcx, idx, None ) ) ;
964
+ let idx = match idx {
965
+ const_int( i) if i >= 0 => i as u64 ,
966
+ const_int( _) => signal ! ( e, IndexNotNatural ) ,
967
+ const_uint( i) => i,
968
+ _ => signal ! ( e, IndexNotInt ) ,
969
+ } ;
970
+ match arr {
971
+ const_val:: Array ( _, n) if idx >= n => signal ! ( e, IndexOutOfBounds ) ,
972
+ const_val:: Array ( v, _) => if let ast:: ExprVec ( ref v) = tcx. map . expect_expr ( v) . node {
973
+ try!( eval_const_expr_partial ( tcx, & * v[ idx as usize ] , None ) )
974
+ } else {
975
+ unreachable ! ( )
976
+ } ,
977
+ const_val:: Repeat ( _, n) if idx >= n => signal ! ( e, IndexOutOfBounds ) ,
978
+ const_val:: Repeat ( elem, _) => try!( eval_const_expr_partial (
979
+ tcx,
980
+ & * tcx. map . expect_expr ( elem) ,
981
+ None ,
982
+ ) ) ,
983
+ _ => signal ! ( e, IndexedNonVec ) ,
984
+ }
985
+ }
986
+ ast:: ExprAddrOf ( ast:: Mutability :: MutMutable , _) => signal ! ( e, MutableRef ) ,
987
+ ast:: ExprAddrOf ( ast:: Mutability :: MutImmutable , ref expr) => {
988
+ const_val:: Ref ( Box :: new ( try!( eval_const_expr_partial ( tcx, & * * expr, None ) ) ) )
989
+ } ,
990
+ ast:: ExprVec ( ref v) => const_val:: Array ( e. id , v. len ( ) as u64 ) ,
991
+ ast:: ExprRepeat ( _, ref n) => const_val:: Repeat (
992
+ e. id ,
993
+ match try!( eval_const_expr_partial ( tcx, & * * n, None ) ) {
994
+ const_int( i) if i >= 0 => i as u64 ,
995
+ const_int( _) => signal ! ( e, RepeatCountNotNatural ) ,
996
+ const_uint( i) => i,
997
+ _ => signal ! ( e, RepeatCountNotInt ) ,
998
+ } ,
999
+ ) ,
886
1000
ast:: ExprStruct ( ..) => {
887
1001
const_val:: Struct ( e. id )
888
1002
}
0 commit comments