Cannot use structure inititialisation (from `@:structInit`) to declare a new entry in a map
Using Haxe version 4.0.5. Here is the content of the file Main.hx.
package;
@:structInit
class Student
{
public final name:String;
public final score:Int;
}
class Main
{
public static function main()
{
var map = new Map<String, Student>();
var student1:Student = { name: "Boris", score: 20 };
map["the best"] = student1;
map["the worst"] = { name: "Vianney", score: -1 }; // Compilation error here
}
}
When trying to launch this code using haxe --run Main, the compiler gives this error:
Main.hx:19: characters 9-58 : No @:arrayAccess function for haxe.ds.Map<String, Student> accepts arguments of String and { score : Int, name : String }
We must use a temporary variable to insert a new value in the map when using the way to construct an instance given by @:structInit.
Interestingly, var map:Map<String, Student> = ["the worst" => { name: "Vianney", score: -1 }]; does work
Edit: type hint makes it work too (map["the worst"] = ({ name: "Vianney", score: -1 } :Student);) but I suppose it should be handled without it
This is a top-down inference problem which we can reduce to this:
abstract A(String) {
public function new() {
this = "";
}
@:arrayAccess public function arrayWrite(k:String, v:Array<Dynamic>) {}
}
class Main {
public static function main() {
var a = new A();
a["foo"] = [1, "foo"];
}
}
This fails with Arrays of mixed types are only allowed if the type is forced to Array<Dynamic>, which means that there is no expected type when typing the rhs of the assignment.
I suppose we can do the same we do for from-casts here: If there's only a single @:arrayAccess on the abstract, we can use its types for top-down inference.
Come to think of it, for consistency we would want this to work for the keys as well:
abstract A(String) {
public function new() {
this = "";
}
@:arrayAccess public function arrayRead(k:Array<Dynamic>) {}
}
class Main {
public static function main() {
var a = new A();
a[[1, "foo"]];
}
}
This gets pretty tricky due to some internal architecture concerns.