mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
added system.unown to make 'owned' sane to use in practice; later on we might change the type inference rules to make it more convenient
This commit is contained in:
@@ -644,7 +644,7 @@ type
|
||||
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
||||
mNewString, mNewStringOfCap, mParseBiggestFloat,
|
||||
mMove, mWasMoved, mDestroy,
|
||||
mDefault, mAccessEnv, mReset,
|
||||
mDefault, mUnown, mAccessEnv, mReset,
|
||||
mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs,
|
||||
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
|
||||
mOrdinal,
|
||||
|
||||
@@ -2179,7 +2179,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
of mCharToStr: genDollar(p, e, d, "#nimCharToStr($1)")
|
||||
of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
|
||||
of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
|
||||
of mStrToStr: expr(p, e.sons[1], d)
|
||||
of mStrToStr, mUnown: expr(p, e.sons[1], d)
|
||||
of mEnumToStr:
|
||||
if optNimV2 in p.config.globalOptions:
|
||||
genEnumToStr(p, e, d)
|
||||
|
||||
@@ -640,7 +640,7 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||
of mInt64ToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
||||
of mFloatToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
||||
of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)")
|
||||
of mStrToStr: applyFormat("$1", "$1")
|
||||
of mStrToStr, mUnown: applyFormat("$1", "$1")
|
||||
else:
|
||||
assert false, $op
|
||||
|
||||
|
||||
@@ -322,6 +322,39 @@ proc semOf(c: PContext, n: PNode): PNode =
|
||||
n.typ = getSysType(c.graph, n.info, tyBool)
|
||||
result = n
|
||||
|
||||
proc semUnown(c: PContext; n: PNode): PNode =
|
||||
proc unownedType(c: PContext; t: PType): PType =
|
||||
case t.kind
|
||||
of tyTuple:
|
||||
var elems = newSeq[PType](t.len)
|
||||
var someChange = false
|
||||
for i in 0..<t.len:
|
||||
elems[i] = unownedType(c, t[i])
|
||||
if elems[i] != t[i]: someChange = true
|
||||
if someChange:
|
||||
result = newType(tyTuple, t.owner)
|
||||
# we have to use 'rawAddSon' here so that type flags are
|
||||
# properly computed:
|
||||
for e in elems: result.rawAddSon(e)
|
||||
else:
|
||||
result = t
|
||||
of tyOwned: result = t.sons[0]
|
||||
of tySequence, tyOpenArray, tyArray, tyVarargs, tyVar, tyLent,
|
||||
tyGenericInst, tyAlias:
|
||||
let L = t.len-1
|
||||
let b = unownedType(c, t[L])
|
||||
if b != t[L]:
|
||||
result = copyType(t, t.owner, keepId = false)
|
||||
result[L] = b
|
||||
result.flags.excl tfHasOwned
|
||||
else:
|
||||
result = t
|
||||
else:
|
||||
result = t
|
||||
|
||||
result = copyTree(n[1])
|
||||
result.typ = unownedType(c, result.typ)
|
||||
|
||||
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
flags: TExprFlags): PNode =
|
||||
## This is the preferred code point to implement magics.
|
||||
@@ -433,4 +466,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
let t = n[1].typ.skipTypes(abstractVar)
|
||||
if t.destructor != nil:
|
||||
result.sons[0] = newSymNode(t.destructor)
|
||||
of mUnown:
|
||||
result = semUnown(c, n)
|
||||
else: result = n
|
||||
|
||||
@@ -471,10 +471,14 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
($typ.kind).substr(2).toLowerAscii)
|
||||
elif typ.kind == tyProc and tfUnresolved in typ.flags:
|
||||
localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
|
||||
elif symkind == skVar and typ.kind == tyOwned and def.kind notin nkCallKinds:
|
||||
# special type inference rule: 'var it = ownedPointer' is turned
|
||||
# into an unowned pointer.
|
||||
typ = typ.lastSon
|
||||
when false:
|
||||
# XXX This typing rule is neither documented nor complete enough to
|
||||
# justify it. Instead use the newer 'unowned x' until we figured out
|
||||
# a more general solution.
|
||||
if symkind == skVar and typ.kind == tyOwned and def.kind notin nkCallKinds:
|
||||
# special type inference rule: 'var it = ownedPointer' is turned
|
||||
# into an unowned pointer.
|
||||
typ = typ.lastSon
|
||||
else:
|
||||
if symkind == skLet: localError(c.config, a.info, errLetNeedsInit)
|
||||
|
||||
|
||||
@@ -957,7 +957,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||
c.genNarrow(n.sons[1], d)
|
||||
c.genAsgnPatch(n.sons[1], d)
|
||||
c.freeTemp(d)
|
||||
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
|
||||
of mOrd, mChr, mArrToSeq, mUnown: c.gen(n.sons[1], dest)
|
||||
of mNew, mNewFinalize:
|
||||
unused(c, n, dest)
|
||||
c.genNew(n)
|
||||
|
||||
@@ -1619,7 +1619,7 @@ template `isnot`*(x, y: untyped): untyped = not (x is y)
|
||||
## assert @[1, 2] isnot enum
|
||||
|
||||
when defined(nimV2) and not defined(nimscript):
|
||||
type owned*{.magic: "BuiltinType".}[T]
|
||||
type owned*{.magic: "BuiltinType".}[T] ## type constructor to mark a ref/ptr or a closure as `owned`.
|
||||
|
||||
proc new*[T](a: var owned(ref T)) {.magic: "New", noSideEffect.}
|
||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||
@@ -1637,8 +1637,13 @@ when defined(nimV2) and not defined(nimscript):
|
||||
var r: owned(ref t)
|
||||
new(r)
|
||||
return r
|
||||
|
||||
proc unown*[T](x: T): T {.magic: "Unown", noSideEffect.}
|
||||
## Use the expression ``x`` ignoring its ownership attribute.
|
||||
|
||||
else:
|
||||
template owned*(t: typeDesc): typedesc = t
|
||||
template unown*(x: typed): typed = x
|
||||
|
||||
proc new*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||
|
||||
Reference in New Issue
Block a user