Skip to content

Commit 959cab4

Browse files
authored
Merge pull request #9837 from dotty-staging/fix-#9829
Fix #9829: Allow `as` in place of `@` for pattern bindings
2 parents 246fc89 + c9caa7e commit 959cab4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+77
-73
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -2618,7 +2618,10 @@ object Parsers {
26182618
/** Pattern2 ::= [id `@'] InfixPattern
26192619
*/
26202620
val pattern2: () => Tree = () => infixPattern() match {
2621-
case p @ Ident(name) if in.token == AT =>
2621+
case p @ Ident(name) if in.token == AT || in.isIdent(nme.as) =>
2622+
if in.token == AT && sourceVersion.isAtLeast(`3.1`) then
2623+
deprecationWarning(s"`@` bindings have been deprecated; use `as` instead", in.offset)
2624+
26222625
val offset = in.skipToken()
26232626

26242627
// compatibility for Scala2 `x @ _*` syntax
@@ -2646,7 +2649,8 @@ object Parsers {
26462649
/** InfixPattern ::= SimplePattern {id [nl] SimplePattern}
26472650
*/
26482651
def infixPattern(): Tree =
2649-
infixOps(simplePattern(), in.canStartExprTokens, simplePattern, isOperator = in.name != nme.raw.BAR)
2652+
infixOps(simplePattern(), in.canStartExprTokens, simplePattern,
2653+
isOperator = in.name != nme.raw.BAR && in.name != nme.as)
26502654

26512655
/** SimplePattern ::= PatVar
26522656
* | Literal

docs/docs/internals/syntax.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ TypeCaseClause ::= ‘case’ InfixType ‘=>’ Type [nl]
273273
Pattern ::= Pattern1 { ‘|’ Pattern1 } Alternative(pats)
274274
Pattern1 ::= Pattern2 [‘:’ RefinedType] Bind(name, Typed(Ident(wildcard), tpe))
275275
| ‘given’ PatVar ‘:’ RefinedType
276-
Pattern2 ::= [id ‘@’] InfixPattern Bind(name, pat)
276+
Pattern2 ::= [id ‘as’] InfixPattern Bind(name, pat)
277277
InfixPattern ::= SimplePattern { id [nl] SimplePattern } InfixOp(pat, op, pat)
278278
SimplePattern ::= PatVar Ident(wildcard)
279279
| Literal Bind(name, Ident(wildcard))

library/src-bootstrapped/dotty/internal/StringContextMacro.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ object StringContextMacro {
6262
val sourceFile = strCtxExpr.unseal.pos.sourceFile
6363

6464
val (partsExpr, parts) = strCtxExpr match {
65-
case Expr.StringContext(p1 @ Consts(p2)) => (p1.toList, p2.toList)
65+
case Expr.StringContext(p1 as Consts(p2)) => (p1.toList, p2.toList)
6666
case _ => report.throwError("Expected statically known String Context", strCtxExpr)
6767
}
6868

library/src-bootstrapped/scala/internal/quoted/Matcher.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ object Matcher {
244244

245245
/* Term hole */
246246
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
247-
case (scrutinee @ Typed(s, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
247+
case (scrutinee as Typed(s, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
248248
if patternHole.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_patternHole &&
249249
s.tpe <:< tpt.tpe &&
250250
tpt2.tpe.derivesFrom(defn.RepeatedParamClass) =>
@@ -259,7 +259,7 @@ object Matcher {
259259

260260
/* Higher order term hole */
261261
// Matches an open term and wraps it into a lambda that provides the free variables
262-
case (scrutinee, pattern @ Apply(TypeApply(Ident("higherOrderHole"), List(Inferred())), Repeated(args, _) :: Nil))
262+
case (scrutinee, pattern as Apply(TypeApply(Ident("higherOrderHole"), List(Inferred())), Repeated(args, _) :: Nil))
263263
if pattern.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_higherOrderHole =>
264264

265265
def bodyFn(lambdaArgs: List[Tree]): Tree = {

library/src-bootstrapped/scala/quoted/util/ExprMap.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ trait ExprMap {
5151
tree
5252
case Super(qual, mix) =>
5353
tree
54-
case tree @ Apply(fun, args) =>
54+
case tree as Apply(fun, args) =>
5555
val MethodType(_, tpes, _) = fun.tpe.widen
5656
Apply.copy(tree)(transformTerm(fun, Type.of[Any]), transformTerms(args, tpes))
5757
case TypeApply(fun, args) =>

tests/init/crash/fors.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ object Test extends App {
2626
var n = 0
2727
for (_ <- xs) n += 1; println(n)
2828
for ((x, y) <- xs zip ys) print(x + " "); println()
29-
for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println()
29+
for (p as (x, y) <- xs zip ys) print(p._1 + " "); println()
3030

3131
// iterators
3232
for (x <- it) print(x + " "); println()
@@ -53,7 +53,7 @@ object Test extends App {
5353
var n = 0
5454
for (_ <- xs) n += 1; println(n)
5555
for ((x, y) <- xs zip ys) print(x + " "); println()
56-
for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println()
56+
for (p as (x, y) <- xs zip ys) print(p._1 + " "); println()
5757

5858
// iterators
5959
for (x <- it) print(x + " "); println()

tests/neg/Iter3.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ object Iter2 {
147147
flatten(map(f(_).buildIterator))
148148

149149
override def ++[B >: A](that: IterableOnce[B]): ArrayIterator[B] = {
150-
val thatIterator @ ArrayIterator(elems2, len2) = fromIterator(that.iterator)
150+
val thatIterator as ArrayIterator(elems2, len2) = fromIterator(that.iterator)
151151
if (len == 0) thatIterator
152152
else if (len2 == 0) this.asInstanceOf[ArrayIterator[B]]
153153
else {

tests/neg/ensureReported.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object AnonymousF {
22
val f = {
3-
case l @ List(1) => // error: missing parameter type
3+
case l as List(1) => // error: missing parameter type
44
Some(l)
55
}
66
}

tests/neg/i1716.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object Fail {
22
def f(m: Option[Int]): Unit = {
33
m match {
4-
case x @ Some[_] => // error: unbound wildcard type
4+
case x as Some[_] => // error: unbound wildcard type
55
case _ =>
66
}
77
}

tests/neg/i3200.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object Test {
22
case object Bob { override def equals(other: Any) = true }
33
def main(args: Array[String]): Unit = {
4-
val m : Bob.type = (5: Any) match { case x @ Bob => x } // error
4+
val m : Bob.type = (5: Any) match { case x as Bob => x } // error
55
}
66
}

tests/neg/i3200b.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
object Test {
22
def main(args: Array[String]): Unit = {
3-
val a: Nil.type = (Vector(): Any) match { case n @ Nil => n } // error
4-
val b: Nil.type = (Vector(): Any) match { case n @ (m @ Nil) => n } // error
5-
val c: Int = (1.0: Any) match { case n @ 1 => n } // error
6-
val d: Int = (1.0: Any) match { case n @ (m @ 1) => n } // error
3+
val a: Nil.type = (Vector(): Any) match { case n as Nil => n } // error
4+
val b: Nil.type = (Vector(): Any) match { case n as (m as Nil) => n } // error
5+
val c: Int = (1.0: Any) match { case n as 1 => n } // error
6+
val d: Int = (1.0: Any) match { case n as (m as 1) => n } // error
77
}
88
}

tests/neg/i3332.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ object Test {
1616
case _ => println("nope")
1717
}
1818
def test(x: Any) = x match {
19-
case _: String | _ @ A() => 1
19+
case _: String | _ as A() => 1
2020
}
2121
}

tests/neg/i3812b.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ object Test {
1919
Some(x) match { case Some(Z2.v) => () } // ok
2020

2121
Some(x) match { case Some(4) | Some(Z1.v) => () } // error
22-
Some(x) match { case a @ Some(Z1.v) => () } // error
22+
Some(x) match { case a as Some(Z1.v) => () } // error
2323

2424
Some(x) match { case Some(4) | Some(Z2.v) => () } // ok
25-
Some(x) match { case a @ Some(Z2.v) => () } // ok
25+
Some(x) match { case a as Some(Z2.v) => () } // ok
2626
}
2727
}

tests/neg/i8407.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
object Test:
22
val xs = List(1, 2, 3, 4, 5)
33
xs match {
4-
case List(1, 2, xs1 @ xs2: _*) => println(xs2) // error // error
4+
case List(1, 2, xs1 as xs2: _*) => println(xs2) // error // error
55
case _ => ()
66
}

tests/neg/i8715.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
@main
2-
def Test = List(42) match { case List(xs @ (ys: _*)) => xs } // error
2+
def Test = List(42) match { case List(xs as (ys: _*)) => xs } // error

tests/neg/i9310.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//AE-d101cfe6d25117a51897609e673f6c8e74d31e6e
2-
val foo @ this = 0
2+
val foo as this = 0
33
class Foo {
44
foo { } // error
55
}

tests/neg/multi-patterns.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
object Test {
22
val (a :: as), bs = List(1, 2, 3) // error
3-
val B @ List(), C: List[Int] = List() // error
3+
val B as List(), C: List[Int] = List() // error
44
}

tests/neg/patternUnsoundness.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object patternUnsoundness extends App {
1010
val y: C[Object] = x
1111

1212
y match {
13-
case d @ D(x) => d.s = new Integer(1) // error
13+
case d as D(x) => d.s = new Integer(1) // error
1414
}
1515

1616
val z: String = x.s // used to throw ClassCast exception

tests/pos/Iter2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ object Iter2 {
193193
flatten(map(f(_).buildIterator))
194194

195195
override def ++[B >: A](that: IterableOnce[B]): ArrayIterator[B] = {
196-
val thatIterator @ ArrayIterator(elems2, len2) = fromIterator(that.iterator)
196+
val thatIterator as ArrayIterator(elems2, len2) = fromIterator(that.iterator)
197197
if (len == 0) thatIterator
198198
else if (len2 == 0) this
199199
else {

tests/pos/i1540.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object Casey1 { def unapply(a: Casey1) = a }
88

99
object Test {
1010
def main(args: Array[String]): Unit = {
11-
val c @ Casey1(x) = new Casey1(0)
11+
val c as Casey1(x) = new Casey1(0)
1212
assert(x == c.get)
1313
}
1414
}

tests/pos/i1540b.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object Casey1 { def unapply[T](a: Casey1[T]) = a }
88

99
object Test {
1010
def main(args: Array[String]): Unit = {
11-
val c @ Casey1(x) = new Casey1(0)
11+
val c as Casey1(x) = new Casey1(0)
1212
assert(x == c.get)
1313
}
1414
}

tests/pos/i3412.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
class Test {
2-
val A @ List() = List()
2+
val A as List() = List()
33
}

tests/pos/i4177.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Test {
66
val a: PartialFunction[Int, String] = { case Foo(x) => x }
77
val b: PartialFunction[Int, String] = { case x => x.toString }
88

9-
val e: PartialFunction[String, String] = { case x @ "abc" => x }
9+
val e: PartialFunction[String, String] = { case x as "abc" => x }
1010
val f: PartialFunction[String, String] = x => x match { case "abc" => x }
1111
val g: PartialFunction[String, String] = x => x match { case "abc" if x.isEmpty => x }
1212

tests/pos/i4564.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object ClashNoSig { // ok
1010
def unapply(x: ClashNoSig) = x
1111

1212
ClashNoSig(2) match {
13-
case c @ ClashNoSig(y) => c.copy(y + c._1)
13+
case c as ClashNoSig(y) => c.copy(y + c._1)
1414
}
1515
}
1616
case class ClashNoSig private (x: Int) {

tests/pos/i5402.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object Main {
99
case 1 => 1
1010
case 0 | 0 => 0
1111
case 2 | 2 | 2 | 3 | 2 | 3 => 0
12-
case 4 | (_ @ 4) => 0
12+
case 4 | (_ as 4) => 0
1313
case _ => -1
1414
}
1515

tests/pos/simpleExtractors-2.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class Foo {
22
def bar(x: Any): Unit = x match {
33
case Some(Some(i: Int)) => println(i)
4-
case Some(s @ Some(i)) => println(s)
5-
case s @ Some(r @ Some(i)) => println(s)
4+
case Some(s as Some(i)) => println(s)
5+
case s as Some(r as Some(i)) => println(s)
66
}
77
}

tests/pos/t10533.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object Foo {
2-
val b @ Bar(_) = Bar(1)(2)(3)
2+
val b as Bar(_) = Bar(1)(2)(3)
33
}
44

55
case class Bar(a: Int)(b: Int)(c: Int)

tests/pos/t3136.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ object NullaryMethodType {
1313
object Test {
1414
def TEST(tp: Type): String =
1515
tp match {
16-
case PolyType(ps1, PolyType(ps2, res @ PolyType(a, b))) => "1" + tp // couldn't find a simpler version that still crashes
16+
case PolyType(ps1, PolyType(ps2, res as PolyType(a, b))) => "1" + tp // couldn't find a simpler version that still crashes
1717
case NullaryMethodType(meh) => "2" + meh
1818
}
1919
}

tests/pos/t6675.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object LeftOrRight {
77

88
object Test {
99
(Left((0, 0)): Either[(Int, Int), (Int, Int)]) match {
10-
case LeftOrRight(pair @ (a, b)) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)"
10+
case LeftOrRight(pair as (a, b)) => a // false -Xlint warning: "extractor pattern binds a single value to a Product2 of type (Int, Int)"
1111
}
1212

1313
(Left((0, 0)): Either[(Int, Int), (Int, Int)]) match {

tests/pos/trailingCommas/trailingCommas.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ trait SimplePattern {
114114

115115
// test '@' syntax in patterns
116116
Some(1) match {
117-
case Some(x @ 1,
117+
case Some(x as 1,
118118
) => x
119119
}
120120

tests/pos/virtpatmat_alts_subst.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
case class Foo(s: String) {
22
def appliedType(tycon: Any) =
33
tycon match {
4-
case Foo(sym @ ("NothingClass" | "AnyClass")) => println(sym)
4+
case Foo(sym as ("NothingClass" | "AnyClass")) => println(sym)
55
}
66
}

tests/run/3179.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object Test {
22
def main(args: Array[String]): Unit = {
33
("": Any) match {
4-
case a @ Test => 1
4+
case a as Test => 1
55
case _ => 2
66
}
77
}

tests/run/enums-serialization-compat.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,19 @@ extension (ref: AnyRef) def aliases(compare: AnyRef) = assert(ref eq compare, co
3131
val read = use(ByteArrayInputStream(buf.toByteArray))
3232
val in = use(ObjectInputStream(read))
3333

34-
val Seq(Red @ _, Green @ _, Blue @ _, Indigo @ _) = (1 to 4).map(_ => in.readObject)
34+
val Seq(Red as _, Green as _, Blue as _, Indigo as _) = (1 to 4).map(_ => in.readObject)
3535
Red aliases JColor.Red
3636
Green aliases SColor.Green
3737
Blue aliases SColorTagged.Blue
3838
Indigo aliases SColorTagged.Indigo
3939

40-
val Seq(A @ _, C @ _, G @ _, T @ _) = (1 to 4).map(_ => in.readObject)
40+
val Seq(A as _, C as _, G as _, T as _) = (1 to 4).map(_ => in.readObject)
4141
A aliases Nucleobase.A
4242
C aliases Nucleobase.C
4343
G aliases Nucleobase.G
4444
T aliases Nucleobase.T
4545

46-
val Seq(IntTag @ _, UnitTag @ _) = (1 to 2).map(_ => in.readObject)
46+
val Seq(IntTag as _, UnitTag as _) = (1 to 2).map(_ => in.readObject)
4747
IntTag aliases MyClassTag.IntTag
4848
UnitTag aliases MyClassTag.UnitTag
4949

tests/run/fors.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ object Test extends App {
2626
var n = 0
2727
for (_ <- xs) n += 1; println(n)
2828
for ((x, y) <- xs zip ys) print(x + " "); println()
29-
for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println()
29+
for (p as (x, y) <- xs zip ys) print(p._1 + " "); println()
3030

3131
// iterators
3232
for (x <- it) print(x + " "); println()
@@ -53,7 +53,7 @@ object Test extends App {
5353
var n = 0
5454
for (_ <- xs) n += 1; println(n)
5555
for ((x, y) <- xs zip ys) print(x + " "); println()
56-
for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println()
56+
for (p as (x, y) <- xs zip ys) print(p._1 + " "); println()
5757

5858
// iterators
5959
for (x <- it) print(x + " "); println()

tests/run/fully-abstract-interface.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object Test {
2020
const1 match {
2121
case AppliedOp(_, _, _) =>
2222
println("test1 fail")
23-
case c @ Constant(n) =>
23+
case c as Constant(n) =>
2424
println("test1 OK")
2525
println(s"$n = ${c.eval}")
2626
}
@@ -41,9 +41,9 @@ object Test {
4141
println(applied.eval)
4242

4343
applied match {
44-
case c @ Constant(n) =>
44+
case c as Constant(n) =>
4545
println("test3 fail")
46-
case a @ AppliedOp(op, x, y) =>
46+
case a as AppliedOp(op, x, y) =>
4747
println("test3 OK")
4848
println(s"AppliedOp($op, $x, $y) = ${a.eval}")
4949
}
@@ -304,7 +304,7 @@ object ListImplementation extends Arithmetic {
304304
def opClassTag: ClassTag[Op] = new ClassTag[Constant] {
305305
def runtimeClass: Class[_] = classOf[List[_]]
306306
override def unapply(x: Any): Option[List[Any]] = x match {
307-
case op @ (("+" | "*") :: Nil) =>
307+
case op as (("+" | "*") :: Nil) =>
308308
// Test that it is:
309309
// type Op <: List[Any] // List(id: "+" | "*")
310310
Some(op)

tests/run/fully-abstract-nat-1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object Test {
3232
}
3333

3434
def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match {
35-
case s @ Succ(_) =>
35+
case s as Succ(_) =>
3636
// s is of type Nat though we know it is a Succ
3737
Some(safeDiv(a, s.asInstanceOf[Succ]))
3838
case _ => None

tests/run/fully-abstract-nat-2.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object Test {
3434
}
3535

3636
def divOpt(a: Nat, b: Nat): Option[(Nat, Nat)] = b match {
37-
case s @ Succ(_) => Some(safeDiv(a, s))
37+
case s as Succ(_) => Some(safeDiv(a, s))
3838
case _ => None
3939
}
4040

0 commit comments

Comments
 (0)