-
-
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
Macro: bool is converted to int inside quote do
#7375
Comments
Couple of updates.
import macros
macro foo(): untyped =
result = quote do: `littleEndian`
doAssert littleEndian == foo() # Error: type mismatch: got <Endianness, int literal(0)>
Test case: import macros
macro eqSym(x, y: untyped): untyped =
let eq = $x == $y # Unfortunately eqIdent compares to string.
result = quote do: `eq`
var r, a, b: int
template fma(result: var int, a, b: int, op: untyped) =
# fused multiple-add
when eqSym(op, `+=`):
echo "+="
else:
echo "+"
fma(r, a, b, `+=`) Workarounds:Instead of result = quote do: `eq`
result = quote do: Endianness(`eq`) |
Turns out the regression was unrelated to this bug. |
I just hit this bug coming from another case;
|
quote do
The issue is not specific to import macros
template test(boolArg: bool) =
static:
echo "type is: ", type(boolArg)
let x: bool = boolArg # compile error here, because boolArg became an int
macro testWrapped1(boolArg: bool): untyped =
# forwarding boolArg directly works
result = getAst(test(boolArg))
macro testWrapped2(boolArg: bool): untyped =
# forwarding boolArg via a local variable also works
let b = boolArg
result = getAst(test(b))
macro testWrapped3(boolArg: bool): untyped =
# but using a literal `true` as a local variable will be converted to int
let b = true
result = getAst(test(b))
test(true) # ok
testWrapped1(true) # ok
testWrapped2(true) # ok
testWrapped3(true) # error I would say it is an regression, because the godot bindings were relying on |
The issue here is that - Lines 42 to 44 in a1e268e
compiler converts enum fields to integers in the semantic phase - Lines 551 to 552 in a1e268e
So if at compile time - the boolean value gets converted to integer value, then at runtime there is no boolean value, only integer value. (Internally in the compiler there is no notion of a bool, .intVal is checked for being 0 or 1, similarly VM does not know anything about bool) |
I would like to reference my new RFC here, because it would be affected: |
I did some investigations. So first of all, enum values are atcually represented as integer literals, but with a type that says that they are actually enum values. So there is nothing wrong with that. Except that the type is lost in translation. For Line 1289 in 417d27c
The argument is passed as an immediate int here: Line 1989 in 417d27c
The type field is not serialized. In the vm the register in translated back into a node here: Line 1118 in 417d27c
This node is an integer literal node without any type information ( Line 2148 in 417d27c
This crashes then in |
For when this is later fixed; here is another bit of sample code to test against. Very likely the same bug involving a template called from macro: |
@JohanaD just make sure all arguments to the template you want to call with macro joe(body: untyped): untyped =
result = newStmtList()
let t = newLit(true)
let temp = getAst test(t)
result.add(temp) |
workaround for nim/macro/typedesc issue work-around for nim-lang/Nim#7375 fixed more isNil usages fixed new name of setStackBottom
…nim-lang#9607; rework quote do; `getAst` uses type info to annotate the type of quoted variables; no more type erasures for quoted variables (nim-lang#21433) * fixes nim-lang#21326; getAst uses type info to annotateType quoted variables * simplify logics; sem types first * fixes important packages * add testcases * tiny
…nim-lang#9607; rework quote do; `getAst` uses type info to annotate the type of quoted variables; no more type erasures for quoted variables (nim-lang#21433) * fixes nim-lang#21326; getAst uses type info to annotateType quoted variables * simplify logics; sem types first * fixes important packages * add testcases * tiny
When creating a boolean in a macro and passing it to other macro, it is transformed to a static[int]
I would expect a conversion to
static[bool]
instead ofstatic[int]
originally posted in #10719
It seems that passing
true
/false
literals within macros gets them converted to integer literals internally, which further results in errors if you try to use them as booleans. This worked as expected in 0.18.0.Example
Current Output
The text was updated successfully, but these errors were encountered: