[lworld] RFR: Make "PrimitiveParameterizedClass.default" a poly expression. [v2]

Srikanth Adayapalam sadayapalam at openjdk.java.net
Mon Jul 19 08:26:05 UTC 2021

On Sun, 4 Jul 2021 19:18:51 GMT, Jesper Steen Møller <jespersm at openjdk.org> wrote:

>> Make .default a separate node type in the parser.
>> ## Issue
>> [JDK-8211914](https://bugs.openjdk.java.net/browse/JDK-8211914): [lworld] Javac should support type inference for default value creation
>> Note: The Linux x86 builds in GitHub actions seem to fail with something completely unrelated to these changes.
> Jesper Steen Møller has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains one commit:
>   [lworld] Handling poly-inference of missing arguments by simulating a synthetic method.

Hello Jesper, this latest patch is problematic. it does not properly treat Foo.default as a poly expression. As Maurizio's earlier review comments points out: 

I don't see how this approach can scale to default expression passed as method arguments - given that in that case there is no pt(). To add support for that you need to add another case/node in ArgumentAttr (see what's been done for anonymous inner classes - this should be simpler as there's no constructor call).

In other words, you want Attr.visitApply to treat your default expression method argument in a special way - by creating what we call a "deferred type" - that is a type that is not fully inferred until after overload resolution (when you DO know the pt()).

I don't see the relevant code changes in your change set - i.e there is no changes in ArgumentAttr {} - I would have expected to see a visitDefaultValue method there.

As Maurizio further pointed out earlier, in Attr.visitApply, right after arguments are attributed, the type of Foo.default as a method argument should be a deferred type . If I debug the uploaded patch, the type of Foo.default is actually Foo<T>

The problem is masked by there being only negative tests in your patch.

If I compile the following:

public primitive class X<T> {

    static void m(X<String> ls) { }

    public static void main(String [] args) {
        m(new X<>()); // OK
        m(X<String>.default); // OK.
        m(X.default);   // OK, BUT get an error here!


at the line with the .default usage I get:

 error: incompatible types: X<T> cannot be converted to X<String>
  where T is a type-variable:
    T extends Object declared in class X
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

This shows that there is no real inference happening there.

(when a poly type argument is attributed without a target type in context, it should be typed to be DeferredType, when considered against overload candidates the positional parameter type becomes the pt() and the deferred type can now be typed to a concrete type)


PR: https://git.openjdk.java.net/valhalla/pull/369

More information about the valhalla-dev mailing list