diff options
-rw-r--r-- | compiler/sem.nim | 3 | ||||
-rw-r--r-- | compiler/semtypes.nim | 25 | ||||
-rw-r--r-- | tests/generics/tgenericshardcases.nim | 18 | ||||
-rw-r--r-- | tests/metatype/tstaticparams.nim | 22 |
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) |