summary refs log tree commit diff stats
path: root/compiler/semobjconstr.nim
diff options
context:
space:
mode:
authorIvan Bobev <bobeff@protonmail.ch>2020-11-06 20:56:09 +0200
committerGitHub <noreply@github.com>2020-11-06 18:56:09 +0000
commit3c85aa9e53cbaae5fae83f9fd29de3bdb107c7aa (patch)
treed014b546d43997de23e1f95b78e40536ba6b179c /compiler/semobjconstr.nim
parent60c364fb224a8b55dc7cacc5a589c569cf202ec5 (diff)
downloadNim-3c85aa9e53cbaae5fae83f9fd29de3bdb107c7aa.tar.gz
Make `{.requiresInit.}` to work for distinct types (#15869)
Make `requiresInit` pragma to work for distinct types in addition to
objects. Tagging of distinct types with `requiresInit` pragma was
already supported, but its impact wasn't applied. Now its behavior when
applied on distinct types is as follows.

Given the following distinct type definitions:

  ```nim
  type
    DistinctObject {.requiresInit, borrow: `.`.} = distinct MyObject
    DistinctString {.requiresInit.} = distinct string
  ```

The following code blocks will fail to compile:

  ```nim
  var foo: DistinctFoo
  foo.x = "test"
  doAssert foo.x == "test"
  ```

  ```nim
  var s: DistinctString
  s = "test"
  doAssert s == "test"
  ```

But these ones will compile successfully:

  ```nim
  let foo = DistinctFoo(Foo(x: "test"))
  doAssert foo.x == "test"
  ```

  ```nim
  let s = "test"
  doAssert s == "test"
  ```
Diffstat (limited to 'compiler/semobjconstr.nim')
-rw-r--r--compiler/semobjconstr.nim21
1 files changed, 14 insertions, 7 deletions
diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim
index 64a27d1db..42529e1e5 100644
--- a/compiler/semobjconstr.nim
+++ b/compiler/semobjconstr.nim
@@ -355,15 +355,22 @@ proc computeRequiresInit(c: PContext, t: PType): bool =
 
 proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) =
   var objType = t
-  while objType.kind != tyObject:
+  while objType.kind notin {tyObject, tyDistinct}:
     objType = objType.lastSon
     assert objType != nil
-  var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info))
-  let initResult = semConstructTypeAux(c, constrCtx, {})
-  assert constrCtx.missingFields.len > 0
-  localError(c.config, info,
-    "The $1 type doesn't have a default value. The following fields must be initialized: $2.",
-    [typeToString(t), listSymbolNames(constrCtx.missingFields)])
+  if objType.kind == tyObject:
+    var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info))
+    let initResult = semConstructTypeAux(c, constrCtx, {})
+    assert constrCtx.missingFields.len > 0
+    localError(c.config, info,
+      "The $1 type doesn't have a default value. The following fields must " &
+      "be initialized: $2.",
+      [typeToString(t), listSymbolNames(constrCtx.missingFields)])
+  elif objType.kind == tyDistinct:
+    localError(c.config, info,
+      "The $1 distinct type doesn't have a default value.", [typeToString(t)])
+  else:
+    assert false, "Must not enter here."
 
 proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
   var t = semTypeNode(c, n[0], nil)