This commit is contained in:
Zahary Karadjov 2015-01-02 17:51:08 +02:00
commit b21b72dc14
3 changed files with 45 additions and 22 deletions

View file

@ -268,7 +268,7 @@ proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
template rangeHasStaticIf*(t: PType): bool = template rangeHasStaticIf*(t: PType): bool =
# this accepts the ranges's node # this accepts the ranges's node
t.n[1].kind == nkStaticExpr t.n != nil and t.n.len > 1 and t.n[1].kind == nkStaticExpr
template getStaticTypeFromRange*(t: PType): PType = template getStaticTypeFromRange*(t: PType): PType =
t.n[1][0][1].typ t.n[1][0][1].typ

View file

@ -676,22 +676,27 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
else: else:
fRange = prev fRange = prev
result = typeRel(c, f.sons[1], a.sons[1]) result = typeRel(c, f.sons[1], a.sons[1])
if result < isGeneric: if result < isGeneric: return isNone
result = isNone if rangeHasStaticIf(fRange):
elif tfUnresolved in fRange.flags and if tfUnresolved in fRange.flags:
rangeHasStaticIf(fRange): # This is a range from an array instantiated with a generic
# This is a range from an array instantiated with a generic # static param. We must extract the static param here and bind
# static param. We must extract the static param here and bind # it to the size of the currently supplied array.
# it to the size of the currently supplied array. var
var rangeStaticT = fRange.getStaticTypeFromRange
rangeStaticT = fRange.getStaticTypeFromRange replacementT = newTypeWithSons(c.c, tyStatic, @[tyInt.getSysType])
replacementT = newTypeWithSons(c.c, tyStatic, @[tyInt.getSysType]) inputUpperBound = a.sons[0].n[1].intVal
inputUpperBound = a.sons[0].n[1].intVal # we must correct for the off-by-one discrepancy between
# we must correct for the off-by-one discrepancy between # ranges and static params:
# ranges and static params: replacementT.n = newIntNode(nkIntLit, inputUpperBound + 1)
replacementT.n = newIntNode(nkIntLit, inputUpperBound + 1) put(c.bindings, rangeStaticT, replacementT)
put(c.bindings, rangeStaticT, replacementT) return isGeneric
result = isGeneric
let len = tryResolvingStaticExpr(c, fRange.n[1])
if len.kind == nkIntLit and len.intVal+1 == lengthOrd(a):
return # if we get this far, the result is already good
else:
return isNone
elif lengthOrd(fRange) != lengthOrd(a): elif lengthOrd(fRange) != lengthOrd(a):
result = isNone result = isNone
else: discard else: discard
@ -1148,7 +1153,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
return argSemantized return argSemantized
if argType.kind == tyStatic: if argType.kind == tyStatic:
if m.callee.kind == tyGenericBody: if m.callee.kind == tyGenericBody and tfGenericTypeParam notin argType.flags:
result = newNodeI(nkType, argOrig.info) result = newNodeI(nkType, argOrig.info)
result.typ = makeTypeFromExpr(c, arg) result.typ = makeTypeFromExpr(c, arg)
return return

View file

@ -56,3 +56,21 @@ type TTestSub[N: static[int]] = TTest[1, N]
var z: TTestSub[2] var z: TTestSub[2]
echo z.high echo z.high
# issue 1049
proc matrix_1*[M, N, T](mat: Matrix[M,N,T], a: array[N, int]) = discard
proc matrix_2*[M, N, T](mat: Matrix[M,N,T], a: array[N+1, int]) = discard
proc matrix_3*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N, int]) = discard
proc matrix_4*[M, N: static[int]; T](mat: Matrix[M,N,T], a: array[N+1, int]) = discard
var
tmat: TMatrix[4,4,int]
ar1: array[4, int]
ar2: array[5, int]
matrix_1(tmat, ar1)
matrix_2(tmat, ar2)
matrix_3(tmat, ar1)
matrix_4(tmat, ar2)