summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-10-19 21:04:32 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-10-19 21:04:32 +0200
commit16a70c84aaabc27c25e48154e423b5f87f95bbd9 (patch)
treeda8b09901e43279021e214cd412d29a44dfb9dbb /compiler
parentd0dd5ea88719e9a85ab6e0708e5caee7caedd5e1 (diff)
downloadNim-16a70c84aaabc27c25e48154e423b5f87f95bbd9.tar.gz
Fixes 6544 (#9427)
* Fix call to converters with var/lent args

Fixes #6544

* Fix printing of lent types

* lent is only valid for result types
Diffstat (limited to 'compiler')
-rw-r--r--compiler/sigmatch.nim10
-rw-r--r--compiler/types.nim3
2 files changed, 12 insertions, 1 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 4fd4a3205..4dc7690ef 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -1826,9 +1826,12 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
     let srca = typeRel(m, src, a)
     if srca notin {isEqual, isGeneric, isSubtype}: continue
 
+    # What's done below matches the logic in ``matchesAux``
     let constraint = c.converters[i].typ.n[1].sym.constraint
     if not constraint.isNil and not matchNodeKinds(constraint, arg):
       continue
+    if src.kind in {tyVar, tyLent} and not arg.isLValue:
+      continue
 
     let destIsGeneric = containsGenericType(dest)
     if destIsGeneric:
@@ -1841,9 +1844,16 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
       s.info = arg.info
       result = newNodeIT(nkHiddenCallConv, arg.info, dest)
       addSon(result, s)
+      # We build the call expression by ourselves in order to avoid passing this
+      # expression trough the semantic check phase once again so let's make sure
+      # it is correct
       var param: PNode = nil
       if srca == isSubtype:
         param = implicitConv(nkHiddenSubConv, src, copyTree(arg), m, c)
+      elif src.kind == tyVar:
+        # Analyse the converter return type
+        param = newNodeIT(nkHiddenAddr, arg.info, s.typ[1])
+        param.addSon(copyTree(arg))
       else:
         param = copyTree(arg)
       addSon(result, param)
diff --git a/compiler/types.nim b/compiler/types.nim
index 485d3c369..05bae401c 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -397,7 +397,7 @@ const
     "float", "float32", "float64", "float128",
     "uint", "uint8", "uint16", "uint32", "uint64",
     "opt", "sink",
-    "lent", "varargs[$1]", "UncheckedArray[$1]", "Error Type",
+    "lent ", "varargs[$1]", "UncheckedArray[$1]", "Error Type",
     "BuiltInTypeClass", "UserTypeClass",
     "UserTypeClassInst", "CompositeTypeClass", "inferred",
     "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
@@ -1176,6 +1176,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
   case t.kind
   of tyVar, tyLent:
     if kind in {skProc, skFunc, skConst}: return t
+    elif t.kind == tyLent and kind != skResult: return t
     var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
     case t2.kind
     of tyVar, tyLent: