diff options
author | Araq <rumpf_a@web.de> | 2019-04-11 12:35:03 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2019-04-11 12:35:49 +0200 |
commit | 1c0b1e9d051685b702b2fe61c0d87c5a36072f3c (patch) | |
tree | 07681d20a5ba3e011d23c985e60a1dac3b450516 | |
parent | 8fb04b320adfe8f50ac2d7977d5dada5ca5fe30d (diff) | |
download | Nim-1c0b1e9d051685b702b2fe61c0d87c5a36072f3c.tar.gz |
sem'check understands 'owned procs'
-rw-r--r-- | compiler/semexprs.nim | 22 | ||||
-rw-r--r-- | compiler/semstmts.nim | 7 |
2 files changed, 22 insertions, 7 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 9e3e5e076..f39603c0e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -125,11 +125,18 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus = var s = src if s.kind in tyUserTypeClasses and s.isResolvedUserTypeClass: s = s.lastSon - s = skipTypes(s, abstractVar-{tyTypeDesc}) - var pointers = 0 - while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}) and (d.kind == s.kind): - d = d.lastSon + s = skipTypes(s, abstractVar-{tyTypeDesc, tyOwned}) + if s.kind == tyOwned and d.kind != tyOwned: 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 if d == nil: 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: case cmpTypes(c, d, s) of isNone, isGeneric: - if not compareTypes(castDest.skipTypes(abstractVar), src, dcEqIgnoreDistinct): + if not compareTypes(castDest.skipTypes(abstractVar), src.skipTypes({tyOwned}), dcEqIgnoreDistinct): result = convNotLegal else: discard @@ -851,7 +858,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = semOpAux(c, n) var t: PType = 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: # This is a proc variable, apply normal overload resolution let m = resolveIndirectCall(c, n, nOrig, t) @@ -2421,6 +2428,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = markIndirect(c, result.sym) # if isGenericRoutine(result.sym): # 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: result = semSym(c, n, s, flags) of nkSym: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 93af6ddbb..fe43c0c36 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1486,6 +1486,8 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = closeScope(c) # close scope for parameters popOwner(c) 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 = var n = n @@ -1521,7 +1523,8 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = popProcCon(c) popOwner(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): # var prc = arg[0].sym # let inferred = c.semGenerateInstance(c, prc, m.bindings, arg.info) @@ -1900,6 +1903,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if isAnon: n.kind = nkLambda 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 s.typ.callConv == ccClosure: localError(c.config, s.info, "'.closure' calling convention for top level routines is invalid") |