@@ -113,6 +113,8 @@ pub enum TypeErrorEnum {
113
113
PatternsAreNotExhaustive ( Vec < PatternStack > ) ,
114
114
/// The expression cannot be matched upon.
115
115
TypeDoesNotSupportPatternMatching ( Type ) ,
116
+ /// The specified identifier is not a constant.
117
+ ArraySizeNotConst ( String ) ,
116
118
}
117
119
118
120
impl std:: fmt:: Display for TypeErrorEnum {
@@ -223,6 +225,9 @@ impl std::fmt::Display for TypeErrorEnum {
223
225
TypeErrorEnum :: TypeDoesNotSupportPatternMatching ( ty) => {
224
226
f. write_fmt ( format_args ! ( "Type {ty} does not support pattern matching" ) )
225
227
}
228
+ TypeErrorEnum :: ArraySizeNotConst ( identifier) => {
229
+ f. write_fmt ( format_args ! ( "Array sizes must be constants, but '{identifier}' is a variable" ) )
230
+ }
226
231
}
227
232
}
228
233
}
@@ -252,6 +257,10 @@ impl Type {
252
257
let elem = elem. as_concrete_type ( types) ?;
253
258
Type :: Array ( Box :: new ( elem) , * size)
254
259
}
260
+ Type :: ArrayConst ( elem, size) => {
261
+ let elem = elem. as_concrete_type ( types) ?;
262
+ Type :: ArrayConst ( Box :: new ( elem) , size. clone ( ) )
263
+ }
255
264
Type :: Tuple ( fields) => {
256
265
let mut concrete_fields = Vec :: with_capacity ( fields. len ( ) ) ;
257
266
for field in fields. iter ( ) {
@@ -792,6 +801,37 @@ impl UntypedExpr {
792
801
let ty = Type :: Array ( Box :: new ( value. ty . clone ( ) ) , * size) ;
793
802
( ExprEnum :: ArrayRepeatLiteral ( Box :: new ( value) , * size) , ty)
794
803
}
804
+ ExprEnum :: ArrayRepeatLiteralConst ( value, size) => match env. get ( size) {
805
+ None => match defs. consts . get ( size. as_str ( ) ) {
806
+ Some ( & ty) if ty == & Type :: Unsigned ( UnsignedNumType :: Usize ) => {
807
+ let value = value. type_check ( top_level_defs, env, fns, defs) ?;
808
+ let ty = Type :: ArrayConst ( Box :: new ( value. ty . clone ( ) ) , size. clone ( ) ) ;
809
+ (
810
+ ExprEnum :: ArrayRepeatLiteralConst ( Box :: new ( value) , size. clone ( ) ) ,
811
+ ty,
812
+ )
813
+ }
814
+ Some ( & ty) => {
815
+ let e = TypeErrorEnum :: UnexpectedType {
816
+ expected : Type :: Unsigned ( UnsignedNumType :: Usize ) ,
817
+ actual : ty. clone ( ) ,
818
+ } ;
819
+ return Err ( vec ! [ Some ( TypeError ( e, meta) ) ] ) ;
820
+ }
821
+ None => {
822
+ return Err ( vec ! [ Some ( TypeError (
823
+ TypeErrorEnum :: UnknownIdentifier ( size. clone( ) ) ,
824
+ meta,
825
+ ) ) ] ) ;
826
+ }
827
+ } ,
828
+ Some ( _) => {
829
+ return Err ( vec ! [ Some ( TypeError (
830
+ TypeErrorEnum :: ArraySizeNotConst ( size. clone( ) ) ,
831
+ meta,
832
+ ) ) ] ) ;
833
+ }
834
+ } ,
795
835
ExprEnum :: ArrayAccess ( arr, index) => {
796
836
let arr = arr. type_check ( top_level_defs, env, fns, defs) ?;
797
837
let mut index = index. type_check ( top_level_defs, env, fns, defs) ?;
@@ -1124,7 +1164,7 @@ impl UntypedExpr {
1124
1164
| Type :: Tuple ( _)
1125
1165
| Type :: Struct ( _)
1126
1166
| Type :: Enum ( _) => { }
1127
- Type :: Fn ( _, _) | Type :: Array ( _, _) => {
1167
+ Type :: Fn ( _, _) | Type :: Array ( _, _) | Type :: ArrayConst ( _ , _ ) => {
1128
1168
let e = TypeErrorEnum :: TypeDoesNotSupportPatternMatching ( ty. clone ( ) ) ;
1129
1169
return Err ( vec ! [ Some ( TypeError ( e, meta) ) ] ) ;
1130
1170
}
@@ -1519,6 +1559,7 @@ enum Ctor {
1519
1559
Struct ( String , Vec < ( String , Type ) > ) ,
1520
1560
Variant ( String , String , Option < Vec < Type > > ) ,
1521
1561
Array ( Box < Type > , usize ) ,
1562
+ ArrayConst ( Box < Type > , String ) ,
1522
1563
}
1523
1564
1524
1565
type PatternStack = Vec < TypedPattern > ;
@@ -1587,7 +1628,7 @@ fn specialize(ctor: &Ctor, pattern: &[TypedPattern]) -> Vec<PatternStack> {
1587
1628
}
1588
1629
_ => vec ! [ ] ,
1589
1630
} ,
1590
- Ctor :: Array ( _, _) => match head_enum {
1631
+ Ctor :: Array ( _, _) | Ctor :: ArrayConst ( _ , _ ) => match head_enum {
1591
1632
PatternEnum :: Identifier ( _) => vec ! [ tail. collect( ) ] ,
1592
1633
_ => vec ! [ ] ,
1593
1634
} ,
@@ -1793,6 +1834,7 @@ fn split_ctor(patterns: &[PatternStack], q: &[TypedPattern], defs: &Defs) -> Vec
1793
1834
vec ! [ Ctor :: Tuple ( fields. clone( ) ) ]
1794
1835
}
1795
1836
Type :: Array ( elem_ty, size) => vec ! [ Ctor :: Array ( elem_ty. clone( ) , * size) ] ,
1837
+ Type :: ArrayConst ( elem_ty, size) => vec ! [ Ctor :: ArrayConst ( elem_ty. clone( ) , size. clone( ) ) ] ,
1796
1838
Type :: Fn ( _, _) => {
1797
1839
panic ! ( "Type {ty:?} does not support pattern matching" )
1798
1840
}
@@ -1889,6 +1931,14 @@ fn usefulness(patterns: Vec<PatternStack>, q: PatternStack, defs: &Defs) -> Vec<
1889
1931
meta,
1890
1932
) ,
1891
1933
) ,
1934
+ Ctor :: ArrayConst ( elem_ty, size) => witness. insert (
1935
+ 0 ,
1936
+ Pattern :: typed (
1937
+ PatternEnum :: Identifier ( "_" . to_string ( ) ) ,
1938
+ Type :: ArrayConst ( elem_ty. clone ( ) , size. clone ( ) ) ,
1939
+ meta,
1940
+ ) ,
1941
+ ) ,
1892
1942
}
1893
1943
witnesses. push ( witness) ;
1894
1944
}
0 commit comments