konsoletyper / teavm

Compiles Java bytecode to JavaScript, WebAssembly and C
https://teavm.org
Apache License 2.0
2.55k stars 260 forks source link

Auto-implemented record methods (`equals`, `hashCode`, `toString`) not found #923

Closed TypeSafeSchwalbe closed 1 month ago

TypeSafeSchwalbe commented 1 month ago

I have been trying to get some Java code involving records to compile with TeaVM, specifically my compiler written in Java. Internally it uses records, such as for example the Namespace record (which looks like this):

package typesafeschwalbe.gerac.compiler.frontend;

import java.util.List;

public record Namespace(List<String> elements) {

    @Override
    public String toString() {
        return String.join("::", this.elements);
    }

}

Trying to compile this with TeaVM gives me the following two errors related to Namespace specifically (I am going to assume one has to actually use Namespace.equals and Namespace.hashCode to get the same or a similar error:

Substitutor for bootstrap method java.lang.runtime.ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; was not found
    at typesafeschwalbe.gerac.compiler.frontend.Namespace.hashCode(Namespace.java:6)
    at java.util.HashMap.computeHashCode(THashMap.java:672)
    at java.util.HashMap.putImpl(THashMap.java:483)
    at java.util.HashMap.put(THashMap.java:468)
    at typesafeschwalbe.gerac.web.WebCompiler.main(WebCompiler.java:14)
Substitutor for bootstrap method java.lang.runtime.ObjectMethods.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; was not found
    at typesafeschwalbe.gerac.compiler.frontend.Namespace.equals(Namespace.java:6)
    at typesafeschwalbe.gerac.compiler.types.ConstraintSolver.checkSymbols(ConstraintSolver.java:113)
    at typesafeschwalbe.gerac.compiler.Compiler.compile(Compiler.java:82)
    at typesafeschwalbe.gerac.web.WebCompiler.main(WebCompiler.java:17)

So then I tried implementing the methods myself like this:

package typesafeschwalbe.gerac.compiler.frontend;

import java.util.List;

public record Namespace(List<String> elements) {

    @Override
    public String toString() {
        return String.join("::", this.elements);
    }

    @Override
    public boolean equals(Object otherRaw) {
        if(!(otherRaw instanceof Namespace)) { return false; }
        Namespace other = (Namespace) otherRaw;
        return this.elements.equals(other.elements);
    }

    @Override
    public int hashCode() {
        return this.elements.hashCode();
    }

}

Which made those two specific errors go away. I am going to assume this is simply TeaVM not automatically generating implementations of these? All errors I am getting are similar to these, so I will probably just implement all of them manually for now and see how that goes. Decided that I should probably leave it as an issue here anyway. Thanks again for making and maintaining TeaVM btw

konsoletyper commented 1 month ago

No, you are wrong. TeaVM automatically implements record methods. Which version are you using?

TypeSafeSchwalbe commented 1 month ago

oh wait yeah I just realized I am using 0.7 and that it may be because of that since I know got

Class java.lang.Record was not found
    at typesafeschwalbe.gerac.compiler.frontend.Namespace.<init>(Namespace.java:6)
    at typesafeschwalbe.gerac.compiler.Compiler.compile(Compiler.java:67)
    at typesafeschwalbe.gerac.web.WebCompiler.main(WebCompiler.java:17)
TypeSafeSchwalbe commented 1 month ago

welp let me update and check again

TypeSafeSchwalbe commented 1 month ago

Yup simply updating to 0.10 works now. That's almost embarrassing :/ Thanks a lot again!