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:
parent
ddc86d1b4b
commit
0a84b8fb4d
7 changed files with 53 additions and 9 deletions
|
|
@ -644,7 +644,7 @@ type
|
||||||
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
||||||
mNewString, mNewStringOfCap, mParseBiggestFloat,
|
mNewString, mNewStringOfCap, mParseBiggestFloat,
|
||||||
mMove, mWasMoved, mDestroy,
|
mMove, mWasMoved, mDestroy,
|
||||||
mDefault, mAccessEnv, mReset,
|
mDefault, mUnown, mAccessEnv, mReset,
|
||||||
mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs,
|
mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs,
|
||||||
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
|
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
|
||||||
mOrdinal,
|
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 mCharToStr: genDollar(p, e, d, "#nimCharToStr($1)")
|
||||||
of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
|
of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
|
||||||
of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($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:
|
of mEnumToStr:
|
||||||
if optNimV2 in p.config.globalOptions:
|
if optNimV2 in p.config.globalOptions:
|
||||||
genEnumToStr(p, e, d)
|
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 mInt64ToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
||||||
of mFloatToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
of mFloatToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
|
||||||
of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)")
|
of mCStrToStr: applyFormat("cstrToNimstr($1)", "cstrToNimstr($1)")
|
||||||
of mStrToStr: applyFormat("$1", "$1")
|
of mStrToStr, mUnown: applyFormat("$1", "$1")
|
||||||
else:
|
else:
|
||||||
assert false, $op
|
assert false, $op
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -322,6 +322,39 @@ proc semOf(c: PContext, n: PNode): PNode =
|
||||||
n.typ = getSysType(c.graph, n.info, tyBool)
|
n.typ = getSysType(c.graph, n.info, tyBool)
|
||||||
result = n
|
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,
|
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
flags: TExprFlags): PNode =
|
flags: TExprFlags): PNode =
|
||||||
## This is the preferred code point to implement magics.
|
## 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)
|
let t = n[1].typ.skipTypes(abstractVar)
|
||||||
if t.destructor != nil:
|
if t.destructor != nil:
|
||||||
result.sons[0] = newSymNode(t.destructor)
|
result.sons[0] = newSymNode(t.destructor)
|
||||||
|
of mUnown:
|
||||||
|
result = semUnown(c, n)
|
||||||
else: result = n
|
else: result = n
|
||||||
|
|
|
||||||
|
|
@ -471,10 +471,14 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
($typ.kind).substr(2).toLowerAscii)
|
($typ.kind).substr(2).toLowerAscii)
|
||||||
elif typ.kind == tyProc and tfUnresolved in typ.flags:
|
elif typ.kind == tyProc and tfUnresolved in typ.flags:
|
||||||
localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
|
localError(c.config, def.info, errProcHasNoConcreteType % def.renderTree)
|
||||||
elif symkind == skVar and typ.kind == tyOwned and def.kind notin nkCallKinds:
|
when false:
|
||||||
# special type inference rule: 'var it = ownedPointer' is turned
|
# XXX This typing rule is neither documented nor complete enough to
|
||||||
# into an unowned pointer.
|
# justify it. Instead use the newer 'unowned x' until we figured out
|
||||||
typ = typ.lastSon
|
# 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:
|
else:
|
||||||
if symkind == skLet: localError(c.config, a.info, errLetNeedsInit)
|
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.genNarrow(n.sons[1], d)
|
||||||
c.genAsgnPatch(n.sons[1], d)
|
c.genAsgnPatch(n.sons[1], d)
|
||||||
c.freeTemp(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:
|
of mNew, mNewFinalize:
|
||||||
unused(c, n, dest)
|
unused(c, n, dest)
|
||||||
c.genNew(n)
|
c.genNew(n)
|
||||||
|
|
|
||||||
|
|
@ -1619,7 +1619,7 @@ template `isnot`*(x, y: untyped): untyped = not (x is y)
|
||||||
## assert @[1, 2] isnot enum
|
## assert @[1, 2] isnot enum
|
||||||
|
|
||||||
when defined(nimV2) and not defined(nimscript):
|
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.}
|
proc new*[T](a: var owned(ref T)) {.magic: "New", noSideEffect.}
|
||||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
## 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)
|
var r: owned(ref t)
|
||||||
new(r)
|
new(r)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
proc unown*[T](x: T): T {.magic: "Unown", noSideEffect.}
|
||||||
|
## Use the expression ``x`` ignoring its ownership attribute.
|
||||||
|
|
||||||
else:
|
else:
|
||||||
template owned*(t: typeDesc): typedesc = t
|
template owned*(t: typeDesc): typedesc = t
|
||||||
|
template unown*(x: typed): typed = x
|
||||||
|
|
||||||
proc new*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
proc new*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||||
## Creates a new object of type ``T`` and returns a safe (traced)
|
## Creates a new object of type ``T`` and returns a safe (traced)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue