diff options
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | compiler/semobjconstr.nim | 9 | ||||
-rw-r--r-- | tests/objvariant/trt_discrim.nim | 12 |
3 files changed, 20 insertions, 4 deletions
diff --git a/changelog.md b/changelog.md index 6c3bc018b..e16211a3d 100644 --- a/changelog.md +++ b/changelog.md @@ -236,7 +236,8 @@ proc enumToString*(enums: openArray[enum]): string = pragmas for further analysis by macros - Custom pragmas are now supported for `var` and `let` symbols. - Tuple unpacking is now supported for constants and for loop variables. - +- Case object branches can be initialized with a runtime discriminator if + possible discriminator values are constrained within a case statement. ### Language changes diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 4b4c5de02..c9216cc51 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -129,8 +129,10 @@ proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string = proc findUsefulCaseContext(c: PContext, discrimator: PNode): (PNode, int) = for i in countdown(c.p.caseContext.high, 0): - let (caseNode, index) = c.p.caseContext[i] - if caseNode[0].kind == nkSym and caseNode[0].sym == discrimator.sym: + let + (caseNode, index) = c.p.caseContext[i] + skipped = caseNode[0].skipHidden + if skipped.kind == nkSym and skipped.sym == discrimator.sym: return (caseNode, index) proc pickCaseBranch(caseExpr, matched: PNode): PNode = @@ -252,7 +254,8 @@ proc semConstructFields(c: PContext, recNode: PNode, let (ctorCase, ctorIdx) = findUsefulCaseContext(c, discriminatorVal) if ctorCase == nil: badDiscriminatorError() - elif discriminatorVal.sym.kind != skLet: + elif discriminatorVal.sym.kind notin {skLet, skParam} or + discriminatorVal.sym.typ.kind == tyVar: localError(c.config, discriminatorVal.info, "runtime discriminator must be immutable if branch fields are " & "initialized, a 'let' binding is required.") diff --git a/tests/objvariant/trt_discrim.nim b/tests/objvariant/trt_discrim.nim index 612647fbe..303c0fa55 100644 --- a/tests/objvariant/trt_discrim.nim +++ b/tests/objvariant/trt_discrim.nim @@ -136,3 +136,15 @@ reject: # not immutable. of k1, k2, k3: discard KindObj(varkind: kind, i32: 1) of k4: discard KindObj(varkind: kind, f32: 2.0) else: discard KindObj(varkind: kind, str: "3") + +accept: + proc kindProc(kind: Kind): KindObj = + case kind: + of k1: result = KindObj(kind: kind, i32: 1) + else: discard + +reject: + proc varKindProc(kind: var Kind): KindObj = + case kind: + of k1: result = KindObj(kind: kind, i32: 1) + else: discard |