scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Scala 3 does not take arbitrary id in pattern @ binding

Open som-snytt opened this issue 3 years ago • 2 comments

Compiler version

3.1.3

Minimized code

Welcome to Scala 3.1.3 (18.0.1.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> List(42) match { case List(h, rest @ _*) => (h, rest) case _ => }
val res0: Matchable = (42,List())

scala> List(42) match { case List(h, Rest @ _*) => (h, Rest) case _ => }
-- [E006] Not Found Error: ---------------------------------------------------------------------------------------------
1 |List(42) match { case List(h, Rest @ _*) => (h, Rest) case _ => }
  |                              ^^^^
  |                              Not found: Rest
  |
  | longer explanation available when compiling with `-explain`
-- [E006] Not Found Error: ---------------------------------------------------------------------------------------------
1 |List(42) match { case List(h, Rest @ _*) => (h, Rest) case _ => }
  |                                                ^^^^
  |                                                Not found: Rest
  |
  | longer explanation available when compiling with `-explain`
2 errors found

Expectation

Welcome to Scala 2.13.8 (OpenJDK 64-Bit Server VM, Java 18.0.1.1).
Type in expressions for evaluation. Or try :help.

scala> List(42) match { case List(h, rest @ _*) => (h, rest) case _ => }
val res0: Any = (42,List())

scala> List(42) match { case List(h, Rest @ _*) => (h, Rest) case _ => }
val res1: Any = (42,List())

scala> List(42) match { case List(h, Nil @ _*) => (h, Nil) case _ => }
val res2: Any = (42,List())

scala> List(42) match { case List(h, `Nil` @ _*) => (h, Nil) case _ => }
val res3: Any = (42,List())

scala> List(42) match { case List(h, `other things` @ _*) => (h, `other things`) case _ => }
val res4: Any = (42,List())

This syntax upgrade was introduced in https://github.com/scala/scala/pull/4935

som-snytt avatar Jul 28 '22 16:07 som-snytt

@odersky Do you think the change introduced to Scala2 was intended and should we port it to Scala 3? In my opinion, current behavior is an improvement as we typically expected capitalized names to be a constant value.

WojciechMazur avatar Aug 04 '22 09:08 WojciechMazur

The pre-dotty ticket was https://github.com/scala/bug/issues/8044

The original use case was generated code, but the idea is that in id @ the id is just an id not a pattern. It's also useful for real people to introduce names such as type and Type.

Then x @ _: X is not simply x: X where varid is required. Scala 2 warnings also treat x @ _ syntax as special to mean don't warn if the x is unused, to treat the x as documentary.

Scala 2 also accepts backticked varid:

42 match { case `type` : Int => `type` }

as opposed to

scala> 42 match { case `Junk`: Int => Junk }
                             ^
       error: Pattern variables must start with a lower-case letter. (SLS 8.1.1.)

Test file at https://github.com/scala/scala/blob/2.13.x/test/files/pos/t8044.scala

som-snytt avatar Aug 04 '22 15:08 som-snytt

This was not intentional. We should keep the Scala 2 rules here.

odersky avatar Jul 12 '23 13:07 odersky