Skip to content
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

Setting the value of an abstract property does not work with enum type inference #7674

Closed
jgranick opened this issue Jan 3, 2019 · 3 comments
Assignees
Milestone

Comments

@jgranick
Copy link

jgranick commented Jan 3, 2019

When setting an enum value in Haxe, ordinarily, type inference allows you to use enum values through type inference without an import:

classInstance.classProperty = NO;

Using @:forward on an abstract allows this same functionality in the Haxe 4 preview 5 release, however it is not possible if you define an abstract property:

enumInstance.enumProperty = NO; // Unknown identifier: NO

Here's code to reproduce the problem, thank you 😄

class Test {
    static function main() {
        // Base Class
        var classInstance = new MyBaseClass ();
        classInstance.classProperty = haxe.zip.FlushMode.NO; // Works
        classInstance.classProperty = NO; // Works
        
        // Abstract
        var enumInstance = new MyAbstract ();
        enumInstance.abstractProperty = haxe.zip.FlushMode.NO; // Works
        enumInstance.abstractProperty = NO; // Broken
    }
}

abstract MyAbstract(MyBaseClass) {
    public var abstractProperty (get, set):haxe.zip.FlushMode;
    public function new () { this = new MyBaseClass (); }
    private inline function get_abstractProperty () { return haxe.zip.FlushMode.NO; }
    private inline function set_abstractProperty (value) { return haxe.zip.FlushMode.NO; }
}

class MyBaseClass {
    public var classProperty:haxe.zip.FlushMode;
    public function new () {}
}

https://try.haxe.org/#53B4c

@Simn Simn added this to the Release 4.0 milestone Jan 24, 2019
@Simn Simn self-assigned this Jan 24, 2019
@Simn
Copy link
Member

Simn commented Jan 24, 2019

Looks like this doesn't employ top-down inference at all:

class Main {
    static function main() {
        var enumInstance = new MyAbstract ();
        enumInstance.abstractProperty = [1];
    }
}

abstract MyAbstract({}) {
    public var abstractProperty (get, set):Array<Float>;
    public function new () { this = {}; }
    private inline function get_abstractProperty () { return []; }
    private inline function set_abstractProperty (value:Array<Float>) { return []; }
}
source/Main.hx:5: characters 9-44 : error: Int should be Float
source/Main.hx:5: characters 9-44 :  have: Array<Int>
source/Main.hx:5: characters 9-44 :  want: Array<Float>

I'm gonna take a look at this for Haxe 4.

@Simn
Copy link
Member

Simn commented Feb 2, 2019

Note that I'm cheating a bit in my example because I type-hint value:Array<Float>. In the original example, this was untyped and as it turns out, we delay the property checks so far that we don't have the proper type when making the access:

AKUsing([Field:(this : { }, value : Unknown<0>) -> Array<Unknown<1>>]
        [TypeExpr _Main.MyAbstract_Impl_:Class<_Main.MyAbstract_Impl_>]
        [FStatic:(this : { }, value : Unknown<0>) -> Array<Unknown<1>>]
                _Main.MyAbstract_Impl_
                set_abstractProperty:(this : { }, value : Unknown<0>) -> Array<Unknown<1>>, _Main.MyAbstract_Impl_, set_abstractProperty, [Local enumInstance(18):MyAbstract:MyAbstract])

All the Array instances there have an unknown type parameter. This is a different but very much related problem because we cannot top-down infer with uninferred types.

@Simn
Copy link
Member

Simn commented Feb 2, 2019

Argh, this changes when we put MyAbstract above Main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants