haxe icon indicating copy to clipboard operation
haxe copied to clipboard

[cs] DCE seems to strip interfaces fields when using theirs in abstract inline functions

Open romanmikhailov opened this issue 8 years ago • 2 comments

I met compilation error (error CS1061: Type `haxe.IMap<object,int>' does not contain a definition for `keys' and no extension method `keys' of type `haxe.IMap<object,int>' could be found. Are you missing an assembly reference?) when try to compile next code:

This can be workarounded one of next ways:

  1. Removing inline from EquatableMap#tryGetKey
  2. Adding --macro keep("haxe.Constraints.IMap") in build.hxml
  3. Move declaration of Main#fooMap to main

Main.hx

package;

import haxe.Constraints.IMap;
import haxe.ds.ObjectMap;

interface IEquatable<T> {
	function equals(other:T):Bool;
}

@:multiType(K)
abstract EquatableMap<K, V>(IMap<K, V>) {
	public function new();

	public inline function containsKey(key:K):Bool {
		key = tryGetKey(key);
		return this.exists(key);
	}

	inline function tryGetKey(key:K):K {
		var result = key;
		if(Std.is(key, IEquatable)) {
			var keyHolder:IEquatable<Dynamic> = cast key;
			for(it in this.keys()) {
				var currentKeyHolder:IEquatable<Dynamic> = cast it;
				if(currentKeyHolder.equals(keyHolder)) {
					result = it;
					break;
				}
			}
		}
		return result;
	}

	@:to static inline function toObjectMap<K:{}, V>(t:IMap<K, V>):ObjectMap<K,V> {
		return new ObjectMap<K, V>();
	}
}

class Foo implements IEquatable<Foo> {
	public function new() {
	}

	public function equals(other:Foo):Bool {
		return this == other;
	}
}

class Main {
	private static var fooMap:EquatableMap<Foo, Int> = new EquatableMap<Foo, Int>();

	public static function main():Void {
		var foo:Foo = new Foo();
		var exists:Bool = fooMap.containsKey(foo);
		trace(exists);
	}
}

build.hxml

-cs output/

-cp .
-main Main
-dce full
-debug
-D real-position

-cmd mono output/bin/Main-Debug.exe

Console output

$ haxe build.hxml 
haxelib run hxcs hxcs_build.txt --haxe-version 3402 --feature-level 1
Note: dmcs is deprecated, please use mcs instead!
src/Main.cs(145,24): error CS1061: Type `haxe.IMap<object,int>' does not contain a definition for `keys' and no extension method `keys' of type `haxe.IMap<object,int>' could be found. Are you missing an assembly reference?
src/haxe/Constraints.cs(5,19): (Location of the symbol related to previous error)
Compilation failed: 1 error(s), 0 warnings
Compilation error
Native compilation failed
Error: Build failed

romanmikhailov avatar Jul 28 '17 19:07 romanmikhailov

Minimal reproducible example without maps and generics (using the same build.hxml): Main.hx

package;

interface IInterface {
	function interfaceMethod1():Void;
	function interfaceMethod2():Void;
}

class InterfaceImplementation implements IInterface {
	public function new() {}

	public function interfaceMethod1():Void {
		trace('interfaceMethod1');
	}

	public function interfaceMethod2():Void {
		trace('interfaceMethod2');
	}
}

@:multiType
abstract AbstractOnInterface(IInterface) {
	public function new();

	public inline function abstractMethod1():Void {
		abstractMethod2();
		this.interfaceMethod1();
	}

	public inline function abstractMethod2():Void {
		this.interfaceMethod2();
	}

	@:to static inline function toObject(t:IInterface):InterfaceImplementation {
		return new InterfaceImplementation();
	}
}

class Main {
	private static var abstractOnInterface:AbstractOnInterface = new AbstractOnInterface();

	public static function main():Void {
		abstractOnInterface.abstractMethod1();
	}
}

Console output:

$ haxe build.hxml 
haxelib run hxcs hxcs_build.txt --haxe-version 3402 --feature-level 1
Note: dmcs is deprecated, please use mcs instead!
src/Main.cs(133,9): error CS1061: Type `IInterface' does not contain a definition for `interfaceMethod2' and no extension method `interfaceMethod2' of type `IInterface' could be found. Are you missing an assembly reference?
src/Main.cs(4,18): (Location of the symbol related to previous error)
Compilation failed: 1 error(s), 0 warnings
Compilation error
Native compilation failed
Error: Build failed

romanmikhailov avatar Jul 28 '17 20:07 romanmikhailov

I also encountered this when doing my Reflaxe/Dart target (although tbf it could be me implementing it wrong) having to add @:keep to IMap to stop it from DCEing the fields.

fourst4r avatar Mar 11 '24 21:03 fourst4r

Hmm, seems like we missed some C# issues. See #11551 (or provide a way to reproduce this on other targets and reopen)

kLabz avatar Jul 19 '24 19:07 kLabz