RFR: 8325859: potential information loss during type inference [v3]

Maurizio Cimadamore mcimadamore at openjdk.org
Thu May 15 16:39:57 UTC 2025


On Fri, 2 May 2025 20:28:06 GMT, Vicente Romero <vromero at openjdk.org> wrote:

>> When an inference context (`IC`) is minimized, the minimized inference context (`MIC`) contains a proper subset of `IC's` inference vars (`IC_IV`). In other words there will be at least one inference variable `T` that belongs to `IC_IV` which doesn't belong to the minimized context inference variable's set (`MIC_IV`). MIC can be propagated to another inference context (AIC) as part of the type inference algo. If at any moment a type containing `T` needs, for example, to be instantiated `AIC` won't be able to perform that operation as it lacks the information to realize that `T` is a free variable it was supposed to know about hadn't a minimization step been performed. This PR is proposing to fix this issue without reducing the universe of inference contexts we apply the minimization algo to.
>> 
>> We are basically proposing to add a field to class InferenceContext which will be supplementary inference context that can be used to look for additional information if necessary. Also when registering a free type listener to an inference context, it could be that it won't be registered in the inference context the client could expect but in a supplementary inference context if it is found out that it contains and instantiation to all the free variables related to the listener. See also some comments inlined in the code,
>> 
>> TIA
>
> Vicente Romero has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision:
> 
>  - Merge branch 'master' into JDK-8325859
>  - make visitor static
>  - updating doc
>  - 8325859: potential information loss during type inference

I think I see the problem now. I believe the issue is in `Check::checkMethod`. That method does this at the start:


if (inferenceContext.free(mtype)) {
            inferenceContext.addFreeTypeListener(List.of(mtype),
                    solvedContext -> checkMethod(solvedContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, solvedContext));
            return mtype;
        }


This is correct -- if `mtype` has some free type variable, we need to come back later and re-run this again (to set the correct type on the AST).

But there's an issue -- if we propagate (`Infer::shouldPropagate` is `true`), then the input inference context is NOT the inference context for the call being checked (in this case `supplyNull`) but the outer context, which contains the propagated vars.

While this was correct before the introduction of context minimization -- because in such case outer inference contexts were always strict supersets of nested inference contexts "contained", this is no longer true with minimization: we can have an outer context that omits some variables from the nested context. At which point, the listener above will "miss the memo" -- e.g. it will instantiate the method type using the outer context inferred vars -- but this will still leave "holes" (because the outer context will not contain all the variables that can appear in `mtype`).

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

PR Comment: https://git.openjdk.org/jdk/pull/25011#issuecomment-2884441846


More information about the compiler-dev mailing list