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
@ -1049,10 +1054,10 @@ proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
initCandidate(c, m, f) initCandidate(c, m, f)
result = typeRel(m, f, a) result = typeRel(m, f, a)
proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
f: PType): PType = f: PType): PType =
result = PType(idTableGet(m.bindings, f)) result = PType(idTableGet(m.bindings, f))
if result == nil: if result == nil:
result = generateTypeInstance(c, m.bindings, arg, f) result = generateTypeInstance(c, m.bindings, arg, f)
if result == nil: if result == nil:
internalError(arg.info, "getInstantiatedType") internalError(arg.info, "getInstantiatedType")
@ -1134,7 +1139,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
arg = argSemantized arg = argSemantized
argType = argType argType = argType
c = m.c c = m.c
if tfHasStatic in fMaybeStatic.flags: if tfHasStatic in fMaybeStatic.flags:
# XXX: When implicit statics are the default # XXX: When implicit statics are the default
# this will be done earlier - we just have to # this will be done earlier - we just have to
@ -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)