summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md3
-rw-r--r--compiler/semmagic.nim2
-rw-r--r--lib/pure/typetraits.nim17
3 files changed, 21 insertions, 1 deletions
diff --git a/changelog.md b/changelog.md
index fb0102cd3..4ea436fb0 100644
--- a/changelog.md
+++ b/changelog.md
@@ -11,7 +11,8 @@
 
 [//]: # "Additions:"
 
-- Adds `newStringUninit` to system, which creates a new string of length `len` like `newString` but with uninitialized content.
+- Added `newStringUninit` to system, which creates a new string of length `len` like `newString` but with uninitialized content.
+- Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
 
 [//]: # "Deprecations:"
 
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index d06b32e47..2b57d1873 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -197,6 +197,8 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
     let complexObj = containsGarbageCollectedRef(t) or
                      hasDestructor(t)
     result = newIntNodeT(toInt128(ord(not complexObj)), traitCall, c.idgen, c.graph)
+  of "hasDefaultValue":
+    result = newIntNodeT(toInt128(ord(not operand.requiresInit)), traitCall, c.idgen, c.graph)
   of "isNamedTuple":
     var operand = operand.skipTypes({tyGenericInst})
     let cond = operand.kind == tyTuple and operand.n != nil
diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim
index 70eb1b81c..384c2dbac 100644
--- a/lib/pure/typetraits.nim
+++ b/lib/pure/typetraits.nim
@@ -96,6 +96,23 @@ proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
   ##
   ## Other languages name a type like these `blob`:idx:.
 
+proc hasDefaultValue*(t: typedesc): bool {.magic: "TypeTrait".} =
+  ## Returns true if `t` has a valid default value.
+  runnableExamples:
+    {.experimental: "strictNotNil".}
+    type
+      NilableObject = ref object
+        a: int
+      Object = NilableObject not nil
+      RequiresInit[T] = object
+        a {.requiresInit.}: T
+
+    assert hasDefaultValue(NilableObject)
+    assert not hasDefaultValue(Object)
+    assert hasDefaultValue(string)
+    assert not hasDefaultValue(var string)
+    assert not hasDefaultValue(RequiresInit[int])
+
 proc isNamedTuple*(T: typedesc): bool {.magic: "TypeTrait".} =
   ## Returns true for named tuples, false for any other type.
   runnableExamples: