parent
6b88cd0d42
commit
4ab6887a67
5 changed files with 32 additions and 24 deletions
|
|
@ -154,20 +154,20 @@ proc collectMissingFields(c: PContext, fieldsRecList: PNode,
|
|||
if assignment == nil:
|
||||
constrCtx.missingFields.add r.sym
|
||||
|
||||
proc semConstructFields(c: PContext, recNode: PNode,
|
||||
proc semConstructFields(c: PContext, n: PNode,
|
||||
constrCtx: var ObjConstrContext,
|
||||
flags: TExprFlags): InitStatus =
|
||||
result = initUnknown
|
||||
|
||||
case recNode.kind
|
||||
case n.kind
|
||||
of nkRecList:
|
||||
for field in recNode:
|
||||
for field in n:
|
||||
let status = semConstructFields(c, field, constrCtx, flags)
|
||||
mergeInitStatus(result, status)
|
||||
|
||||
of nkRecCase:
|
||||
template fieldsPresentInBranch(branchIdx: int): string =
|
||||
let branch = recNode[branchIdx]
|
||||
let branch = n[branchIdx]
|
||||
let fields = branch[^1]
|
||||
fieldsPresentInInitExpr(c, fields, constrCtx.initExpr)
|
||||
|
||||
|
|
@ -176,12 +176,12 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
let fields = branchNode[^1]
|
||||
collectMissingFields(c, fields, constrCtx)
|
||||
|
||||
let discriminator = recNode[0]
|
||||
let discriminator = n[0]
|
||||
internalAssert c.config, discriminator.kind == nkSym
|
||||
var selectedBranch = -1
|
||||
|
||||
for i in 1..<recNode.len:
|
||||
let innerRecords = recNode[i][^1]
|
||||
for i in 1..<n.len:
|
||||
let innerRecords = n[i][^1]
|
||||
let status = semConstructFields(c, innerRecords, constrCtx, flags)
|
||||
if status notin {initNone, initUnknown}:
|
||||
mergeInitStatus(result, status)
|
||||
|
|
@ -217,9 +217,9 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
localError(c.config, discriminatorVal.info, ("possible values " &
|
||||
"$2 are in conflict with discriminator values for " &
|
||||
"selected object branch $1.") % [$selectedBranch,
|
||||
valsDiff.renderAsType(recNode[0].typ)])
|
||||
valsDiff.renderAsType(n[0].typ)])
|
||||
|
||||
let branchNode = recNode[selectedBranch]
|
||||
let branchNode = n[selectedBranch]
|
||||
let flags = flags*{efAllowDestructor} + {efPreferStatic,
|
||||
efPreferNilResult}
|
||||
var discriminatorVal = semConstrField(c, flags,
|
||||
|
|
@ -230,7 +230,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
if discriminatorVal.kind notin nkLiterals and (
|
||||
not isOrdinalType(discriminatorVal.typ, true) or
|
||||
lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or
|
||||
lengthOrd(c.config, recNode[0].typ) > MaxSetElements):
|
||||
lengthOrd(c.config, n[0].typ) > MaxSetElements):
|
||||
localError(c.config, discriminatorVal.info,
|
||||
"branch initialization with a runtime discriminator only " &
|
||||
"supports ordinal types with 2^16 elements or less.")
|
||||
|
|
@ -242,7 +242,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
if ctorCase == nil:
|
||||
if discriminatorVal.typ.kind == tyRange:
|
||||
let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
|
||||
let recBranchVals = branchVals(c, recNode, selectedBranch, false)
|
||||
let recBranchVals = branchVals(c, n, selectedBranch, false)
|
||||
let diff = rangeVals - recBranchVals
|
||||
if diff.len != 0:
|
||||
valuesInConflictError(diff)
|
||||
|
|
@ -260,7 +260,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
else:
|
||||
var
|
||||
ctorBranchVals = branchVals(c, ctorCase, ctorIdx, true)
|
||||
recBranchVals = branchVals(c, recNode, selectedBranch, false)
|
||||
recBranchVals = branchVals(c, n, selectedBranch, false)
|
||||
branchValsDiff = ctorBranchVals - recBranchVals
|
||||
if branchValsDiff.len != 0:
|
||||
valuesInConflictError(branchValsDiff)
|
||||
|
|
@ -271,14 +271,14 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
failedBranch = selectedBranch
|
||||
else:
|
||||
# With an else clause, check that all other branches don't match:
|
||||
for i in 1..<recNode.len - 1:
|
||||
if recNode[i].caseBranchMatchesExpr(discriminatorVal):
|
||||
for i in 1..<n.len - 1:
|
||||
if n[i].caseBranchMatchesExpr(discriminatorVal):
|
||||
failedBranch = i
|
||||
break
|
||||
if failedBranch != -1:
|
||||
if discriminatorVal.typ.kind == tyRange:
|
||||
let rangeVals = c.getIntSetOfType(discriminatorVal.typ)
|
||||
let recBranchVals = branchVals(c, recNode, selectedBranch, false)
|
||||
let recBranchVals = branchVals(c, n, selectedBranch, false)
|
||||
let diff = rangeVals - recBranchVals
|
||||
if diff.len != 0:
|
||||
valuesInConflictError(diff)
|
||||
|
|
@ -301,22 +301,22 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
|||
# initialized to zero and this will select a particular branch as
|
||||
# a result:
|
||||
let defaultValue = newIntLit(c.graph, constrCtx.initExpr.info, 0)
|
||||
let matchedBranch = recNode.pickCaseBranch defaultValue
|
||||
let matchedBranch = n.pickCaseBranch defaultValue
|
||||
collectMissingFields matchedBranch
|
||||
else:
|
||||
result = initPartial
|
||||
if discriminatorVal.kind == nkIntLit:
|
||||
# When the discriminator is a compile-time value, we also know
|
||||
# which branch will be selected:
|
||||
let matchedBranch = recNode.pickCaseBranch discriminatorVal
|
||||
let matchedBranch = n.pickCaseBranch discriminatorVal
|
||||
if matchedBranch != nil: collectMissingFields matchedBranch
|
||||
else:
|
||||
# All bets are off. If any of the branches has a mandatory
|
||||
# fields we must produce an error:
|
||||
for i in 1..<recNode.len: collectMissingFields recNode[i]
|
||||
for i in 1..<n.len: collectMissingFields n[i]
|
||||
|
||||
of nkSym:
|
||||
let field = recNode.sym
|
||||
let field = n.sym
|
||||
let e = semConstrField(c, flags, field, constrCtx.initExpr)
|
||||
result = if e != nil: initFull else: initNone
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue