Reputation: 19026
I want to write a macro that returns an (expression of an) Array -- but I can't seem to convince the compiler that my returned value will be typed as an Array. I always get "you can't iterate on a Dynamic value", even though I've tried:
ExprOf<Array<Whatever>>
http://try-haxe.mrcdk.com/#D7D82
import haxe.macro.Context;
import haxe.macro.Expr;
class Test {
static function main() {
trace("Haxe is great!");
// ERROR: You can't iterate on a Dynamic value
for (val in Macro.someArrayExpr()) {
trace(val);
}
}
}
class Macro
{
public static macro function someArrayExpr():ExprOf<Array<String>>
{
// Neither of these works:
// Try to insert a type hint:
// return Context.parse('([]:Array<String>)', Context.currentPos());
return macro [];
}
}
Upvotes: 3
Views: 186
Reputation: 19026
Uh oh, it looks like it's a side effect of defining my Macro class in the same module (file) as my invocation. Separating the classes into separate files makes it work!
http://try-haxe.mrcdk.com/#57801
Test.hx:
class Test {
static function main() {
trace("Haxe is great!");
// Hooray, it works!
for (val in Macro.someArrayExpr()) {
trace(val);
}
}
}
Macro.hx:
import haxe.macro.Context;
import haxe.macro.Expr;
//use this for macros or other classes
class Macro
{
public static macro function someArrayExpr():ExprOf<Array<String>>
{
return macro ["a", "b", "c"];
}
}
The technical explanation for this (thanks to Juraj): the Test class is being typed in the macro context. In that case, it's calling the macro from a macro, which is always typed Dynamic, hence the error. So another solution is to exclude the class Test from being compiled into the macro context: http://try-haxe.mrcdk.com/#1f3b2
Upvotes: 4