diff options
author | Araq <rumpf_a@web.de> | 2019-05-24 00:44:49 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-05-24 00:44:49 +0200 |
commit | c7de1a252e2ec8ba9ce0e0872a626aad04bd4c68 (patch) | |
tree | 7f782e9975de086f6cfedc6b0a13e5e0dc3258ba | |
parent | b75ad05267bad6f10e1939354eac14ac821fb8c6 (diff) | |
download | Nim-c7de1a252e2ec8ba9ce0e0872a626aad04bd4c68.tar.gz |
fixes #11257
-rw-r--r-- | compiler/sigmatch.nim | 15 | ||||
-rw-r--r-- | tests/destructor/tconsume_twice.nim | 13 | ||||
-rw-r--r-- | tests/destructor/twidgets_unown.nim | 5 |
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() |