supports default for range types using firstOrd with nimPreviewRangeDefault (#23950)

ref https://github.com/nim-lang/Nim/issues/23943
This commit is contained in:
ringabout
2024-08-13 23:08:30 +08:00
committed by GitHub
parent ddc47fecca
commit a33e2b76ae
2 changed files with 26 additions and 5 deletions

View File

@@ -651,7 +651,8 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode, checkDefault:
proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): PNode =
let aTypSkip = aTyp.skipTypes(defaultFieldsSkipTypes)
if aTypSkip.kind == tyObject:
case aTypSkip.kind
of tyObject:
let child = defaultFieldsForTheUninitialized(c, aTypSkip.n, checkDefault)
if child.len > 0:
var asgnExpr = newTree(nkObjConstr, newNodeIT(nkType, a.info, aTyp))
@@ -660,7 +661,7 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): P
result = semExpr(c, asgnExpr)
else:
result = nil
elif aTypSkip.kind == tyArray:
of tyArray:
let child = defaultNodeField(c, a, aTypSkip[1], checkDefault)
if child != nil:
@@ -673,7 +674,7 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): P
result.typ = aTyp
else:
result = nil
elif aTypSkip.kind == tyTuple:
of tyTuple:
var hasDefault = false
if aTypSkip.n != nil:
let children = defaultFieldsForTuple(c, aTypSkip.n, hasDefault, checkDefault)
@@ -686,6 +687,12 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType, checkDefault: bool): P
result = nil
else:
result = nil
of tyRange:
if c.graph.config.isDefined("nimPreviewRangeDefault"):
result = newIntNode(nkIntLit, firstOrd(c.config, aTypSkip))
result.typ = aTyp
else:
result = nil
else:
result = nil

View File

@@ -121,7 +121,7 @@ template main {.dirty.} =
rVal: R = default(R) # Works fine
objVal = default(Obj)
doAssert rVal == 0 # it should be 1
doAssert rVal == 1
doAssert objVal.r == 1
block: # bug #16744
@@ -134,7 +134,7 @@ template main {.dirty.} =
rVal: R = default(R) # Works fine
objVal = Obj()
doAssert rVal == 0 # it should be 1
doAssert rVal == 1 # it should be 1
doAssert objVal.r == 1
block: # bug #3608
@@ -745,5 +745,19 @@ template main {.dirty.} =
doAssert b.list[North] == 1
block:
type
range1 = range[1..10]
range2 = range[-1..10]
proc foo =
doAssert default(range1) == 1
doAssert default(range2) == -1
let s = default(array[5, range1])
doAssert s == [range1 1, 1, 1, 1, 1]
foo()
static: main()
main()