-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
False positive detection of conflicting branches of object variant #11862
Comments
This is expected since the body of a macro is evaluated by the VM which doesn't currently support variants. |
Not sure if that is true; If you take out the quote-do block the type is instantiated and evaluated at compile time by the VM just fine:
|
The vm treats case objects in a flattened way (like normal objects) with added field checks. This seems fine for loads/store, but breaks for literal constructions from getAst. As a workaround, you can postprocess the ast removing null initializations, but proc patchUpObjConstrs*(n: NimNode) =
proc isDefault(n: NimNode): bool {.nimcall.} =
result = case n.kind:
of nnkExprColonExpr: isDefault(n[1])
of nnkIntLit, nnkUIntLit: n.intVal == 0
of nnkFloatLit: n.floatVal == 0
of nnkBracket: n.len == 0
of nnkStrLit: n.strVal == ""
of nnkNilLit: true
of nnkObjConstr:
patchUpObjConstrs(n)
n.len == 1
else:
patchUpObjConstrs(n)
false
proc findDiscrims(n: NimNode): seq[NimNode] {.nimcall.} =
case n.kind:
of nnkObjectTy:
result.add(findDiscrims(n[2]))
of nnkRecList:
for i in 0 ..< n.len:
result.add(findDiscrims(n[i]))
of nnkRecCase:
result.add(n[0])
for i in 1 ..< n.len:
result.add(findDiscrims(n[i]))
else: discard
proc isDiscrim(discrims: seq[NimNode], init: NimNode): bool {.nimcall.} =
for discrim in discrims:
if init[0].eqIdent(discrim):
return true
if n.kind == nnkObjConstr:
let discrims = findDiscrims(getType(n))
for i in countdown(n.len-1, 1):
if isDefault(n[i]) and not isDiscrim(discrims, n[i]):
n.del(i)
else:
for i in 0 ..< n.len:
patchUpObjConstrs(n[i]) |
When you want to embed values in a quoted source code block, you always have to to lift the value into a import macros
type
Kind = enum kOne, kTwo
Thing = object
case kind: Kind
of kOne:
v1: int
of kTwo:
v2: int
macro magic(): untyped =
var b = newLit(Thing(kind: kOne, v1: 3))
echo b.repr
quote do:
`b`
const c = magic() The simple reason is, the result of Since so many people do use But as aready mentioned, it does not fix the problem |
From @Araq in #8015 (comment)
|
This snippet:
generates the following error:
The text was updated successfully, but these errors were encountered: