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

Mark Mahieu markmahieu at gmail.com
Sun Jan 5 08:54:35 UTC 2020


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