fixes #2125
This commit is contained in:
parent
e6dcceae6c
commit
b7f11b8b0a
7 changed files with 113 additions and 20 deletions
|
|
@ -1298,6 +1298,12 @@ proc initIdTable(x: var TIdTable) =
|
||||||
x.counter = 0
|
x.counter = 0
|
||||||
newSeq(x.data, StartSize)
|
newSeq(x.data, StartSize)
|
||||||
|
|
||||||
|
proc resetIdTable*(x: var TIdTable) =
|
||||||
|
x.counter = 0
|
||||||
|
# clear and set to old initial size:
|
||||||
|
setLen(x.data, 0)
|
||||||
|
setLen(x.data, StartSize)
|
||||||
|
|
||||||
proc initObjectSet(x: var TObjectSet) =
|
proc initObjectSet(x: var TObjectSet) =
|
||||||
x.counter = 0
|
x.counter = 0
|
||||||
newSeq(x.data, StartSize)
|
newSeq(x.data, StartSize)
|
||||||
|
|
|
||||||
|
|
@ -174,17 +174,27 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
result.n = originalParams.shallowCopy
|
result.n = originalParams.shallowCopy
|
||||||
|
|
||||||
for i in 1 .. <result.len:
|
for i in 1 .. <result.len:
|
||||||
|
# twrong_field_caching requires these 'resetIdTable' calls:
|
||||||
|
if i > 1: resetIdTable(cl.symMap)
|
||||||
result.sons[i] = replaceTypeVarsT(cl, result.sons[i])
|
result.sons[i] = replaceTypeVarsT(cl, result.sons[i])
|
||||||
propagateToOwner(result, result.sons[i])
|
propagateToOwner(result, result.sons[i])
|
||||||
|
internalAssert originalParams[i].kind == nkSym
|
||||||
|
when true:
|
||||||
|
let oldParam = originalParams[i].sym
|
||||||
|
let param = copySym(oldParam)
|
||||||
|
param.owner = prc
|
||||||
|
param.typ = result.sons[i]
|
||||||
|
param.ast = oldParam.ast.copyTree
|
||||||
|
# don't be lazy here and call replaceTypeVarsN(cl, originalParams[i])!
|
||||||
|
result.n.sons[i] = newSymNode(param)
|
||||||
|
addDecl(c, param)
|
||||||
|
else:
|
||||||
let param = replaceTypeVarsN(cl, originalParams[i])
|
let param = replaceTypeVarsN(cl, originalParams[i])
|
||||||
result.n.sons[i] = param
|
result.n.sons[i] = param
|
||||||
if param.kind == nkSym:
|
|
||||||
# XXX: this won't be true for void params
|
|
||||||
# implement pass-through of void params and
|
|
||||||
# the "sort by distance to point" container
|
|
||||||
param.sym.owner = prc
|
param.sym.owner = prc
|
||||||
addDecl(c, param.sym)
|
addDecl(c, result.n.sons[i].sym)
|
||||||
|
|
||||||
|
resetIdTable(cl.symMap)
|
||||||
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
||||||
result.n.sons[0] = originalParams[0].copyTree
|
result.n.sons[0] = originalParams[0].copyTree
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
|
||||||
result = errorType(cl.c)
|
result = errorType(cl.c)
|
||||||
# In order to prevent endless recursions, we must remember
|
# In order to prevent endless recursions, we must remember
|
||||||
# this bad lookup and replace it with errorType everywhere.
|
# this bad lookup and replace it with errorType everywhere.
|
||||||
# These code paths are only active in nimrod check
|
# These code paths are only active in "nim check"
|
||||||
idTablePut(cl.typeMap, t, result)
|
idTablePut(cl.typeMap, t, result)
|
||||||
elif result.kind == tyGenericParam and not cl.allowMetaTypes:
|
elif result.kind == tyGenericParam and not cl.allowMetaTypes:
|
||||||
internalError(cl.info, "substitution with generic parameter")
|
internalError(cl.info, "substitution with generic parameter")
|
||||||
|
|
|
||||||
|
|
@ -1261,6 +1261,14 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||||
result = implicitConv(nkHiddenStdConv, f, result, m, c)
|
result = implicitConv(nkHiddenStdConv, f, result, m, c)
|
||||||
of isGeneric:
|
of isGeneric:
|
||||||
inc(m.genericMatches)
|
inc(m.genericMatches)
|
||||||
|
when false:
|
||||||
|
if skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple:
|
||||||
|
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
|
||||||
|
else:
|
||||||
|
result = arg.copyTree
|
||||||
|
else:
|
||||||
|
# XXX Why is this ever necessary? arg's type should not be retrofitted
|
||||||
|
# to match formal's type in this way!
|
||||||
result = copyTree(arg)
|
result = copyTree(arg)
|
||||||
result.typ = getInstantiatedType(c, arg, m, f)
|
result.typ = getInstantiatedType(c, arg, m, f)
|
||||||
# BUG: f may not be the right key!
|
# BUG: f may not be the right key!
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,16 @@ discard """
|
||||||
|
|
||||||
import tables
|
import tables
|
||||||
|
|
||||||
proc memoize(f: proc (a: int): int): proc (a: int): int =
|
proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 =
|
||||||
var previous = initTable[int, int]()
|
var previous = initTable[int64, int64]()
|
||||||
return proc(i: int): int =
|
return proc(i: int64): int64 =
|
||||||
if not previous.hasKey i:
|
if not previous.hasKey i:
|
||||||
previous[i] = f(i)
|
previous[i] = f(i)
|
||||||
return previous[i]
|
return previous[i]
|
||||||
|
|
||||||
var fib: proc(a: int): int
|
var fib: proc(a: int64): int64
|
||||||
|
|
||||||
fib = memoize(proc (i: int): int =
|
fib = memoize(proc (i: int64): int64 =
|
||||||
if i == 0 or i == 1:
|
if i == 0 or i == 1:
|
||||||
return 1
|
return 1
|
||||||
return fib(i-1) + fib(i-2)
|
return fib(i-1) + fib(i-2)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tissue1642.nim"
|
file: "tissue1642.nim"
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
block:
|
block:
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
|
||||||
68
tests/generics/twrong_field_caching.nim
Normal file
68
tests/generics/twrong_field_caching.nim
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
discard """
|
||||||
|
output: '''a23: 2x3
|
||||||
|
a32: 3x2
|
||||||
|
transpose A
|
||||||
|
t32: 3x2
|
||||||
|
transpose B
|
||||||
|
x23: 2x3 (2x3)
|
||||||
|
x32: 3x2 (3x2)'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #2125
|
||||||
|
# Suppose we have the following type for a rectangular array:
|
||||||
|
|
||||||
|
type
|
||||||
|
RectArray*[R, C: static[int], T] = distinct array[R * C, T]
|
||||||
|
|
||||||
|
var a23: RectArray[2, 3, int]
|
||||||
|
var a32: RectArray[3, 2, int]
|
||||||
|
|
||||||
|
echo "a23: ", a23.R, "x", a23.C
|
||||||
|
echo "a32: ", a32.R, "x", a32.C
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
# a23: 2x3
|
||||||
|
# a32: 3x2
|
||||||
|
|
||||||
|
# Looking good. Let's add a proc:
|
||||||
|
proc transpose*[R, C, T](m: RectArray[R, C, T]): RectArray[C, R, T] =
|
||||||
|
echo "transpose A"
|
||||||
|
|
||||||
|
var t32 = a23.transpose
|
||||||
|
|
||||||
|
echo "t32: ", t32.R, "x", t32.C
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
# t32: 3x2
|
||||||
|
|
||||||
|
|
||||||
|
# Everything is still OK. Now let's use the rectangular array inside another
|
||||||
|
# generic type:
|
||||||
|
type
|
||||||
|
Matrix*[R, C: static[int], T] = object
|
||||||
|
theArray*: RectArray[R, C, T]
|
||||||
|
|
||||||
|
#var m23: Matrix[2, 3, int]
|
||||||
|
#var m32: Matrix[3, 2, int]
|
||||||
|
|
||||||
|
#echo "m23: ", m23.R, "x", m23.C, " (", m23.theArray.R, "x", m23.theArray.C, ")"
|
||||||
|
#echo "m32: ", m32.R, "x", m32.C, " (", m32.theArray.R, "x", m32.theArray.C, ")"
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
# m23: 2x3 (2x3)
|
||||||
|
# m32: 3x2 (3x2)
|
||||||
|
|
||||||
|
|
||||||
|
# Everything is still as expected. Now let's add the following proc:
|
||||||
|
proc transpose*[R, C, T](m: Matrix[R, C, T]): Matrix[C, R, T] =
|
||||||
|
echo "transpose B"
|
||||||
|
|
||||||
|
var x23: Matrix[2, 3, int]
|
||||||
|
var x32 = x23.transpose
|
||||||
|
|
||||||
|
echo "x23: ", x23.R, "x", x23.C, " (", x23.theArray.R, "x", x23.theArray.C, ")"
|
||||||
|
echo "x32: ", x32.R, "x", x32.C, " (", x32.theArray.R, "x", x32.theArray.C, ")"
|
||||||
|
|
||||||
|
# Output:
|
||||||
|
# x23: 2x3 (2x3)
|
||||||
|
# x32: 3x2 (3x2) <--- this is incorrect. R and C do not match!
|
||||||
Loading…
Add table
Add a link
Reference in a new issue