Skip to content

Type argument inference crash when a call with an inherited-method reference argument is the receiver of a chained call #2163

Description

@aosen-xiong
import java.util.Comparator;

class L1 {
    static class Base {
        String name() {
            return "";
        }
    }

    static class Sub extends Base {
        String other() {
            return "";
        }
    }

    Comparator<Sub> c = Comparator.comparing(Sub::name).thenComparing(Sub::other);
}

javac -processor nullness L1.java (plain javac accepts it):

L1.java:16: error: [type.argument.inference.crashed] Type argument inference crashed for Comparator.thenComparing
    Comparator<Sub> c = Comparator.comparing(Sub::name).thenComparing(Sub::other);
                                                                     ^
  error: An exception occurred:  False bound for: Constraint: Base <: Sub Result: FALSE

With -AconvertTypeArgInferenceCrashToWarning=false, the exception is thrown from:

FalseBoundException: False bound for: Constraint: Base <: Sub Result: FALSE
  at ...typeinference8.constraint.ConstraintSet.reduceOneStep(ConstraintSet.java:458)
  at ...typeinference8.constraint.ConstraintSet.reduce(ConstraintSet.java:391)
  at ...typeinference8.InvocationTypeInference.createB2(InvocationTypeInference.java:279)
  at ...typeinference8.InvocationTypeInference.infer(InvocationTypeInference.java:167)
  at ...typeinference8.DefaultTypeArgumentInference.inferTypeArgs(DefaultTypeArgumentInference.java:108)

With a lambda, .thenComparing(s -> s.other()), the checker crashes outright:

error: AsSuperVisitor: type is not an erased subtype of supertype.
  type: Base
  superType: Sub
  ; The Checker Framework crashed.  Please report the crash.
  	at org.checkerframework.framework.type.AsSuperVisitor.errorTypeNotErasedSubtypeOfSuperType(AsSuperVisitor.java:152)
Variant Result
as above crash
.thenComparing(s -> s.other()) AsSuperVisitor crash
Sub overrides name() no crash
.thenComparing(Sub::name) or Base::name no crash
Comparator<Sub> c1 = Comparator.comparing(Sub::name); c1.thenComparing(Sub::other) no crash
.reversed() no crash

Found in spring-framework, spring-core/.../aot/hint/ExecutableHint.java:100: Comparator.comparing(ExecutableHint::getName, …).thenComparing(ExecutableHint::getParameterTypes, …), where getName is declared in the superclass MemberHint.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions