HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.17k stars 656 forks source link

DCE causes toString() methods to be discarded #9541

Open deepnight opened 4 years ago

deepnight commented 4 years ago

If there's no direct reference to a class toString() method, it's discarded by DCE, forcing you to add @:keep in front of all of them.

kLabz commented 4 years ago

Another discussion about this: #6841

RealyUniqueName commented 4 years ago

The compiler handles a few cases when toString is kept even if not used directly. What's your scenario of using toString without referencing it?

deepnight commented 4 years ago

This is an example:

class Test {
    public function new() {
    }

    public function toString() {
        return "I'm test toString";
    }
}
var foo = new Test();
trace(foo);

This works on HL target target, but doesn't on JS (dce removes the toString() ).

Now if I have the following example, the toString is discarded on both targets:

function debugLog(v:Dynamic) {
    writeValueSomewhere( Std.string(v) );
}
debugLog(foo);
RealyUniqueName commented 4 years ago

I think the first sample is supposed to work on all targets already. If it doesn't, then it's a bug.

The second one is "by design". The compiler can't figure out fields usages through dynamic typing. I think, changing v:Dynamic to v:{function toString():String} should fix the issue.