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

@EqualsAndHashCode on inner class produces invalid cast #362

Closed
lombokissues opened this Issue Jul 14, 2015 · 6 comments

Comments

Projects
None yet
2 participants
@lombokissues
Collaborator

lombokissues commented Jul 14, 2015

Migrated from Google Code (issue 289)

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 jwnimmer@jaybridge.com   🕗 Oct 18, 2011 at 18:30 UTC

What steps will reproduce the problem?
What is the expected output? What do you see instead?

A lombok-generated equals method has problems with instanceof vs type erasure of an outer class.

$ cat Bug.java

public class Bug<T> {
@ lombok.EqualsAndHashCode
public final class Inner {
public int foo;
}
}

$ java -jar lombok.jar delombok -d delombok Bug.java; cat delombok/Bug.java

// Generated by delombok at Tue Oct 18 14:22:08 EDT 2011
public class Bug<T> {
public final class Inner {
public int foo;

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Inner)) return false;
        final Inner other = (Inner)o;
        if (this.foo != other.foo) return false;
        return true;
    }

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + this.foo;
        return result;
    }
}

}

$ javac -classpath lombok.jar delombok/Bug.java

delombok/Bug.java:14: illegal generic type for instanceof
if (!(o instanceof Inner)) return false;
^
1 error

$ java -jar ecj.jar -source 1.6 delombok/Bug.java

  1. ERROR in delombok/Bug.java (at line 14)
    if (!(o instanceof Inner)) return false;
    ^^^^^^^^^^^^^^^^^^^^
    Cannot perform instanceof check against parameterized type Bug<T>.Inner.
    Use the form Bug.Inner instead since further generic type information
    will be erased at runtime

    1 problem (1 error)

What version of the product are you using? On what operating system?

Lombok version: 0.10.1-EDGE 2011-09-20 18:50 UTC
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2)
OpenJDK Server VM (build 19.0-b09, mixed mode)
Ubuntu Lucid (10.04).

Please provide any additional information below.

The fix suggested by ECJ is s/Inner/Bug.Inner/ on instanceof, as in:
if (!(o instanceof Bug.Inner)) return false;
but perhaps using Bug<?>.Inner to be as specific as possible would be best.

Collaborator

lombokissues commented Jul 14, 2015

👤 jwnimmer@jaybridge.com   🕗 Oct 18, 2011 at 18:30 UTC

What steps will reproduce the problem?
What is the expected output? What do you see instead?

A lombok-generated equals method has problems with instanceof vs type erasure of an outer class.

$ cat Bug.java

public class Bug<T> {
@ lombok.EqualsAndHashCode
public final class Inner {
public int foo;
}
}

$ java -jar lombok.jar delombok -d delombok Bug.java; cat delombok/Bug.java

// Generated by delombok at Tue Oct 18 14:22:08 EDT 2011
public class Bug<T> {
public final class Inner {
public int foo;

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Inner)) return false;
        final Inner other = (Inner)o;
        if (this.foo != other.foo) return false;
        return true;
    }

    @ java.lang.Override
    @ java.lang.SuppressWarnings(&quot;all&quot;)
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = result * PRIME + this.foo;
        return result;
    }
}

}

$ javac -classpath lombok.jar delombok/Bug.java

delombok/Bug.java:14: illegal generic type for instanceof
if (!(o instanceof Inner)) return false;
^
1 error

$ java -jar ecj.jar -source 1.6 delombok/Bug.java

  1. ERROR in delombok/Bug.java (at line 14)
    if (!(o instanceof Inner)) return false;
    ^^^^^^^^^^^^^^^^^^^^
    Cannot perform instanceof check against parameterized type Bug<T>.Inner.
    Use the form Bug.Inner instead since further generic type information
    will be erased at runtime

    1 problem (1 error)

What version of the product are you using? On what operating system?

Lombok version: 0.10.1-EDGE 2011-09-20 18:50 UTC
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2)
OpenJDK Server VM (build 19.0-b09, mixed mode)
Ubuntu Lucid (10.04).

Please provide any additional information below.

The fix suggested by ECJ is s/Inner/Bug.Inner/ on instanceof, as in:
if (!(o instanceof Bug.Inner)) return false;
but perhaps using Bug<?>.Inner to be as specific as possible would be best.

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 jwnimmer@jaybridge.com   🕗 Oct 18, 2011 at 18:39 UTC

Two more notes:

  1. Obviously, this only happens with a generically-typed outer class.
  2. When the inner class is non-final, the canEqual method's instanceof
    check encounters the same problem.
Collaborator

lombokissues commented Jul 14, 2015

👤 jwnimmer@jaybridge.com   🕗 Oct 18, 2011 at 18:39 UTC

Two more notes:

  1. Obviously, this only happens with a generically-typed outer class.
  2. When the inner class is non-final, the canEqual method's instanceof
    check encounters the same problem.
@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 pe.fips   🕗 Oct 19, 2011 at 21:53 UTC

Good find!

Collaborator

lombokissues commented Jul 14, 2015

👤 pe.fips   🕗 Oct 19, 2011 at 21:53 UTC

Good find!

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 reinierz   🕗 Oct 25, 2011 at 13:06 UTC

Very good find. I'd make the case that this is a javac bug, actually, but ecj agrees with javac, so, maybe it's just a boneheaded part of the spec.

Nevertheless, we can fix this by always fully specifying the full chain (Outer.Inner.Innerer.Innermost). Seems easy enough.

Collaborator

lombokissues commented Jul 14, 2015

👤 reinierz   🕗 Oct 25, 2011 at 13:06 UTC

Very good find. I'd make the case that this is a javac bug, actually, but ecj agrees with javac, so, maybe it's just a boneheaded part of the spec.

Nevertheless, we can fix this by always fully specifying the full chain (Outer.Inner.Innerer.Innermost). Seems easy enough.

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

👤 reinierz   🕗 Oct 25, 2011 at 17:39 UTC

Fixed in 16661be for both eclipse and javac (it was broken in both).

Collaborator

lombokissues commented Jul 14, 2015

👤 reinierz   🕗 Oct 25, 2011 at 17:39 UTC

Fixed in 16661be for both eclipse and javac (it was broken in both).

@lombokissues

This comment has been minimized.

Show comment
Hide comment
@lombokissues

lombokissues Jul 14, 2015

Collaborator

End of migration

Collaborator

lombokissues commented Jul 14, 2015

End of migration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment