diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2689821475aac..2b74846bdb331 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 cd032c8a819fb..f4d60a6f7862d 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 0000000000000..5ef8bc7c4cc37 --- /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 c4f8ecbf8155c..81564a7a93c00 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