haxe icon indicating copy to clipboard operation
haxe copied to clipboard

Can't use defineType to create a TDField in a module that already has other module level fields

Open basro opened this issue 3 years ago • 7 comments

I'm using haxe 4.2.5

class Macro {
	public static macro function myMacro():Expr {
		Context.defineType({
			name: "baz0",
			kind: TDField(FVar(null, macro "hello")),
			fields: [],
			pos: Context.currentPos(),
			pack: ["foo", "Bar"],
		});

		Context.defineType({
			name: "baz1",
			kind: TDField(FVar(null, macro "hello")),
			fields: [],
			pos: Context.currentPos(),
			pack: ["foo", "Bar"],
		});

		return macro $p{["foo", "Bar", "baz1"]};
	}
}

Running this macro will result in the error Type name foo._Bar.Bar_Fields_ is redefined from module foo.Bar Same will happen if you call defineType only once but use a module that already had module level fields in it as target.

I believe this is creating the class Bar_fields_ with kind KModuleFields each time and that causes the collision. I'm not sure if this is actually intended or a bug.

basro avatar Mar 27 '23 02:03 basro

This seems consistent, I don't think we should allow augmenting existing modules with more fields like this. You can use Context.defineModule in such cases.

Simn avatar Mar 27 '23 06:03 Simn

I'm already able modify/augment existing modules with defineType for all the other type definition kinds. TDField is the exception so it's not exactly consistent in that regard. It is consistent with not being able to modify a type, which the TInst with KmoduleFields kind is, so I get it if it's impossible because of that.

While my example called defineType twice in the same function the real use case has repeated calls to a macro that calls defineType once. It is not possible to bundle the definitions into a single defineModule call.

basro avatar Mar 27 '23 13:03 basro

I can see where you're coming from because this is right in the frontier between fields and types, but ultimately we're still adding fields to a type (even if it's invisible). I don't know if I want to make an exception for module fields here, but I'll reopen for further discussion.

Simn avatar Mar 27 '23 13:03 Simn

Maybe the compiler could support multiple KModuleFields instances per module, then have defineType create a new one each time.

basro avatar Mar 27 '23 14:03 basro

I think this would be in contradiction with what you recently said there https://github.com/HaxeFoundation/haxe/issues/11297#issuecomment-2194348428

We should definitely disallow defining types into existing modules for Haxe 5, if we didn't do that yet.

kLabz avatar Jul 19 '24 18:07 kLabz

Indeed. I wonder if we could give a better error for such cases.

Simn avatar Jul 19 '24 19:07 Simn

We probably could if we started disallowing it entirely

kLabz avatar Jul 19 '24 19:07 kLabz