diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index d0ec6c6360..f2ad3dca0e 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -73,7 +73,7 @@ proc sameMethodBucket(a, b: PSym): MethodResult = bb = bb.lastSon else: break - if sameType(aa, bb): + if sameType(a.typ.sons[i], b.typ.sons[i]): if aa.kind == tyObject and result != Invalid: result = Yes elif aa.kind == tyObject and bb.kind == tyObject: @@ -83,7 +83,7 @@ proc sameMethodBucket(a, b: PSym): MethodResult = result = Yes else: return No - elif diff != high(int): + elif diff != high(int) and sfFromGeneric notin (a.flags+b.flags): result = Invalid else: return No diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index a6067dfc9d..bf06b019f9 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -373,12 +373,17 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = else: newbody.lastSon.typeInst = result cl.c.typesWithOps.add((newbody, result)) - let methods = skipTypes(bbody, abstractPtrs).methods - for col, meth in items(methods): - # we instantiate the known methods belonging to that type, this causes - # them to be registered and that's enough, so we 'discard' the result. - discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info, - attachedAsgn, col) + let mm = skipTypes(bbody, abstractPtrs) + if tfFromGeneric notin mm.flags: + # bug #5479, prevent endless recursions here: + incl mm.flags, tfFromGeneric + let methods = mm.methods + for col, meth in items(methods): + # we instantiate the known methods belonging to that type, this causes + # them to be registered and that's enough, so we 'discard' the result. + discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info, + attachedAsgn, col) + excl mm.flags, tfFromGeneric proc eraseVoidParams*(t: PType) = # transform '(): void' into '()' because old parts of the compiler really diff --git a/tests/method/tgeneric_methods.nim b/tests/method/tgeneric_methods.nim index 76a68fbb06..0e2aeeedee 100644 --- a/tests/method/tgeneric_methods.nim +++ b/tests/method/tgeneric_methods.nim @@ -1,5 +1,7 @@ discard """ - output: "wow2" + output: '''wow2 +X 1 +X 3''' """ type First[T] = ref object of RootObj @@ -22,3 +24,18 @@ proc takeFirst(x: First[int]) = wow(2, x) takeFirst(x) + + +# bug #5479 +type + Base[T: static[int]] = ref object of RootObj + +method test[T](t: Base[T]) {.base.} = + echo "X ", t.T + +let ab = Base[1]() + +ab.test() + +let ac = Base[3]() +ac.test()