summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2018-05-03 19:42:20 +0300
committerAndreas Rumpf <rumpf_a@web.de>2018-05-07 09:37:49 +0200
commit72976139009b9ae74669dc2443474f091c99f2e4 (patch)
tree48921b7781a9a3d3dc47ce93700352a245730e1d
parent4ab1cfb0b07b33015652e8f0d0444f1feed18a57 (diff)
downloadNim-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.nim3
-rw-r--r--compiler/types.nim4
-rw-r--r--tests/generics/module_with_generics.nim14
-rw-r--r--tests/generics/t5602_inheritence.nim8
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)
+