summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2024-08-13 23:08:30 +0800
committerGitHub <noreply@github.com>2024-08-13 17:08:30 +0200
commita33e2b76ae4355db61ecf51aec0ced7690c975ef (patch)
tree76d0072977d90949c7cd7d36fd4de64da4baea26
parentddc47feccadf23423d969e970b816b9808335769 (diff)
downloadNim-a33e2b76ae4355db61ecf51aec0ced7690c975ef.tar.gz
supports `default` for range types using `firstOrd` with `nimPreviewRangeDefault` (#23950)
ref https://github.com/nim-lang/Nim/issues/23943
-rw-r--r--compiler/sem.nim13
-rw-r--r--tests/objects/tobject_default_value.nim18
2 files changed, 26 insertions, 5 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index d813a791d..2dd9ebae8 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -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
 
diff --git a/tests/objects/tobject_default_value.nim b/tests/objects/tobject_default_value.nim
index 152b355f4..77837bb84 100644
--- a/tests/objects/tobject_default_value.nim
+++ b/tests/objects/tobject_default_value.nim
@@ -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()