summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-04-11 12:35:03 +0200
committerAraq <rumpf_a@web.de>2019-04-11 12:35:49 +0200
commit1c0b1e9d051685b702b2fe61c0d87c5a36072f3c (patch)
tree07681d20a5ba3e011d23c985e60a1dac3b450516
parent8fb04b320adfe8f50ac2d7977d5dada5ca5fe30d (diff)
downloadNim-1c0b1e9d051685b702b2fe61c0d87c5a36072f3c.tar.gz
sem'check understands 'owned procs'
-rw-r--r--compiler/semexprs.nim22
-rw-r--r--compiler/semstmts.nim7
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")