JDK-8219318 (???): inferred type does not conform to upper bound(s) when collecting to a HashMap
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Dec 16 16:40:33 UTC 2019
On 16/12/2019 16:30, B. Blaser wrote:
> On Mon, 16 Dec 2019 at 16:29, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>>
>> On 16/12/2019 15:09, B. Blaser wrote:
>>> On Mon, 16 Dec 2019 at 15:00, Maurizio Cimadamore
>>> <maurizio.cimadamore at oracle.com> wrote:
>>>> On 14/12/2019 14:14, B. Blaser wrote:
>>>>> Thanks for your feedback, Maurizio.
>>>>>
>>>>> Using a lacunal inference mechanism during overload resolution would
>>>>> definitely lead to inconsistencies like this.
>>>>>
>>>>> Moreover, JLS §15.12.2.2 [1] is about applicability by strict
>>>>> invocation and our example refers to applicability by loose invocation
>>>>> (§15.12.2.3 [2]):
>>>>>
>>>>> "If m is a generic method and the method invocation does not provide
>>>>> explicit type arguments, then the applicability of the method is
>>>>> inferred as specified in §18.5.1."
>>>> Same process applies - the subsequent sections e.g. 15.12.2.3 are only applied when previous steps have failed:
>>>>
>>>> "If no method applicable by strict invocation is found, the search for applicable methods continues with phase 2 (§15.12.2.3)." - so the pertinent to applicability analysis is really the same for all steps.
>>> Well, if I apply these rules to our example, javac shouldn't find any
>>> applicable method by strict invocation (§15.12.2.2) but it should then
>>> find one by loose invocation (§15.12.2.3) inferring it correctly.
>> How can it infer it correctly in 15.12.2.3? The arguments are still not
>> pertinent to applicability - hence, you will end up with same result
>> (lack of constraints).
> So, let's go step by step following the JLS:
>
> 1) "15.12.2.2. Phase 1: Identify Matching Arity Methods Applicable by
> Strict Invocation"
>
> 2) "An argument expression is considered pertinent to applicability
> for a potentially applicable method m unless it has one of the
> following forms:"
>
> 3) "An inexact method reference expression (§15.13.1)."
>
> => 'HashMap::new' isn't pertinent to applicability by strict invocation.
>
> 4) "If no method applicable by strict invocation is found, the search
> for applicable methods continues with phase 2 (§15.12.2.3)."
>
> 5) "15.12.2.3. Phase 2: Identify Matching Arity Methods Applicable by
> Loose Invocation"
>
> 6) "If m is a generic method and the method invocation does not
> provide explicit type arguments, then the applicability of the method
> is inferred as specified in §18.5.1."
Note that this applied also to 15.12.2.2 - all the paragraphs
15.12.2.2/3/4 - are meant to be applied in sequence - they are literally
the same logic (esp. the first two), just with a different check context
(strict vs. loose vs. varargs). So I don't get why you believe that
'pertinent to applicability' applies to 15.12.2.2 but not to 15.12.2.3 ?
In any case, inside 18.5.1 you will find that constraints are only set
up for arguments that are pertinent to applicability:
"A set of constraint formulas, C, is generated as follows.
Let F1, ..., Fn be the formal parameter types of m, and let e1, ..., ek
be the actual argument expressions of the invocation. Then:
To test for applicability by strict invocation:
If k ≠ n, or if there exists an i (1 ≤ i ≤ n) such that ei is
pertinent to applicability (§15.12.2.2) and either (i) ei is a
standalone expression of a primitive type but Fi is a reference type, or
(ii) Fi is a primitive type but ei is not a standalone expression of a
primitive type; then the method is not applicable and there is no need
to proceed with inference.
Otherwise, C includes, for all i (1 ≤ i ≤ k) where ei is pertinent
to applicability, ‹ei → Fi θ›.
To test for applicability by loose invocation:
If k ≠ n, the method is not applicable and there is no need to
proceed with inference.
Otherwise, C includes, for all i (1 ≤ i ≤ k) where ei is pertinent
to applicability, ‹ei → Fi θ›.
To test for applicability by variable arity invocation:
Let F'1, ..., F'k be the first k variable arity parameter types of
m (§15.12.2.4). C includes, for all i (1 ≤ i ≤ k) where ei is pertinent
to applicability, ‹ei → F'i θ›.
"
Which again leaves us in a position where no useful constraint can be
derived from HashMap::new
Maurizio
>
> => if the overload inference includes constraints from 'HashMap::new'
> as suggested in the fix, the method would be pertinent to
> applicability.
>
> Did I miss anything?
>
>>> The current behavior is a dubious mixture of these two steps; instead
>>> of performing a clear strict invocation applicability check, javac
>>> simply truncate the inference process concluding to the
>>> non-applicability of the candidate.
>>>
>>> Of course, this is only my modest interpretation of the JLS.
>>> So, would you like me to close it as "not an issue"?
>> Sure, unless I'm missing something of what you are trying to say above.
> Up to you to conclude, should I close it?
>
> Thanks,
> Bernard
More information about the compiler-dev
mailing list