mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 05:20:31 +00:00
first steps in implementing 'owned' pointers; undocumented, do not use
This commit is contained in:
@@ -679,14 +679,14 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
||||
#if e[0].kind != nkBracketExpr:
|
||||
# message(e.info, warnUser, "CAME HERE " & renderTree(e))
|
||||
expr(p, e.sons[0], d)
|
||||
if e.sons[0].typ.skipTypes(abstractInst).kind == tyRef:
|
||||
if e.sons[0].typ.skipTypes(abstractInstOwned).kind == tyRef:
|
||||
d.storage = OnHeap
|
||||
else:
|
||||
var a: TLoc
|
||||
var typ = e.sons[0].typ
|
||||
if typ.kind in {tyUserTypeClass, tyUserTypeClassInst} and typ.isResolvedUserTypeClass:
|
||||
typ = typ.lastSon
|
||||
typ = typ.skipTypes(abstractInst)
|
||||
typ = typ.skipTypes(abstractInstOwned)
|
||||
if typ.kind == tyVar and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e.sons[0].kind == nkHiddenAddr:
|
||||
initLocExprSingleUse(p, e[0][0], d)
|
||||
return
|
||||
@@ -726,7 +726,7 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
||||
|
||||
proc genAddr(p: BProc, e: PNode, d: var TLoc) =
|
||||
# careful 'addr(myptrToArray)' needs to get the ampersand:
|
||||
if e.sons[0].typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
|
||||
if e.sons[0].typ.skipTypes(abstractInstOwned).kind in {tyRef, tyPtr}:
|
||||
var a: TLoc
|
||||
initLocExpr(p, e.sons[0], a)
|
||||
putIntoDest(p, d, e, "&" & a.r, a.storage)
|
||||
@@ -1158,7 +1158,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||
let typ = a.t
|
||||
var b: TLoc
|
||||
initLoc(b, locExpr, a.lode, OnHeap)
|
||||
let refType = typ.skipTypes(abstractInst)
|
||||
let refType = typ.skipTypes(abstractInstOwned)
|
||||
assert refType.kind == tyRef
|
||||
let bt = refType.lastSon
|
||||
if sizeExpr.isNil:
|
||||
|
||||
@@ -67,7 +67,7 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||
var p = c.p
|
||||
case typ.kind
|
||||
of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred,
|
||||
tySink:
|
||||
tySink, tyOwned:
|
||||
genTraverseProc(c, accessor, lastSon(typ))
|
||||
of tyArray:
|
||||
let arraySize = lengthOrd(c.p.config, typ.sons[0])
|
||||
@@ -134,7 +134,7 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
|
||||
var c: TTraversalClosure
|
||||
var p = newProc(nil, m)
|
||||
result = "Marker_" & getTypeName(m, origTyp, sig)
|
||||
var typ = origTyp.skipTypes(abstractInst)
|
||||
var typ = origTyp.skipTypes(abstractInstOwned)
|
||||
|
||||
let header = "static N_NIMCALL(void, $1)(void* p, NI op)" % [result]
|
||||
|
||||
@@ -149,7 +149,7 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
|
||||
if typ.kind == tySequence:
|
||||
genTraverseProcSeq(c, "a".rope, typ)
|
||||
else:
|
||||
if skipTypes(typ.sons[0], typedescInst).kind == tyArray:
|
||||
if skipTypes(typ.sons[0], typedescInst+{tyOwned}).kind == tyArray:
|
||||
# C's arrays are broken beyond repair:
|
||||
genTraverseProc(c, "a".rope, typ.sons[0])
|
||||
else:
|
||||
|
||||
@@ -115,7 +115,7 @@ proc getTypeName(m: BModule; typ: PType; sig: SigHash): Rope =
|
||||
t = t.lastSon
|
||||
else:
|
||||
break
|
||||
let typ = if typ.kind in {tyAlias, tySink}: typ.lastSon else: typ
|
||||
let typ = if typ.kind in {tyAlias, tySink, tyOwned}: typ.lastSon else: typ
|
||||
if typ.loc.r == nil:
|
||||
typ.loc.r = typ.typeName & $sig
|
||||
else:
|
||||
@@ -296,7 +296,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
||||
of tyStatic:
|
||||
if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ)
|
||||
else: internalError(m.config, "tyStatic for getSimpleTypeDesc")
|
||||
of tyGenericInst, tyAlias, tySink:
|
||||
of tyGenericInst, tyAlias, tySink, tyOwned:
|
||||
result = getSimpleTypeDesc(m, lastSon typ)
|
||||
else: result = nil
|
||||
|
||||
@@ -619,7 +619,7 @@ proc getSeqPayloadType(m: BModule; t: PType): Rope =
|
||||
|
||||
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||
# returns only the type's name
|
||||
var t = origTyp.skipTypes(irrelevantForBackend)
|
||||
var t = origTyp.skipTypes(irrelevantForBackend-{tyOwned})
|
||||
if containsOrIncl(check, t.id):
|
||||
if not (isImportedCppType(origTyp) or isImportedCppType(t)):
|
||||
internalError(m.config, "cannot generate C type for: " & typeToString(origTyp))
|
||||
|
||||
@@ -927,7 +927,7 @@ proc needsNoCopy(p: PProc; y: PNode): bool =
|
||||
return y.kind in nodeKindsNeedNoCopy or
|
||||
((mapType(y.typ) != etyBaseIndex or (y.kind == nkSym and y.sym.kind == skParam)) and
|
||||
(skipTypes(y.typ, abstractInst).kind in
|
||||
{tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes))
|
||||
{tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc, tyOwned} + IntegralTypes))
|
||||
|
||||
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||
var a, b: TCompRes
|
||||
@@ -1120,7 +1120,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
|
||||
proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr, tyLent}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr, tyLent, tyOwned}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||
case ty.kind
|
||||
of tyArray, tyOpenArray, tySequence, tyString, tyCString, tyVarargs:
|
||||
genArrayAddr(p, n, r)
|
||||
@@ -1340,7 +1340,8 @@ proc genArg(p: PProc, n: PNode, param: PSym, r: var TCompRes; emitted: ptr int =
|
||||
add(r.res, ", ")
|
||||
add(r.res, a.res)
|
||||
if emitted != nil: inc emitted[]
|
||||
elif n.typ.kind in {tyVar, tyPtr, tyRef, tyLent} and n.kind in nkCallKinds and mapType(param.typ) == etyBaseIndex:
|
||||
elif n.typ.kind in {tyVar, tyPtr, tyRef, tyLent, tyOwned} and
|
||||
n.kind in nkCallKinds and mapType(param.typ) == etyBaseIndex:
|
||||
# this fixes bug #5608:
|
||||
let tmp = getTemp(p)
|
||||
add(r.res, "($1 = $2, $1[0]), $1[1]" % [tmp, a.rdLoc])
|
||||
@@ -1540,7 +1541,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||
result = putToSeq("0", indirect)
|
||||
of tyFloat..tyFloat128:
|
||||
result = putToSeq("0.0", indirect)
|
||||
of tyRange, tyGenericInst, tyAlias, tySink:
|
||||
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned:
|
||||
result = createVar(p, lastSon(typ), indirect)
|
||||
of tySet:
|
||||
result = putToSeq("{}", indirect)
|
||||
@@ -1619,7 +1620,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||
|
||||
if n.kind == nkEmpty:
|
||||
if not isIndirect(v) and
|
||||
v.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and mapType(p, v.typ) == etyBaseIndex:
|
||||
v.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and mapType(p, v.typ) == etyBaseIndex:
|
||||
lineF(p, "var $1 = null;$n", [varName])
|
||||
lineF(p, "var $1_Idx = 0;$n", [varName])
|
||||
else:
|
||||
@@ -1807,7 +1808,8 @@ proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
|
||||
proc genOf(p: PProc, n: PNode, r: var TCompRes) =
|
||||
var x: TCompRes
|
||||
let t = skipTypes(n.sons[2].typ, abstractVarRange+{tyRef, tyPtr, tyLent, tyTypeDesc})
|
||||
let t = skipTypes(n.sons[2].typ,
|
||||
abstractVarRange+{tyRef, tyPtr, tyLent, tyTypeDesc, tyOwned})
|
||||
gen(p, n.sons[1], x)
|
||||
if tfFinal in t.flags:
|
||||
r.res = "($1.m_type == $2)" % [x.res, genTypeInfo(p, t)]
|
||||
@@ -2172,7 +2174,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||
resultSym = prc.ast.sons[resultPos].sym
|
||||
let mname = mangleName(p.module, resultSym)
|
||||
if not isindirect(resultSym) and
|
||||
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef} and
|
||||
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and
|
||||
mapType(p, resultSym.typ) == etyBaseIndex:
|
||||
resultAsgn = p.indentLine(("var $# = null;$n") % [mname])
|
||||
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
||||
|
||||
@@ -122,7 +122,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
|
||||
[name, genTypeInfo(p, typ.sons[0])])
|
||||
|
||||
proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink})
|
||||
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
|
||||
result = "NTI$1" % [rope(t.id)]
|
||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
||||
case t.kind
|
||||
|
||||
@@ -127,7 +127,7 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
|
||||
s = s.lastSon
|
||||
s = skipTypes(s, abstractVar-{tyTypeDesc})
|
||||
var pointers = 0
|
||||
while (d != nil) and (d.kind in {tyPtr, tyRef}) and (d.kind == s.kind):
|
||||
while (d != nil) and (d.kind in {tyPtr, tyRef, tyOwned}) and (d.kind == s.kind):
|
||||
d = d.lastSon
|
||||
s = s.lastSon
|
||||
inc pointers
|
||||
@@ -224,7 +224,7 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||
|
||||
maybeLiftType(targetType, c, n[0].info)
|
||||
|
||||
if targetType.kind in {tySink, tyLent}:
|
||||
if targetType.kind in {tySink, tyLent, tyOwned}:
|
||||
let baseType = semTypeNode(c, n.sons[1], nil).skipTypes({tyTypeDesc})
|
||||
let t = newTypeS(targetType.kind, c)
|
||||
t.rawAddSonNoPropagationOfTypeFlags baseType
|
||||
@@ -997,7 +997,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||
|
||||
const
|
||||
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
||||
tyDotOpTransparent = {tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink}
|
||||
tyDotOpTransparent = {tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink}
|
||||
|
||||
proc readTypeParameter(c: PContext, typ: PType,
|
||||
paramName: PIdent, info: TLineInfo): PNode =
|
||||
@@ -1150,7 +1150,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||
p = p.next
|
||||
if p != nil and p.selfSym != nil:
|
||||
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef,
|
||||
tyAlias, tySink})
|
||||
tyAlias, tySink, tyOwned})
|
||||
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
|
||||
var check: PNode = nil
|
||||
if ty.kind == tyObject:
|
||||
@@ -1282,7 +1282,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
return nil
|
||||
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
|
||||
ty = ty.lastSon
|
||||
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink})
|
||||
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct})
|
||||
var check: PNode = nil
|
||||
if ty.kind == tyObject:
|
||||
@@ -1353,7 +1353,7 @@ proc semDeref(c: PContext, n: PNode): PNode =
|
||||
checkSonsLen(n, 1, c.config)
|
||||
n.sons[0] = semExprWithType(c, n.sons[0])
|
||||
result = n
|
||||
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink})
|
||||
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink, tyOwned})
|
||||
case t.kind
|
||||
of tyRef, tyPtr: n.typ = t.lastSon
|
||||
else: result = nil
|
||||
@@ -1372,7 +1372,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
# make sure we don't evaluate generic macros/templates
|
||||
n.sons[0] = semExprWithType(c, n.sons[0],
|
||||
{efNoEvaluateGeneric})
|
||||
var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyUserTypeClassInst,
|
||||
var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyUserTypeClassInst, tyOwned,
|
||||
tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||
if arr.kind == tyStatic:
|
||||
if arr.base.kind == tyNone:
|
||||
|
||||
@@ -391,18 +391,18 @@ proc makeDeref(n: PNode): PNode =
|
||||
var t = n.typ
|
||||
if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass:
|
||||
t = t.lastSon
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias, tySink})
|
||||
t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned})
|
||||
result = n
|
||||
if t.kind in {tyVar, tyLent}:
|
||||
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
|
||||
addSon(result, n)
|
||||
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink})
|
||||
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink, tyOwned})
|
||||
while t.kind in {tyPtr, tyRef}:
|
||||
var a = result
|
||||
let baseTyp = t.lastSon
|
||||
result = newNodeIT(nkHiddenDeref, n.info, baseTyp)
|
||||
addSon(result, a)
|
||||
t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink})
|
||||
t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink, tyOwned})
|
||||
|
||||
proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
||||
if n.len == 2:
|
||||
@@ -908,7 +908,7 @@ proc semRaise(c: PContext, n: PNode): PNode =
|
||||
n[0] = semExprWithType(c, n[0])
|
||||
var typ = n[0].typ
|
||||
if not isImportedException(typ, c.config):
|
||||
typ = typ.skipTypes({tyAlias, tyGenericInst})
|
||||
typ = typ.skipTypes({tyAlias, tyGenericInst, tyOwned})
|
||||
if typ.kind != tyRef:
|
||||
localError(c.config, n.info, errExprCannotBeRaised)
|
||||
if typ.len > 0 and not isException(typ.lastSon):
|
||||
@@ -1059,7 +1059,7 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
|
||||
of tyPtr, tyRef, tyVar, tyLent:
|
||||
if t.base.kind == tyGenericParam: return true
|
||||
return traverseSubTypes(c, t.base)
|
||||
of tyDistinct, tyAlias, tySink:
|
||||
of tyDistinct, tyAlias, tySink, tyOwned:
|
||||
return traverseSubTypes(c, t.lastSon)
|
||||
of tyGenericInst:
|
||||
internalAssert c.config, false
|
||||
@@ -1180,7 +1180,7 @@ proc checkForMetaFields(c: PContext; n: PNode) =
|
||||
let t = n.sym.typ
|
||||
case t.kind
|
||||
of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyLent, tyPtr, tyRef,
|
||||
tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink:
|
||||
tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink, tyOwned:
|
||||
let start = ord(t.kind in {tyGenericInvocation, tyGenericInst})
|
||||
for i in start ..< t.len:
|
||||
checkMeta(c, n, t.sons[i])
|
||||
@@ -1636,7 +1636,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
||||
if t != nil and t.kind == tyGenericInvocation:
|
||||
var x = skipTypes(t.sons[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst,
|
||||
tyGenericInvocation, tyGenericBody,
|
||||
tyAlias, tySink})
|
||||
tyAlias, tySink, tyOwned})
|
||||
if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len:
|
||||
foundObj = true
|
||||
x.methods.add((col,s))
|
||||
|
||||
@@ -750,7 +750,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} =
|
||||
result = t
|
||||
if result.kind == tyGenericInvocation:
|
||||
result = result.sons[0]
|
||||
while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias, tySink}:
|
||||
while result.kind in {tyGenericInst, tyGenericBody, tyRef, tyPtr, tyAlias, tySink, tyOwned}:
|
||||
result = lastSon(result)
|
||||
|
||||
proc addInheritedFields(c: PContext, check: var IntSet, pos: var int,
|
||||
@@ -955,7 +955,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
# disable the bindOnce behavior for the type class
|
||||
result = liftingWalk(paramType.base, true)
|
||||
|
||||
of tyAlias:
|
||||
of tyAlias, tyOwned:
|
||||
result = liftingWalk(paramType.base)
|
||||
|
||||
of tySequence, tySet, tyArray, tyOpenArray,
|
||||
@@ -1528,7 +1528,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = semRangeAux(c, n, prev)
|
||||
elif n[0].kind == nkNilLit and n.len == 2:
|
||||
result = semTypeNode(c, n.sons[1], prev)
|
||||
if result.skipTypes({tyGenericInst, tyAlias, tySink}).kind in NilableTypes+GenericTypes:
|
||||
if result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).kind in NilableTypes+GenericTypes:
|
||||
if tfNotNil in result.flags:
|
||||
result = freshType(result, prev)
|
||||
result.flags.excl(tfNotNil)
|
||||
@@ -1556,7 +1556,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
case n.len
|
||||
of 3:
|
||||
result = semTypeNode(c, n.sons[1], prev)
|
||||
if result.skipTypes({tyGenericInst, tyAlias, tySink}).kind in NilableTypes+GenericTypes+{tyForward} and
|
||||
if result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).kind in NilableTypes+GenericTypes+{tyForward} and
|
||||
n.sons[2].kind == nkNilLit:
|
||||
result = freshType(result, prev)
|
||||
result.flags.incl(tfNotNil)
|
||||
|
||||
@@ -574,7 +574,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
var r = replaceTypeVarsT(cl, result.sons[i])
|
||||
if result.kind == tyObject:
|
||||
# carefully coded to not skip the precious tyGenericInst:
|
||||
let r2 = r.skipTypes({tyAlias, tySink})
|
||||
let r2 = r.skipTypes({tyAlias, tySink, tyOwned})
|
||||
if r2.kind in {tyPtr, tyRef}:
|
||||
r = skipTypes(r2, {tyPtr, tyRef})
|
||||
result.sons[i] = r
|
||||
|
||||
@@ -165,7 +165,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||
c.hashType t.sons[i], flags
|
||||
else:
|
||||
c.hashType t.lastSon, flags
|
||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
|
||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred, tyOwned:
|
||||
c.hashType t.lastSon, flags
|
||||
of tyBool, tyChar, tyInt..tyUInt64:
|
||||
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
||||
|
||||
@@ -188,7 +188,7 @@ proc sumGeneric(t: PType): int =
|
||||
case t.kind
|
||||
of tyGenericInst, tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray,
|
||||
tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyGenericBody,
|
||||
tyLent:
|
||||
tyLent, tyOwned:
|
||||
t = t.lastSon
|
||||
inc result
|
||||
of tyOr:
|
||||
@@ -476,7 +476,7 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
|
||||
inc ptrs
|
||||
skipped = skippedPtr
|
||||
r = r.lastSon
|
||||
of tyGenericBody, tyGenericInst, tyAlias, tySink:
|
||||
of tyGenericBody, tyGenericInst, tyAlias, tySink, tyOwned:
|
||||
r = r.lastSon
|
||||
else:
|
||||
break
|
||||
@@ -919,7 +919,8 @@ proc inferStaticsInRange(c: var TCandidate,
|
||||
doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(c.c.config, concrete))
|
||||
|
||||
template subtypeCheck() =
|
||||
if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
||||
if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in {
|
||||
tyRef, tyPtr, tyVar, tyLent, tyOwned}:
|
||||
result = isNone
|
||||
|
||||
proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
|
||||
@@ -927,11 +928,11 @@ proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
|
||||
assert f.kind == a.kind
|
||||
|
||||
template baseTypesCheck(lhs, rhs: PType): bool =
|
||||
lhs.kind notin {tyPtr, tyRef, tyVar, tyLent} and
|
||||
lhs.kind notin {tyPtr, tyRef, tyVar, tyLent, tyOwned} and
|
||||
typeRel(c, lhs, rhs, {trNoCovariance}) == isSubtype
|
||||
|
||||
case f.kind
|
||||
of tyRef, tyPtr:
|
||||
of tyRef, tyPtr, tyOwned:
|
||||
return baseTypesCheck(f.base, a.base)
|
||||
of tyGenericInst:
|
||||
let body = f.base
|
||||
@@ -962,6 +963,9 @@ when false:
|
||||
of tyFloat64: greater({tyFloat128})
|
||||
else: discard
|
||||
|
||||
template skipOwned(a) =
|
||||
if a.kind == tyOwned: a = a.skipTypes({tyOwned, tyGenericInst})
|
||||
|
||||
proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
flags: TTypeRelFlags = {}): TTypeRelation =
|
||||
# typeRel can be used to establish various relationships between types:
|
||||
@@ -1279,6 +1283,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
#internalError("forward type in typeRel()")
|
||||
result = isNone
|
||||
of tyNil:
|
||||
skipOwned(a)
|
||||
if a.kind == f.kind: result = isEqual
|
||||
of tyTuple:
|
||||
if a.kind == tyTuple: result = recordRel(c, f, a)
|
||||
@@ -1298,7 +1303,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
#elif f.base.kind == tyAnything: result = isGeneric # issue 4435
|
||||
elif c.coerceDistincts: result = typeRel(c, f.base, a)
|
||||
elif a.kind == tyNil and f.base.kind in NilableTypes:
|
||||
result = f.allowsNil
|
||||
result = f.allowsNil # XXX remove this typing rule, it is not in the spec
|
||||
elif c.coerceDistincts: result = typeRel(c, f.base, a)
|
||||
of tySet:
|
||||
if a.kind == tySet:
|
||||
@@ -1309,6 +1314,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
if result <= isConvertible:
|
||||
result = isNone # BUGFIX!
|
||||
of tyPtr, tyRef:
|
||||
skipOwned(a)
|
||||
if a.kind == f.kind:
|
||||
# ptr[R, T] can be passed to ptr[T], but not the other way round:
|
||||
if a.len < f.len: return isNone
|
||||
@@ -1322,10 +1328,18 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
elif a.kind == tyNil: result = f.allowsNil
|
||||
else: discard
|
||||
of tyProc:
|
||||
skipOwned(a)
|
||||
result = procTypeRel(c, f, a)
|
||||
if result != isNone and tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
result = isNilConversion
|
||||
of tyOwned:
|
||||
case a.kind
|
||||
of tyOwned:
|
||||
result = typeRel(c, lastSon(f), lastSon(a))
|
||||
of tyNil: result = f.allowsNil
|
||||
else: discard
|
||||
of tyPointer:
|
||||
skipOwned(a)
|
||||
case a.kind
|
||||
of tyPointer:
|
||||
if tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
@@ -1917,8 +1931,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||
# this will be done earlier - we just have to
|
||||
# make sure that static types enter here
|
||||
|
||||
# XXX: weaken tyGenericParam and call it tyGenericPlaceholder
|
||||
# Zahary: weaken tyGenericParam and call it tyGenericPlaceholder
|
||||
# and finally start using tyTypedesc for generic types properly.
|
||||
# Araq: This would only shift the problems around, in 'proc p[T](x: T)'
|
||||
# the T is NOT a typedesc.
|
||||
if a.kind == tyGenericParam and tfWildcard in a.flags:
|
||||
a.assignType(f)
|
||||
# put(m.bindings, f, a)
|
||||
|
||||
@@ -52,20 +52,21 @@ const
|
||||
# TODO: Remove tyTypeDesc from each abstractX and (where necessary)
|
||||
# replace with typedescX
|
||||
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal,
|
||||
tyTypeDesc, tyAlias, tyInferred, tySink, tyLent}
|
||||
tyTypeDesc, tyAlias, tyInferred, tySink, tyLent, tyOwned}
|
||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||
tyAlias, tyInferred, tySink, tyLent}
|
||||
tyAlias, tyInferred, tySink, tyLent, tyOwned}
|
||||
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyTypeDesc,
|
||||
tyAlias, tyInferred, tySink}
|
||||
tyAlias, tyInferred, tySink, tyOwned}
|
||||
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
|
||||
tyTypeDesc, tyAlias, tyInferred, tySink}
|
||||
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias,
|
||||
tyInferred, tySink}
|
||||
abstractInstOwned* = abstractInst + {tyOwned}
|
||||
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyTypeDesc, tyAlias,
|
||||
tyInferred, tySink, tyLent}
|
||||
tyInferred, tySink, tyLent, tyOwned}
|
||||
# typedescX is used if we're sure tyTypeDesc should be included (or skipped)
|
||||
typedescPtrs* = abstractPtrs + {tyTypeDesc}
|
||||
typedescInst* = abstractInst + {tyTypeDesc}
|
||||
typedescInst* = abstractInst + {tyTypeDesc, tyOwned}
|
||||
|
||||
type
|
||||
TTypeFieldResult* = enum
|
||||
@@ -323,7 +324,7 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
|
||||
result = false
|
||||
if typ == nil: return
|
||||
if tfAcyclic in typ.flags: return
|
||||
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
||||
var t = skipTypes(typ, abstractInst+{tyOwned}-{tyTypeDesc})
|
||||
if tfAcyclic in t.flags: return
|
||||
case t.kind
|
||||
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyOpenArray, tyVarargs:
|
||||
@@ -399,8 +400,8 @@ const
|
||||
"int", "int8", "int16", "int32", "int64",
|
||||
"float", "float32", "float64", "float128",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
"opt", "sink",
|
||||
"lent ", "varargs[$1]", "UncheckedArray[$1]", "Error Type",
|
||||
"owned", "sink",
|
||||
"lent", "varargs[$1]", "UncheckedArray[$1]", "Error Type",
|
||||
"BuiltInTypeClass", "UserTypeClass",
|
||||
"UserTypeClassInst", "CompositeTypeClass", "inferred",
|
||||
"and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor",
|
||||
@@ -622,6 +623,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
result = typeToStr[t.kind] % typeToString(t.sons[0])
|
||||
of tySink:
|
||||
result = "sink " & typeToString(t.sons[0])
|
||||
of tyOwned:
|
||||
result = "owned " & typeToString(t.sons[0])
|
||||
else:
|
||||
result = typeToStr[t.kind]
|
||||
result.addTypeFlags(t)
|
||||
@@ -1328,7 +1331,7 @@ proc baseOfDistinct*(t: PType): PType =
|
||||
result = copyType(t, t.owner, false)
|
||||
var parent: PType = nil
|
||||
var it = result
|
||||
while it.kind in {tyPtr, tyRef}:
|
||||
while it.kind in {tyPtr, tyRef, tyOwned}:
|
||||
parent = it
|
||||
it = it.lastSon
|
||||
if it.kind == tyDistinct and parent != nil:
|
||||
|
||||
Reference in New Issue
Block a user