summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/sem.nim3
-rw-r--r--compiler/semtypes.nim25
-rw-r--r--tests/generics/tgenericshardcases.nim18
-rw-r--r--tests/metatype/tstaticparams.nim22
4 files changed, 45 insertions, 23 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index ed4c4b093..c8228618b 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -198,7 +198,8 @@ proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode =
       result = semExprWithType(c, evaluated)
     else:
       result = evaluated
-      semmacrosanity.annotateType(result, eOrig.typ)
+      let expectedType = eOrig.typ.skipTypes({tyStatic})
+      semmacrosanity.annotateType(result, expectedType)
   else:
     result = semExprWithType(c, evaluated)
     #result = fitNode(c, e.typ, result) inlined with special case:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index c441c3c44..f91222477 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -155,27 +155,30 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
   if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
     localError(n.info, errRangeIsEmpty)
   
-  var imm: array[2, PNode]
-  imm[0] = semExprWithType(c, n[1], {efDetermineType})
-  imm[1] = semExprWithType(c, n[2], {efDetermineType})
+  var range: array[2, PNode]
+  range[0] = semExprWithType(c, n[1], {efDetermineType})
+  range[1] = semExprWithType(c, n[2], {efDetermineType})
   
-  if not sameType(imm[0].typ, imm[1].typ):
+  var rangeT: array[2, PType]
+  for i in 0..1: rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
+
+  if not sameType(rangeT[0], rangeT[1]):
     localError(n.info, errPureTypeMismatch)
-  elif not imm[0].typ.isOrdinalType:
+  elif not rangeT[0].isOrdinalType:
     localError(n.info, errOrdinalTypeExpected)
-  elif enumHasHoles(imm[0].typ):
-    localError(n.info, errEnumXHasHoles, imm[0].typ.sym.name.s)
+  elif enumHasHoles(rangeT[0]):
+    localError(n.info, errEnumXHasHoles, rangeT[0].sym.name.s)
   
   for i in 0..1:
-    if hasGenericArguments(imm[i]):
-      result.n.addSon makeStaticExpr(c, imm[i])
+    if hasGenericArguments(range[i]):
+      result.n.addSon makeStaticExpr(c, range[i])
     else:
-      result.n.addSon semConstExpr(c, imm[i])
+      result.n.addSon semConstExpr(c, range[i])
  
   if weakLeValue(result.n[0], result.n[1]) == impNo:
     localError(n.info, errRangeIsEmpty)
 
-  addSonSkipIntLit(result, imm[0].typ)
+  addSonSkipIntLit(result, rangeT[0])
 
 proc semRange(c: PContext, n: PNode, prev: PType): PType =
   result = nil
diff --git a/tests/generics/tgenericshardcases.nim b/tests/generics/tgenericshardcases.nim
index 2ef63bc20..e3b805db6 100644
--- a/tests/generics/tgenericshardcases.nim
+++ b/tests/generics/tgenericshardcases.nim
@@ -14,7 +14,8 @@ macro selectType(a, b: typedesc): typedesc =
 type
   Foo[T] = object
     data1: array[T.high, int]
-    data2: array[typeNameLen(T), float] # data3: array[0..T.typeNameLen, selectType(float, int)]
+    data2: array[typeNameLen(T), float]
+    data3: array[0..T.typeNameLen, selectType(float, int)]
 
   MyEnum = enum A, B, C, D
 
@@ -27,10 +28,15 @@ echo high(f1.data2) # (MyEnum.len = 6) - 1 == 5
 echo high(f2.data1) # 127 - 1 == 126
 echo high(f2.data2) # int8.len - 1 == 3
 
-#static:
-# assert high(f1.data1) == ord(D)
-# assert high(f1.data2) == 6 # length of MyEnum
+static:
+  assert high(f1.data1) == ord(C)
+  assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high
 
-# assert high(f2.data1) == 127
-# assert high(f2.data2) == 4 # length of int8
+  assert high(f2.data1) == 126
+  assert high(f2.data2) == 3 
+
+  assert high(f1.data3) == 6 # length of MyEnum
+  assert high(f2.data3) == 4 # length of int8
+
+  assert f2.data3[0] is float
 
diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim
index b1377443b..0597325c3 100644
--- a/tests/metatype/tstaticparams.nim
+++ b/tests/metatype/tstaticparams.nim
@@ -1,6 +1,6 @@
 discard """
   file: "tstaticparams.nim"
-  output: "abracadabra\ntest\n3"
+  output: "abracadabra\ntest\n3\n15"
 """
 
 type 
@@ -11,8 +11,8 @@ type
     data: array[I, T]
 
   TA1[T; I: static[int]] = array[I, T]
-  # TA2[T; I: static[int]] = array[0..I, T]
-  # TA3[T; I: static[int]] = array[I-1, T]
+  TA2[T; I: static[int]] = array[0..I, T]
+  TA3[T; I: static[int]] = array[I-1, T]
 
 proc takeFoo(x: TFoo) =
   echo "abracadabra"
@@ -26,6 +26,18 @@ echo high(y.data)
 
 var
   t1: TA1[float, 1]
-  # t2: TA2[string, 4]
-  # t3: TA3[int, 10]
+  t2: TA2[string, 4]
+  t3: TA3[int, 10]
+
+# example from the manual:
+type
+  Matrix[M,N: static[int]; T] = array[0..(M*N - 1), T]
+    # Note how `Number` is just a type constraint here, while
+    # `static[int]` requires us to supply a compile-time int value
+
+  AffineTransform2D[T] = Matrix[3, 3, T]
+  AffineTransform3D[T] = Matrix[4, 4, T]
+
+var m: AffineTransform3D[float]
+echo high(m)