This commit is contained in:
Araq 2019-05-24 00:44:49 +02:00
commit c7de1a252e
3 changed files with 24 additions and 9 deletions

View file

@ -329,7 +329,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
proc typeRel*(c: var TCandidate, f, aOrig: PType, proc typeRel*(c: var TCandidate, f, aOrig: PType,
flags: TTypeRelFlags = {}): TTypeRelation flags: TTypeRelFlags = {}): TTypeRelation
proc concreteType(c: TCandidate, t: PType): PType = proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
case t.kind case t.kind
of tyNil: of tyNil:
result = nil # what should it be? result = nil # what should it be?
@ -351,6 +351,13 @@ proc concreteType(c: TCandidate, t: PType): PType =
of tyGenericInvocation: of tyGenericInvocation:
result = t result = t
doAssert(false, "cannot resolve type: " & typeToString(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: else:
result = t # Note: empty is valid here 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)' # check if 'T' has a constraint as in 'proc p[T: Constraint](x: T)'
if f.sonsLen > 0 and f.sons[0].kind != tyNone: if f.sonsLen > 0 and f.sons[0].kind != tyNone:
let oldInheritancePenalty = c.inheritancePenalty 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}: if doBind and result notin {isNone, isGeneric}:
let concrete = concreteType(c, a) let concrete = concreteType(c, a, f)
if concrete == nil: return isNone if concrete == nil: return isNone
put(c, f, concrete) put(c, f, concrete)
# bug #6526 # bug #6526
@ -1684,7 +1691,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
a.sym.kind = skType a.sym.kind = skType
a.flags.excl tfWildcard a.flags.excl tfWildcard
else: else:
concrete = concreteType(c, a) concrete = concreteType(c, a, f)
if concrete == nil: if concrete == nil:
return isNone return isNone
if doBind: if doBind:

View file

@ -1,12 +1,15 @@
discard """ discard """
cmd: "nim c --newruntime $file" cmd: "nim c --newruntime $file"
errormsg: "sink parameter `a` is already consumed at tconsume_twice.nim(8, 6)" errormsg: "sink parameter `a` is already consumed at tconsume_twice.nim(11, 10)"
line: 10 line: 13
""" """
type
Foo = ref object
proc consumeTwice(a: owned proc()): owned proc() = proc use(a: owned Foo): bool = discard
if a == nil: proc consumeTwice(a: owned Foo): owned Foo =
if use(a):
return return
return a return a
assert consumeTwice(proc() = discard) != nil assert consumeTwice(Foo()) != nil

View file

@ -62,6 +62,11 @@ proc main =
w.draw() w.draw()
# bug #11257
var a: owned proc()
if a != nil:
a()
main() main()
let (a, d) = allocCounters() let (a, d) = allocCounters()