diff --git a/compiler/seminst.nim b/compiler/seminst.nim index abc5600c3a..f9a1377400 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -239,14 +239,20 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, pushInfoContext(info) var entry = TInstantiation.new entry.sym = result - newSeq(entry.concreteTypes, gp.len) + # we need to compare both the generic types and the concrete types: + # generic[void](), generic[int]() + # see ttypeor.nim test. var i = 0 + newSeq(entry.concreteTypes, fn.typ.len+gp.len) for s in instantiateGenericParamList(c, gp, pt): addDecl(c, s) entry.concreteTypes[i] = s.typ inc i pushProcCon(c, result) instantiateProcType(c, pt, result, info) + for j in 0 .. result.typ.len-1: + entry.concreteTypes[i] = result.typ.sons[j] + inc i if tfTriggersCompileTime in result.typ.flags: incl(result.flags, sfCompileTime) n.sons[genericParamsPos] = ast.emptyNode diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index f643fb9035..7957ac50a4 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -75,8 +75,12 @@ proc searchInstTypes*(key: PType): PType = proc cacheTypeInst*(inst: PType) = # XXX: add to module's generics # update the refcount - let genericTyp = inst.sons[0] - genericTyp.sym.typeInstCache.safeAdd(inst) + let gt = inst.sons[0] + let t = if gt.kind == tyGenericBody: gt.lastSon else: gt + if t.kind in {tyStatic, tyGenericParam, tyIter} + tyTypeClasses: + return + gt.sym.typeInstCache.safeAdd(inst) + type TReplTypeVars* {.final.} = object diff --git a/compiler/types.nim b/compiler/types.nim index 66fb657fc7..3846be8a0a 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -991,7 +991,9 @@ proc compareTypes*(x, y: PType, var c = initSameTypeClosure() c.cmp = cmp c.flags = flags - result = sameTypeAux(x, y, c) + if x == y: result = true + elif x.isNil or y.isNil: result = false + else: result = sameTypeAux(x, y, c) proc inheritanceDiff*(a, b: PType): int = # | returns: 0 iff `a` == `b` diff --git a/tests/metatype/ttypeor.nim b/tests/metatype/ttypeor.nim new file mode 100644 index 0000000000..f5acce7721 --- /dev/null +++ b/tests/metatype/ttypeor.nim @@ -0,0 +1,35 @@ +discard """ + output: '''Foo +Bar''' +""" + +# bug #3338 + +type + Base[T] = Foo[T] | Bar[T] + + Foo[T] = ref object + x: T + + Bar[T] = ref object + x: T + +proc test[T](ks: Foo[T], x, y: T): T = + echo("Foo") + return x + y + ks.x + +proc test[T](ks: Bar[T], x, y: T): T = + echo("Bar") + return x + +proc add[T](ksa: Base[T]) = + var test = ksa.test(5, 10) + ksa.x = test + +var t1 = Foo[int32]() +t1.add() +doAssert t1.x == 15 + +var t2 = Bar[int32]() +t2.add() +doAssert t2.x == 5