
Type: Bug

Status: Closed

Priority: P4

Resolution: Duplicate

Affects Version/s: 7

Fix Version/s: None

Component/s: specification

Labels:None

Subcomponent:

CPU:unknown

OS:generic
Consider the following class hierarchy:
class A{ public void a(){}}
class B extends A{ public void b(){}}
interface I{ void i();}
class E extends B implements I{ public void i(){};}
class C<W extends B & I, T extends W>{
public T fieldT; }
Question: What is the capture of C<? extends I, ? extends E> ?
It's C<#1. #2>, where both #1 and #2 are capturedtype variables. According to JLS3 5.1.10, we have that:
upperbound(#1) = glb(I, B&I) = B&I
upperbound(#2) = glb(E, #1) = E & #1 (in eval of 6594284 I stated that this glb was incorrect)
Are #1, #2 conform to declared bounds?
a) #1 <: B&I, ok (since #1 <: upperbound(#1) = B&I <: B&I)
b) #2 <: I, ok (since #2 <: upperbound(#2) = E&I <: I)
At first it seems like everything is correct  however reading 5.1.10 it's not crystal clear to understand what the desired behavior should look like:
"If Ti is a wildcard type argument of the form ? extends Bi, then Si is a fresh type variable whose upper bound is glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is a compiletime error if for any two classes (not interfaces) Vi and Vj,Vi is not a subclass of Vj or vice versa"
I think the problem is all in the sentence *if for any two classes (not interfaces)* ; here we have to compute a glb between a classtype (namely E) and a capturedtypevariable (namely #1)  which rules should we apply? This is not clear as #1 is neither a class nor an interface.
Note: enforcing that either #1 <: E or E <: #1 will result in flagging the above captureconversion as erroneous as neither of the two subtyping assumptions hold:
Is either #CAP1 <: E or E <: #CAP1 ?
a) #1 <: E iff
ub(#1) = B&I <: E > false
b) E <: #1 false
Note that we don't have (as you say) that #1 = B&I, we have that #1's upper bound is B&I which is different.
The above subtyping test would hold only if you assume the following rule:
S <: T iff S <: ub(T)
which is unsafe (e.g. Integer <: T, where T is a typevariable whose bound is Object).
I don't see how the subtyping between E and #1 could be justified in term of the JLS.
class A{ public void a(){}}
class B extends A{ public void b(){}}
interface I{ void i();}
class E extends B implements I{ public void i(){};}
class C<W extends B & I, T extends W>{
public T fieldT; }
Question: What is the capture of C<? extends I, ? extends E> ?
It's C<#1. #2>, where both #1 and #2 are capturedtype variables. According to JLS3 5.1.10, we have that:
upperbound(#1) = glb(I, B&I) = B&I
upperbound(#2) = glb(E, #1) = E & #1 (in eval of 6594284 I stated that this glb was incorrect)
Are #1, #2 conform to declared bounds?
a) #1 <: B&I, ok (since #1 <: upperbound(#1) = B&I <: B&I)
b) #2 <: I, ok (since #2 <: upperbound(#2) = E&I <: I)
At first it seems like everything is correct  however reading 5.1.10 it's not crystal clear to understand what the desired behavior should look like:
"If Ti is a wildcard type argument of the form ? extends Bi, then Si is a fresh type variable whose upper bound is glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is a compiletime error if for any two classes (not interfaces) Vi and Vj,Vi is not a subclass of Vj or vice versa"
I think the problem is all in the sentence *if for any two classes (not interfaces)* ; here we have to compute a glb between a classtype (namely E) and a capturedtypevariable (namely #1)  which rules should we apply? This is not clear as #1 is neither a class nor an interface.
Note: enforcing that either #1 <: E or E <: #1 will result in flagging the above captureconversion as erroneous as neither of the two subtyping assumptions hold:
Is either #CAP1 <: E or E <: #CAP1 ?
a) #1 <: E iff
ub(#1) = B&I <: E > false
b) E <: #1 false
Note that we don't have (as you say) that #1 = B&I, we have that #1's upper bound is B&I which is different.
The above subtyping test would hold only if you assume the following rule:
S <: T iff S <: ub(T)
which is unsafe (e.g. Integer <: T, where T is a typevariable whose bound is Object).
I don't see how the subtyping between E and #1 could be justified in term of the JLS.
 duplicates

JDK8039222 5.1.10: Define glb for nonclass types
 Open
 relates to

JDK6594284 NPE thrown when calling a method on an intersection type
 Closed