summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-05-24 00:44:49 +0200
committerAraq <rumpf_a@web.de>2019-05-24 00:44:49 +0200
commitc7de1a252e2ec8ba9ce0e0872a626aad04bd4c68 (patch)
tree7f782e9975de086f6cfedc6b0a13e5e0dc3258ba
parentb75ad05267bad6f10e1939354eac14ac821fb8c6 (diff)
downloadNim-c7de1a252e2ec8ba9ce0e0872a626aad04bd4c68.tar.gz
fixes #11257
-rw-r--r--compiler/sigmatch.nim15
-rw-r--r--tests/destructor/tconsume_twice.nim13
-rw-r--r--tests/destructor/twidgets_unown.nim5
3 files changed, 24 insertions, 9 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index f4d60a6f7..8065c4992 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -329,7 +329,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
 proc typeRel*(c: var TCandidate, f, aOrig: PType,
               flags: TTypeRelFlags = {}): TTypeRelation
 
-proc concreteType(c: TCandidate, t: PType): PType =
+proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
   case t.kind
   of tyNil:
     result = nil              # what should it be?
@@ -351,6 +351,13 @@ proc concreteType(c: TCandidate, t: PType): PType =
   of tyGenericInvocation:
     result = t
     doAssert(false, "cannot resolve type: " & typeToString(t))
+  of tyOwned:
+    # bug #11257: the comparison system.`==`[T: proc](x, y: T) works
+    # better without the 'owned' type:
+    if f != nil and f.len > 0 and f.sons[0].skipTypes({tyBuiltInTypeClass}).kind == tyProc:
+      result = t.lastSon
+    else:
+      result = t
   else:
     result = t                # Note: empty is valid here
 
@@ -1663,9 +1670,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
         # check if 'T' has a constraint as in 'proc p[T: Constraint](x: T)'
         if f.sonsLen > 0 and f.sons[0].kind != tyNone:
           let oldInheritancePenalty = c.inheritancePenalty
-          result = typeRel(c, f.lastSon, a, flags + {trDontBind})
+          result = typeRel(c, f.sons[0], a, flags + {trDontBind})
           if doBind and result notin {isNone, isGeneric}:
-            let concrete = concreteType(c, a)
+            let concrete = concreteType(c, a, f)
             if concrete == nil: return isNone
             put(c, f, concrete)
           # bug #6526
@@ -1684,7 +1691,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
           a.sym.kind = skType
           a.flags.excl tfWildcard
         else:
-          concrete = concreteType(c, a)
+          concrete = concreteType(c, a, f)
           if concrete == nil:
             return isNone
         if doBind:
diff --git a/tests/destructor/tconsume_twice.nim b/tests/destructor/tconsume_twice.nim
index a06ea4efd..8687b3ce5 100644
--- a/tests/destructor/tconsume_twice.nim
+++ b/tests/destructor/tconsume_twice.nim
@@ -1,12 +1,15 @@
 discard """
   cmd: "nim c --newruntime $file"
-  errormsg: "sink parameter `a` is already consumed at tconsume_twice.nim(8, 6)"
-  line: 10
+  errormsg: "sink parameter `a` is already consumed at tconsume_twice.nim(11, 10)"
+  line: 13
 """
+type
+  Foo = ref object
 
-proc consumeTwice(a: owned proc()): owned proc() =
-  if a == nil:
+proc use(a: owned Foo): bool = discard
+proc consumeTwice(a: owned Foo): owned Foo =
+  if use(a):
     return
   return a
 
-assert consumeTwice(proc() = discard) != nil
+assert consumeTwice(Foo()) != nil
diff --git a/tests/destructor/twidgets_unown.nim b/tests/destructor/twidgets_unown.nim
index bd4cd76af..5e53a0e5b 100644
--- a/tests/destructor/twidgets_unown.nim
+++ b/tests/destructor/twidgets_unown.nim
@@ -62,6 +62,11 @@ proc main =
 
   w.draw()
 
+  # bug #11257
+  var a: owned proc()
+  if a != nil:
+    a()
+
 main()
 
 let (a, d) = allocCounters()