COMMUNITY

Generic Class with T Dynamic referenced for type possibly instantiated

Hey I’m running into an issue where i’m trying to reference logic but it’s preventing compilation when referencing a generic class that can instantiate itself and is extended by a class that might be referenced as dynamic for logic, as the type might be unknown or a different type than the passed in parameter see below:

import haxe.Constraints.Constructible;

class Test {
    static function main() {
        var val = new GenericImpl<GenericTest>();
        trace("Compiled Successfully");
    }
}

@:generic
class GenericImpl<T:Constructible<Void->Void>> extends GenericBase<T>
{
    //Commenting out the below line will fix the issue but loses the functionality
    public function Logic(reference:GenericImpl<Dynamic>){}
}

@:generic
class GenericBase<T:Constructible<Void->Void>>
{
    public function new(){}
    
	public function instantiate():T
    {
        var instance = new T();
        return instance;
    }
}

class GenericTest {
    public function new(){}
}

fails compilation with error:

Test.hx:21: lines 21-25 : Dynamic has no field new

Any workarounds for this logic, so that i can maintain a reference to the GenericImpl class as either dynamic or something else and maintaining the construction.

https://try.haxe.org/#6883F

public function Logic(reference:GenericImpl<T>){}

or if you want reference to allow any type parameter:

public function Logic<R>(reference:GenericImpl<R>){}

This is what i was going for:

public function Logic<R>(reference:GenericImpl<R>){} 

Do you have an example of it working i’ve tried and i’m getting various errors

public function Logic<R:Constructible<Void->Void>>(reference:GenericImpl<R>){
}

Test.hx:13: characters 65-79 : Type parameters with a constructor cannot be used non-generically

The original error position is not very helpful, I reported this issue here https://github.com/HaxeFoundation/haxe/issues/9497.

Still, I’m curious what are you trying to achieve with this? It looks quite complicated, not just to me, but also apparently to the compiler :slight_smile: I suspect this can be done simplier, maybe even without @:generic.

Something closer to this:

https://try.haxe.org/#81407

@:generic
class GenericBase<T:Constructible<Void->Void>>
{
    public function new(){}
    
	public function instantiate():T
    {
        var instance = new T();
        return instance;
    }
    
    @:isVar public var example(get, null):T;
	
	private function get_example():T 
	{
		if (example == null) example = instantiate();
		return example;
	}
}

Where the example type can be strong typed and decided in a subclass with only cursory restrictions which works, but when factoring the first post where i’m trying to pass around a generic reference it fails

Dynamic has no field new

Edit:

This is a class where you have A extended by B and where a is subclassed by A1, A2 … and B is subclassed by B1, B2, B3 …