[patterns] Redefinition of pattern variable is allowed by javac in some cases

Brian Goetz brian.goetz at oracle.com
Sun Jan 5 15:02:16 UTC 2020


Heh, was just about to point you to that.  In the table "Scoping of 
pattern variables", the 6th row covers conditionals -- I suspect it 
probably covers everything you want.

On 1/5/2020 3:54 AM, Mark Mahieu wrote:
> Just to follow up on my own question re future directions, I think I’ll find what I'm after with a more careful reading of https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html <https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html>
>
> Mark
>
>
>> On 5 Jan 2020, at 07:15, Mark Mahieu <markmahieu at gmail.com> wrote:
>>
>> Hi.
>>
>> I just bumped into a variant of that one with 14-ea-29, whilst musing on how the ? : operator might take further advantage of pattern matching.  My example actually used the pattern variable inside a branch, but I expect it’s the same apparent discrepancy between javac and the draft spec.
>>
>> That draft also suggests that more sophisticated rules may be considered in future for some conditional statements (e.g. the last sentence in 6.3.1.4).  I imagine this was discussed at some point (and I guess, parked for now) but I’ve had no luck searching the archives - any pointers would be gratefully received :)
>>
>> Mark
>>
>>
>>> On 26 Dec 2019, at 11:34, Tagir Valeev <amaembo at gmail.com> wrote:
>>>
>>> Another shadowing case:
>>>
>>> class Test {
>>> static void test(Object o1, Object o2, Object o3) {
>>>    boolean b1 = o1 instanceof String s ? o2 instanceof String s : o3
>>> instanceof String s;
>>> }
>>> }
>>>
>>> Also happily compiled by javac. If I understand correctly the spec
>>> draft, 6.3.1.4 [1], this should be rejected:
>>>
>>> The following rules apply to a conditional expression a ? b : c:
>>> ...
>>> A pattern variable is introduced both by a when true, and by c when true.
>>> ...
>>> A pattern variable is introduced both by b when true, and by c when true.
>>>
>>> Am I missing something?
>>>
>>> With best regards,
>>> Tagir Valeev.
>>>
>>> [1] http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html#jls-6.3.1.4
>>>
>>> On Thu, Dec 26, 2019 at 5:10 PM Tagir Valeev <amaembo at gmail.com> wrote:
>>>> Hello!
>>>>
>>>> Playing with javac 14-ea+28-1366. This code can be successfully compiled:
>>>>
>>>> class Test {
>>>> static void test(Object o1, Object o2) {
>>>>      boolean b = o1 instanceof String s && (!(o2 instanceof String s)
>>>> || consume(s));
>>>> }
>>>>
>>>> static boolean consume(String s) {
>>>>     System.out.println(s);
>>>>     return true;
>>>> }
>>>>
>>>> public static void main(String[] args) {
>>>>    test("x", "y"); // prints y
>>>> }
>>>> }
>>>>
>>>> Spec draft says for `a || b`:
>>>> It is a compile-time error if any pattern variable introduced by a
>>>> when false is already in scope at b.
>>>>
>>>> If I understand correctly, assuming a = !(o2 instanceof String s) and
>>>> b = consume(s), we already have `s` (from `o1 instanceof String s`) in
>>>> the scope at b, and a introduces new `s` when false, so this code
>>>> should be rejected. Please correct me if I am wrong.
>>>>
>>>> With best regards,
>>>> Tagir Valeev.



More information about the amber-dev mailing list