diff options
author | Zahary Karadjov <zahary@gmail.com> | 2018-05-03 19:42:20 +0300 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-05-07 09:37:49 +0200 |
commit | 72976139009b9ae74669dc2443474f091c99f2e4 (patch) | |
tree | 48921b7781a9a3d3dc47ce93700352a245730e1d | |
parent | 4ab1cfb0b07b33015652e8f0d0444f1feed18a57 (diff) | |
download | Nim-72976139009b9ae74669dc2443474f091c99f2e4.tar.gz |
Bugfix: The compiler were not inserting proper downcasts for generic types
This resulted in a codegen error in C++ mode, because the generic types were not defined in modules where calls requiring downcasts were used (generating a downcast forces the inclusion of the full definition of the involved types).
-rw-r--r-- | compiler/sigmatch.nim | 3 | ||||
-rw-r--r-- | compiler/types.nim | 4 | ||||
-rw-r--r-- | tests/generics/module_with_generics.nim | 14 | ||||
-rw-r--r-- | tests/generics/t5602_inheritence.nim | 8 |
4 files changed, 25 insertions, 4 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 716a4f54a..55d83d990 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1962,7 +1962,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, inc(m.genericMatches) if arg.typ == nil: result = arg - elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple: + elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple or + m.inheritancePenalty > 0: result = implicitConv(nkHiddenSubConv, f, arg, m, c) elif arg.typ.isEmptyContainer: result = arg.copyTree diff --git a/compiler/types.nim b/compiler/types.nim index edf4e5b46..b9b6ab33c 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -612,7 +612,7 @@ proc firstOrd*(t: PType): BiggestInt = else: assert(t.n.sons[0].kind == nkSym) result = t.n.sons[0].sym.position - of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic: + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: result = firstOrd(lastSon(t)) of tyOrdinal: if t.len > 0: result = firstOrd(lastSon(t)) @@ -651,7 +651,7 @@ proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt = of tyEnum: assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) result = t.n.sons[sonsLen(t.n) - 1].sym.position - of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic: + of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred: result = lastOrd(lastSon(t)) of tyProxy: result = 0 of tyOrdinal: diff --git a/tests/generics/module_with_generics.nim b/tests/generics/module_with_generics.nim new file mode 100644 index 000000000..e801a4790 --- /dev/null +++ b/tests/generics/module_with_generics.nim @@ -0,0 +1,14 @@ +type + Base[T] = ref object {.inheritable.} + value*: T + + Derived[T] = ref object of Base[T] + derivedValue*: T + +proc makeDerived*[T](v: T): Derived[T] = + new result + result.value = v + +proc setBaseValue*[T](a: Base[T], value: T) = + a.value = value + diff --git a/tests/generics/t5602_inheritence.nim b/tests/generics/t5602_inheritence.nim index 6d48c796e..ee5ba89d5 100644 --- a/tests/generics/t5602_inheritence.nim +++ b/tests/generics/t5602_inheritence.nim @@ -1,10 +1,11 @@ discard """ output: "seq[float]\n0" + targets: "c cpp" """ # https://github.com/nim-lang/Nim/issues/5602 -import typetraits +import typetraits, module_with_generics type Foo[T] = object of RootObj @@ -16,3 +17,8 @@ proc p[T](f: Foo[T]): T = var s: Bar[float] echo p(s).len # the bug was: p(s) should return seq[float], but returns float instead +# Test overloading and code generation when +# downcasting is required for generic types: +var d = makeDerived(10) +setBaseValue(d, 20) + |