JDK-8160114 : Unexpected inferred type from wildcard subtyping constraint
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • Submitted: 2016-06-22
  • Updated: 2016-09-09
  • Resolved: 2016-09-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorResolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
This should compile, does not:

    interface I<X> {}
    <T> T make(I<T> ts) { return null; }
    <E extends CharSequence> E take(I<? extends E> arg) { return null; }

    void test(I<I<? extends String>> arg) {
        take(make(arg)).intern();
    }

Inference succeeds, with E=CharSequence. The call to 'intern' then fails. Expected: infer E=String.

Walking through expected inference behavior:

Applicability inference for 'make':
I<I<? extends String>> --> I<t>
{ t = I<? extends String> }

Applicability inference for 'take':
make(arg) --> I<? extends e>
t --> I<? extends e>
{ t = I<? extends String>, t <: I<? extends e>, e <: CharSequence }

Incorporation:
I<? extends String> <: I<? extends e>
{ t = I<? extends String>, t <: I<? extends e>, String <: e, e <: CharSequence }

Resolution:
e = String, t = I<? extends String>
Comments
Another test: import java.util.concurrent.Callable; import java.util.stream.Stream; public class A { public static <E extends Exception> void x_noTW(Callable<? extends E>... actions) throws E { A.x(Stream.of(actions)); } public static <E extends Exception> void x(Stream<Callable<? extends E>> actions) throws E { } }
22-06-2016

Began failing with JDK-8033718, which addressed another bug that was masking this issue.
22-06-2016

It's likely that this constraint is part of the problem: I<? extends String> <: I<? extends e> If we perform capture on the LHS, we end up with CAP <: e, but I<? extends String> </: I<? extends CAP> This spec issue is raised in JDK-8016196. However, if that's what javac is doing, it should either resolve e = CAP or produce an applicability failure. Not clear why it's resolving e = CharSequence.
22-06-2016