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

Tagir Valeev amaembo at gmail.com
Thu Dec 26 10:34:47 UTC 2019


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