added system.default in order to prevent the abstraction inversion that 'template default(T): untyped = (var x: T; x)' causes

This commit is contained in:
Andreas Rumpf 2019-03-05 09:54:59 +01:00
commit 142a2d3551
7 changed files with 50 additions and 11 deletions

View file

@ -130,6 +130,7 @@ proc enumToString*(enums: openArray[enum]): string =
- Added the `posix_utils` module. - Added the `posix_utils` module.
- Added `system.default`.
### Library changes ### Library changes

View file

@ -635,7 +635,7 @@ type
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
mNewString, mNewStringOfCap, mParseBiggestFloat, mNewString, mNewStringOfCap, mParseBiggestFloat,
mMove, mWasMoved, mDestroy, mMove, mWasMoved, mDestroy,
mReset, mDefault, 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,

View file

@ -1153,6 +1153,9 @@ proc genReset(p: BProc, n: PNode) =
addrLoc(p.config, a), addrLoc(p.config, a),
genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)) genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info))
proc genDefault(p: BProc; n: PNode; d: var TLoc) =
resetLoc(p, d)
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
var sizeExpr = sizeExpr var sizeExpr = sizeExpr
let typ = a.t let typ = a.t
@ -2063,6 +2066,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
addf(p.module.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n", addf(p.module.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
[mangleDynLibProc(prc), getTypeDesc(p.module, prc.loc.t), getModuleDllPath(p.module, prc)]) [mangleDynLibProc(prc), getTypeDesc(p.module, prc.loc.t), getModuleDllPath(p.module, prc)])
genCall(p, e, d) genCall(p, e, d)
of mDefault: genDefault(p, e, d)
of mReset: genReset(p, e) of mReset: genReset(p, e)
of mEcho: genEcho(p, e[1].skipConv) of mEcho: genEcho(p, e[1].skipConv)
of mArrToSeq: genArrToSeq(p, e, d) of mArrToSeq: genArrToSeq(p, e, d)

View file

@ -85,6 +85,7 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasHotCodeReloading") defineSymbol("nimHasHotCodeReloading")
defineSymbol("nimHasNilSeqs") defineSymbol("nimHasNilSeqs")
defineSymbol("nimHasSignatureHashInMacro") defineSymbol("nimHasSignatureHashInMacro")
defineSymbol("nimHasDefault")
for f in low(Feature)..high(Feature): for f in low(Feature)..high(Feature):
defineSymbol("nimHas" & $f) defineSymbol("nimHas" & $f)

View file

@ -910,6 +910,15 @@ proc genBindSym(c: PCtx; n: PNode; dest: var TDest) =
c.gABC(n, opcNDynBindSym, dest, x, n.len) c.gABC(n, opcNDynBindSym, dest, x, n.len)
c.freeTempRange(x, n.len) c.freeTempRange(x, n.len)
proc fitsRegister*(t: PType): bool =
assert t != nil
t.skipTypes(abstractInst-{tyTypeDesc}).kind in {
tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar}
proc ldNullOpcode(t: PType): TOpcode =
assert t != nil
if fitsRegister(t): opcLdNullReg else: opcLdNull
proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
case m case m
of mAnd: c.genAndOr(n, opcFJmp, dest) of mAnd: c.genAndOr(n, opcFJmp, dest)
@ -1129,9 +1138,13 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mReset: of mReset:
unused(c, n, dest) unused(c, n, dest)
var d = c.genx(n.sons[1]) var d = c.genx(n.sons[1])
# XXX use ldNullOpcode() here?
c.gABx(n, opcLdNull, d, c.genType(n.sons[1].typ)) c.gABx(n, opcLdNull, d, c.genType(n.sons[1].typ))
c.gABx(n, opcNodeToReg, d, d) c.gABx(n, opcNodeToReg, d, d)
c.genAsgnPatch(n.sons[1], d) c.genAsgnPatch(n.sons[1], d)
of mDefault:
if dest < 0: dest = c.getTemp(n.typ)
c.gABx(n, ldNullOpcode(n.typ), dest, c.genType(n.typ))
of mOf, mIs: of mOf, mIs:
if dest < 0: dest = c.getTemp(n.typ) if dest < 0: dest = c.getTemp(n.typ)
var tmp = c.genx(n.sons[1]) var tmp = c.genx(n.sons[1])
@ -1332,11 +1345,6 @@ const
tyFloat, tyFloat32, tyFloat64, tyFloat128, tyFloat, tyFloat32, tyFloat64, tyFloat128,
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64} tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64}
proc fitsRegister*(t: PType): bool =
assert t != nil
t.skipTypes(abstractInst-{tyTypeDesc}).kind in {
tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar}
proc unneededIndirection(n: PNode): bool = proc unneededIndirection(n: PNode): bool =
n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef
@ -1766,10 +1774,6 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode =
globalError(conf, info, "cannot create null element for: " & $t.kind) globalError(conf, info, "cannot create null element for: " & $t.kind)
result = newNodeI(nkEmpty, info) result = newNodeI(nkEmpty, info)
proc ldNullOpcode(t: PType): TOpcode =
assert t != nil
if fitsRegister(t): opcLdNullReg else: opcLdNull
proc genVarSection(c: PCtx; n: PNode) = proc genVarSection(c: PCtx; n: PNode) =
for a in n: for a in n:
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue

View file

@ -4278,6 +4278,10 @@ proc `$`*(t: typedesc): string {.magic: "TypeTrait".} =
doAssert $(type("Foo")) == "string" doAssert $(type("Foo")) == "string"
static: doAssert $(type(@['A', 'B'])) == "seq[char]" static: doAssert $(type(@['A', 'B'])) == "seq[char]"
when defined(nimHasDefault):
proc default*(T: typedesc): T {.magic: "Default", noSideEffect.}
## returns the default value of the type ``T``.
import system/widestrs import system/widestrs
export widestrs export widestrs

View file

@ -1,3 +1,6 @@
discard """
output: '''0'''
"""
static: static:
type Obj = object type Obj = object
field: int field: int
@ -5,6 +8,17 @@ static:
reset(o) reset(o)
doAssert o.field == 0 doAssert o.field == 0
var x = 4
reset(x)
doAssert x == 0
static:
type ObjB = object
field: int
var o = ObjB(field: 1)
o = default(ObjB)
doAssert o.field == 0
static: static:
var i = 2 var i = 2
reset(i) reset(i)
@ -26,3 +40,14 @@ static:
reset(i) reset(i)
doAssert i == 0 doAssert i == 0
f() f()
proc main =
var y = [1, 2, 3, 4]
y = default(array[4, int])
for a in y: doAssert(a == 0)
var x = 4
x = default(int)
echo x
main()