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.
javac -processor nullness L1.java(plain javac accepts it):With
-AconvertTypeArgInferenceCrashToWarning=false, the exception is thrown from:With a lambda,
.thenComparing(s -> s.other()), the checker crashes outright:.thenComparing(s -> s.other())Suboverridesname().thenComparing(Sub::name)orBase::nameComparator<Sub> c1 = Comparator.comparing(Sub::name); c1.thenComparing(Sub::other).reversed()Found in spring-framework,
spring-core/.../aot/hint/ExecutableHint.java:100:Comparator.comparing(ExecutableHint::getName, …).thenComparing(ExecutableHint::getParameterTypes, …), wheregetNameis declared in the superclassMemberHint.