Skip to content

Commit

Permalink
fix #19266; allow reassign discriminant field (#19567)
Browse files Browse the repository at this point in the history
* add inUncheckedAssignSection

* add one more test
  • Loading branch information
ringabout authored Feb 25, 2022
1 parent ef3f343 commit 9c17a32
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
16 changes: 15 additions & 1 deletion compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2932,7 +2932,21 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
nkFromStmt, nkTemplateDef, nkMacroDef, nkStaticStmt:
discard
of nkPragma: genPragma(p, n)
of nkPragmaBlock: expr(p, n.lastSon, d)
of nkPragmaBlock:
var inUncheckedAssignSection = 0
let pragmaList = n[0]
for pi in pragmaList:
if whichPragma(pi) == wCast:
case whichPragma(pi[1])
of wUncheckedAssign:
inUncheckedAssignSection = 1
else:
discard

inc p.inUncheckedAssignSection, inUncheckedAssignSection
expr(p, n.lastSon, d)
dec p.inUncheckedAssignSection, inUncheckedAssignSection

of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
if n[genericParamsPos].kind == nkEmpty:
var prc = n[namePos].sym
Expand Down
2 changes: 1 addition & 1 deletion compiler/ccgstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
initLocExpr(p, e[0], a)
getTemp(p, a.t, tmp)
expr(p, e[1], tmp)
if optTinyRtti notin p.config.globalOptions:
if optTinyRtti notin p.config.globalOptions and p.inUncheckedAssignSection == 0:
let field = dotExpr[1].sym
genDiscriminantCheck(p, a, tmp, dotExpr[0].typ, field)
message(p.config, e.info, warnCaseTransition)
Expand Down
1 change: 1 addition & 0 deletions compiler/cgendata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type
withinTryWithExcept*: int # required for goto based exception handling
withinBlockLeaveActions*: int # complex to explain
sigConflicts*: CountTable[string]
inUncheckedAssignSection*: int

TTypeSeq* = seq[PType]
TypeCache* = Table[SigHash, Rope]
Expand Down
22 changes: 22 additions & 0 deletions tests/objvariant/treassign.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,25 @@ proc passToVar(x: var Token) = discard
t.curr = TokenObject(kind: t.curr.kind, foo: "abc")

t.curr.kind = Token.foo


block:
type
TokenKind = enum
strLit, intLit
Token = object
case kind*: TokenKind
of strLit:
s*: string
of intLit:
i*: int64

var t = Token(kind: strLit, s: "abc")

{.cast(uncheckedAssign).}:

# inside the 'cast' section it is allowed to assign to the 't.kind' field directly:
t.kind = intLit

{.cast(uncheckedAssign).}:
t.kind = strLit

0 comments on commit 9c17a32

Please sign in to comment.