parameter runtime discriminators (#11397)

* allow param for runtime discriminator construction
This commit is contained in:
Jasper Jenkins
2019-06-04 13:10:39 -07:00
committed by Andreas Rumpf
parent bfa32e8d99
commit fc4f0808c4
3 changed files with 20 additions and 4 deletions

View File

@@ -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

View File

@@ -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.")

View File

@@ -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