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
This commit is contained in:
LemonBoy
2018-10-19 21:04:32 +02:00
committed by Andreas Rumpf
parent d0dd5ea887
commit 16a70c84aa
3 changed files with 20 additions and 1 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -18,3 +18,11 @@ converter toPtr*(some: var TFoo): ptr TFoo = (addr some)
proc zoot(x: ptr TFoo) = discard
var x: Tfoo
zoot(x)
# issue #6544
converter withVar(b: var string): int = ord(b[1])
block:
var x = "101"
var y: int = x # instantiate withVar
doAssert(y == ord('0'))