RFR: 8367530: The exhaustiveness errors could be improved [v8]

Jan Lahoda jlahoda at openjdk.org
Wed Nov 19 16:25:08 UTC 2025


On Fri, 14 Nov 2025 13:28:29 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Jan Lahoda has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Fixing trailing whitespaces.
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java line 832:
> 
>> 830:                                                     Set.of(defaultPattern));
>> 831:         } catch (TimeoutException ex) {
>> 832:             return ex.missingPatterns != null ? ex.missingPatterns : Set.of();
> 
> Instead of a timeout, I wonder if you could instead cut the recursion at a specific threshold. It seems to me that recursing more will provide more precision _at the nested level_, so it's a trade off between when do we want to stop. 
> 
> Overload resolution provides some kind of precedent:
> 
> 
> error: incompatible types: String cannot be converted to int
>       m("Hello");
>         ^
> Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
> 1 error
> 
> 
> (We "compress" the diagnostic whenever we can somehow figure out if an overload is "better" than the others). Then if you provide the option, you get the full thing:
> 
> 
> error: no suitable method found for m(String)
>       m("Hello");
>       ^
>     method Test.m() is not applicable
>       (actual and formal argument lists differ in length)
>     method Test.m(int) is not applicable
>       (argument mismatch; String cannot be converted to int)
>     method Test.m(int,int) is not applicable
>       (actual and formal argument lists differ in length)
>     method Test.m(int,int,int) is not applicable
>       (actual and formal argument lists differ in length)
>     method Test.m(int,int,int,int) is not applicable
>       (actual and formal argument lists differ in length)
>     method Test.m(int,int,int,int,int) is not applicable
>       (actual and formal argument lists differ in length)
>     method Test.m(int,int,int,int,int,int) is not applicable
>       (actual and formal argument lists differ in length)
> 
> 
> But, also, maybe putting an upper bound on the recursion, no matter what, might be a good idea?

While I agree that having a timeout in weird/non-standard in javac, I believe it is the first time when we have a process that a) can run for a very long time; b) is not required for correctness. In all other cases I can recall, if some process is slow (including e.g. verifying exhaustiveness), then it is required for correctness. And so we cannot skip it based on criteria like time.

The timeout here provides a way to say how much real-world time is the user willing to invest to get the outcome - if more time is invested, more detailed missing patterns may possibly be computed. It is a somewhat weird approach for javac, but it is a limit that (I think) the user and javac can agree on.

We could introduce a limit on e.g. the depth to which we expand, but adding one level of nesting may affect performance significantly or almost not at all, depending on e.g. the record type form/shape.

E.g. having a record with many components, where each component is a sealed type with many permitted subtypes, one level of nesting may lead to a high number of newly generated patterns possibly taking a lot of time to go through them. But having a record that has a single component that is not a sealed type should only generate one pattern, and so have minimal impact.

> test/langtools/tools/javac/patterns/ExhaustivenessConvenientErrors.java line 290:
> 
>> 288:                            case Triple(_, _, A _) -> 0;
>> 289:                            case Triple(A p, C(Nested _, NestedBaseA _), _) -> 0;
>> 290:                            case Triple(A p, C(Nested _, NestedBaseB _), C(Underneath _, NestedBaseA _)) -> 0;
> 
> Where is `Underneath` defined?

That's a mistake, it should be `Nested`. Fixed here:
https://github.com/openjdk/jdk/pull/27256/commits/08fdb6d93ea721541a16b3e1456606dc13198136
Thanks!

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27256#discussion_r2542699544
PR Review Comment: https://git.openjdk.org/jdk/pull/27256#discussion_r2542702684


More information about the compiler-dev mailing list