summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-05-22 20:59:54 +0200
committerGitHub <noreply@github.com>2019-05-22 20:59:54 +0200
commitfd16875561634e3ef24072631cf85eeead6213f2 (patch)
treec3c74a5df3298070dc64042633353056c1e6e6a8
parentb62f4b1b0c4c9579ab2cee58fdf8a35b258c6f19 (diff)
downloadNim-fd16875561634e3ef24072631cf85eeead6213f2.tar.gz
fixes #8568 (#11303)
* fixes #8568

* fixes regression
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/sigmatch.nim11
-rw-r--r--tests/overload/tor_isnt_better.nim18
-rw-r--r--tests/overload/toverload_various.nim22
4 files changed, 51 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 268982147..2b74846bd 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1472,6 +1472,10 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
         # type parameters: partial generic specialization
         n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
         result = explicitGenericInstantiation(c, n, s)
+        if result == n:
+          n.sons[0] = copyTree(result)
+        else:
+          n.sons[0] = result
       of skMacro, skTemplate:
         if efInCall in flags:
           # We are processing macroOrTmpl[] in macroOrTmpl[](...) call.
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index cd032c8a8..f4d60a6f7 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -190,6 +190,9 @@ proc copyCandidate(a: var TCandidate, b: TCandidate) =
   copyIdTable(a.bindings, b.bindings)
 
 proc sumGeneric(t: PType): int =
+  # count the "genericness" so that Foo[Foo[T]] has the value 3
+  # and Foo[T] has the value 2 so that we know Foo[Foo[T]] is more
+  # specific than Foo[T].
   var t = t
   var isvar = 1
   while true:
@@ -202,9 +205,9 @@ proc sumGeneric(t: PType): int =
     of tyOr:
       var maxBranch = 0
       for branch in t.sons:
-        let branchSum = branch.sumGeneric
+        let branchSum = sumGeneric(branch)
         if branchSum > maxBranch: maxBranch = branchSum
-      inc result, maxBranch + 1
+      inc result, maxBranch
       break
     of tyVar:
       t = t.sons[0]
@@ -218,10 +221,10 @@ proc sumGeneric(t: PType): int =
       result += ord(t.kind in {tyGenericInvocation, tyAnd})
       for i in 0 ..< t.len:
         if t.sons[i] != nil:
-          result += t.sons[i].sumGeneric
+          result += sumGeneric(t.sons[i])
       break
     of tyStatic:
-      return t.sons[0].sumGeneric + 1
+      return sumGeneric(t.sons[0]) + 1
     of tyGenericParam, tyUntyped, tyTyped: break
     of tyAlias, tySink: t = t.lastSon
     of tyBool, tyChar, tyEnum, tyObject, tyPointer,
diff --git a/tests/overload/tor_isnt_better.nim b/tests/overload/tor_isnt_better.nim
new file mode 100644
index 000000000..5ef8bc7c4
--- /dev/null
+++ b/tests/overload/tor_isnt_better.nim
@@ -0,0 +1,18 @@
+discard """
+  errormsg: "ambiguous call;"
+  line: 16
+"""
+
+# bug #8568
+
+type
+  D[T] = object
+  E[T] = object
+
+proc g(a: D|E): string = "foo D|E"
+proc g(a: D): string = "foo D"
+
+proc test() =
+  let x = g D[int]()
+
+test()
diff --git a/tests/overload/toverload_various.nim b/tests/overload/toverload_various.nim
index c4f8ecbf8..81564a7a9 100644
--- a/tests/overload/toverload_various.nim
+++ b/tests/overload/toverload_various.nim
@@ -176,6 +176,28 @@ block tstaticoverload:
   foo("constant" & " " & "folding")
   foo(staticString("static string"))
 
+# bug #8568 (2)
+
+proc goo(a: int): string = "int"
+proc goo(a: static[int]): string = "static int"
+proc goo(a: var int): string = "var int"
+proc goo[T: int](a: T): string = "T: int"
+#proc goo[T](a: T): string = "nur T"
+
+const tmp1 = 1
+let tmp2 = 1
+var tmp3 = 1
+
+doAssert goo(1) == "static int"
+doAssert goo(tmp1) == "static int"
+doAssert goo(tmp2) == "int"
+doAssert goo(tmp3) == "var int"
+
+doAssert goo[int](1) == "T: int"
+
+doAssert goo[int](tmp1) == "T: int"
+doAssert goo[int](tmp2) == "T: int"
+doAssert goo[int](tmp3) == "T: int"
 
 # bug #6076