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

[cs] abstract operator overload + readonly var #6164

Closed
kevinresol opened this issue Apr 7, 2017 · 2 comments · Fixed by #11551
Closed

[cs] abstract operator overload + readonly var #6164

kevinresol opened this issue Apr 7, 2017 · 2 comments · Fixed by #11551
Assignees
Labels
bug platform-cs Everything related to c#
Milestone

Comments

@kevinresol
Copy link
Contributor

kevinresol commented Apr 7, 2017

Haxe revision: 84bf7e5
The following code causes a runtime error on c#:

Unhandled Exception:
Cannot access field for writing.
class Main {
	static function main() {
		var f1:Future<Int> = Future.trigger();
		var f2:Future<Int> = Future.trigger();
		
		var f = f1 || f2; // run-time fail
		var f = f1.first(f2); // ok
		var f = Future.or(f1, f2); // ok
	}
}

abstract Future<T>(FutureTrigger<T>) from FutureTrigger<T> to FutureTrigger<T> {
	public static function trigger<T>():FutureTrigger<T>
		return new FutureTrigger();
		
	public function handle(f:Void->Void)
		return null;
		
  	@:op(a || b) static public function or<A>(a:Future<A>, b:Future<A>):Future<A>
    	return a.first(b);
		
	public function first(other:Future<T>):Future<T> {
		var ret = Future.trigger();
		var l1 = handle(ret.trigger);
		return ret;
	}
}

class FutureTrigger<T> {
	public var triggered(get, never):Bool; // ok if changing never to something else
	public function new() {}
	public function trigger() {}
	public function get_triggered()
		return true;
}
@nadako
Copy link
Member

nadako commented Apr 7, 2017

Reduced to this:

class C<T> {
    public var v(get,never):Bool;
    function get_v() return true;

    public function new() {}
}

class Main {
    static function main() {
        var d:Dynamic = new C<Dynamic>();
        var i:C<Int> = d;
    }
}

Bad things happen in the dynamic type param cast helpers: it iterates over Reflect.fields(this) and that include the get,never var, setting of which obviously fails when trying to Reflect.setField it in a copy.

As a (fairly) quick fix we should look into iterating only over physical fields instead of relying on Reflect.fields, but this cast-by-copy thing is so bad we should seriously consider reworking it for 4.0 (see #2103).

@kevinresol
Copy link
Contributor Author

But I also wonder why there is a need for casting in the operator-overload case, while not in the direct function call case?

@Simn Simn added this to the Bugs milestone Apr 17, 2018
@Simn Simn modified the milestones: Bugs, Later Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug platform-cs Everything related to c#
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants