Skip to content

Commit

Permalink
avoid AnyEnumConv warning in genEnumCaseStmt (#22061)
Browse files Browse the repository at this point in the history
When parsing enums from strings using `genEnumCaseStmt`, `AnyEnumConv`
warnings are generated due to conversion from integer value. It seems
possible meanwhile to refer to the actual `enum` value by symbol instead
of being required to do the conversion from `ord`, even when the `enum`
is defined in a `block`.
  • Loading branch information
etan-status committed Jun 10, 2023
1 parent d3af088 commit 8bba040
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions lib/std/enumutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ macro genEnumCaseStmt*(typ: typedesc, argSym: typed, default: typed,
# Generates a case stmt, which assigns the correct enum field given
# a normalized string comparison to the `argSym` input.
# string normalization is done using passed normalizer.
# NOTE: for an enum with fields Foo, Bar, ... we cannot generate
# `of "Foo".nimIdentNormalize: Foo`.
# This will fail, if the enum is not defined at top level (e.g. in a block).
# Thus we check for the field value of the (possible holed enum) and convert
# the integer value to the generic argument `typ`.
let typ = typ.getTypeInst[1]
let impl = typ.getImpl[2]
expectKind impl, nnkEnumTy
Expand All @@ -34,19 +29,25 @@ macro genEnumCaseStmt*(typ: typedesc, argSym: typed, default: typed,
result = nnkCaseStmt.newTree(newCall(normalizerNode, argSym))
# stores all processed field strings to give error msg for ambiguous enums
var foundFields: seq[string] = @[]
var fVal = ""
var fStr = "" # string of current field
var fNum = BiggestInt(0) # int value of current field
for f in impl:
case f.kind
of nnkEmpty: continue # skip first node of `enumTy`
of nnkSym, nnkIdent: fStr = f.strVal
of nnkSym, nnkIdent:
fVal = f.strVal
fStr = fVal
of nnkAccQuoted:
fStr = ""
fVal = ""
for ch in f:
fStr.add ch.strVal
fVal.add ch.strVal
fStr = fVal
of nnkEnumFieldDef:
fVal = f[0].strVal
case f[1].kind
of nnkStrLit: fStr = f[1].strVal
of nnkStrLit:
fStr = f[1].strVal
of nnkTupleConstr:
fStr = f[1][1].strVal
fNum = f[1][0].intVal
Expand All @@ -64,7 +65,7 @@ macro genEnumCaseStmt*(typ: typedesc, argSym: typed, default: typed,
if fNum >= userMin and fNum <= userMax:
fStr = normalizer(fStr)
if fStr notin foundFields:
result.add nnkOfBranch.newTree(newLit fStr, nnkCall.newTree(typ, newLit fNum))
result.add nnkOfBranch.newTree(newLit fStr, newDotExpr(typ, ident fVal))
foundFields.add fStr
else:
error("Ambiguous enums cannot be parsed, field " & $fStr &
Expand Down

0 comments on commit 8bba040

Please sign in to comment.