sem'check understands 'owned procs'

This commit is contained in:
Araq 2019-04-11 12:35:03 +02:00
commit 1c0b1e9d05
2 changed files with 22 additions and 7 deletions

View file

@ -125,11 +125,18 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
var s = src var s = src
if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass: if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass:
s = s.lastSon s = s.lastSon
s = skipTypes(s, abstractVar-{tyTypeDesc}) s = skipTypes(s, abstractVar-{tyTypeDesc, tyOwned})
var pointers = 0 if s.kind == tyOwned and d.kind != tyOwned:
while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}) and (d.kind == s.kind):
d = d.lastSon
s = s.lastSon s = s.lastSon
var pointers = 0
while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}):
if s.kind == tyOwned and d.kind != tyOwned:
s = s.lastSon
elif d.kind != s.kind:
break
else:
d = d.lastSon
s = s.lastSon
inc pointers inc pointers
if d == nil: if d == nil:
result = convNotLegal result = convNotLegal
@ -143,7 +150,7 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
# we use d, s here to speed up that operation a bit: # we use d, s here to speed up that operation a bit:
case cmpTypes(c, d, s) case cmpTypes(c, d, s)
of isNone, isGeneric: of isNone, isGeneric:
if not compareTypes(castDest.skipTypes(abstractVar), src, dcEqIgnoreDistinct): if not compareTypes(castDest.skipTypes(abstractVar), src.skipTypes({tyOwned}), dcEqIgnoreDistinct):
result = convNotLegal result = convNotLegal
else: else:
discard discard
@ -851,7 +858,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
semOpAux(c, n) semOpAux(c, n)
var t: PType = nil var t: PType = nil
if n.sons[0].typ != nil: if n.sons[0].typ != nil:
t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}) t = skipTypes(n.sons[0].typ, abstractInst+{tyOwned}-{tyTypeDesc})
if t != nil and t.kind == tyProc: if t != nil and t.kind == tyProc:
# This is a proc variable, apply normal overload resolution # This is a proc variable, apply normal overload resolution
let m = resolveIndirectCall(c, n, nOrig, t) let m = resolveIndirectCall(c, n, nOrig, t)
@ -2421,6 +2428,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
markIndirect(c, result.sym) markIndirect(c, result.sym)
# if isGenericRoutine(result.sym): # if isGenericRoutine(result.sym):
# localError(c.config, n.info, errInstantiateXExplicitly, s.name.s) # localError(c.config, n.info, errInstantiateXExplicitly, s.name.s)
# "procs literals" are 'owned'
if optNimV2 in c.config.globalOptions:
result.typ = makeVarType(c, result.typ, tyOwned)
else: else:
result = semSym(c, n, s, flags) result = semSym(c, n, s, flags)
of nkSym: of nkSym:

View file

@ -1486,6 +1486,8 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
closeScope(c) # close scope for parameters closeScope(c) # close scope for parameters
popOwner(c) popOwner(c)
result.typ = s.typ result.typ = s.typ
if optNimV2 in c.config.globalOptions:
result.typ = makeVarType(c, result.typ, tyOwned)
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
var n = n var n = n
@ -1521,7 +1523,8 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
popProcCon(c) popProcCon(c)
popOwner(c) popOwner(c)
closeScope(c) closeScope(c)
if optNimV2 in c.config.globalOptions and result.typ != nil:
result.typ = makeVarType(c, result.typ, tyOwned)
# alternative variant (not quite working): # alternative variant (not quite working):
# var prc = arg[0].sym # var prc = arg[0].sym
# let inferred = c.semGenerateInstance(c, prc, m.bindings, arg.info) # let inferred = c.semGenerateInstance(c, prc, m.bindings, arg.info)
@ -1900,6 +1903,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if isAnon: if isAnon:
n.kind = nkLambda n.kind = nkLambda
result.typ = s.typ result.typ = s.typ
if optNimV2 in c.config.globalOptions:
result.typ = makeVarType(c, result.typ, tyOwned)
if isTopLevel(c) and s.kind != skIterator and if isTopLevel(c) and s.kind != skIterator and
s.typ.callConv == ccClosure: s.typ.callConv == ccClosure:
localError(c.config, s.info, "'.closure' calling convention for top level routines is invalid") localError(c.config, s.info, "'.closure' calling convention for top level routines is invalid")