Skip to content

Commit 6648126

Browse files
KacperFKorbantgodzik
authored andcommitted
fix: allow postfix setters under language.postfixOps (scala#23775)
Allow for postfix operators to be followed by assigns. This enables the definition and use of the following syntax (more precisely the parsing of the `>_=` method as a `postfix operator + assign`): ```scala val v = new Vector(1, 2, 3) println(v) // prints <1, 2, 3> v<1> = 10 // assign 10 to element at index 1 println(v) // prints <1, 10, 3> println(v<1>) // prints: value at 1 is 10 // Definition of Vector: class Vector(values: Int*) { val data = values.toArray class Getter(i: Int) { def `>_=`(x: Int) = data(i) = x def > : Int = data(i) } def < (i:Int) = new Getter(i) override def toString = data.mkString("<", ", ", ">") } ``` [Cherry-picked de18af4]
1 parent 3a156a7 commit 6648126

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2179,6 +2179,7 @@ object Parsers {
21792179
* | ForExpr
21802180
* | [SimpleExpr `.'] id `=' Expr
21812181
* | PrefixOperator SimpleExpr `=' Expr
2182+
* | InfixExpr id [nl] `=' Expr -- only if language.postfixOps is enabled
21822183
* | SimpleExpr1 ArgumentExprs `=' Expr
21832184
* | PostfixExpr [Ascription]
21842185
* | ‘inline’ InfixExpr MatchClause
@@ -2339,7 +2340,7 @@ object Parsers {
23392340
def expr1Rest(t: Tree, location: Location): Tree =
23402341
if in.token == EQUALS then
23412342
t match
2342-
case Ident(_) | Select(_, _) | Apply(_, _) | PrefixOp(_, _) =>
2343+
case Ident(_) | Select(_, _) | Apply(_, _) | PrefixOp(_, _) | PostfixOp(_, _) =>
23432344
atSpan(startOffset(t), in.skipToken()) {
23442345
val loc = if location.inArgs then location else Location.ElseWhere
23452346
Assign(t, subPart(() => expr(loc)))

docs/_docs/internals/syntax.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ Expr1 ::= [‘inline’] ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[
240240
| ForExpr
241241
| [SimpleExpr ‘.’] id ‘=’ Expr Assign(expr, expr)
242242
| PrefixOperator SimpleExpr ‘=’ Expr Assign(expr, expr)
243+
| InfixExpr id [nl] `=' Expr Assign(expr, expr) -- only if language.postfixOps is enabled
243244
| SimpleExpr ArgumentExprs ‘=’ Expr Assign(expr, expr)
244245
| PostfixExpr [Ascription]
245246
| ‘inline’ InfixExpr MatchClause

docs/_docs/reference/syntax.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ Expr1 ::= [‘inline’] ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[
240240
| ForExpr
241241
| [SimpleExpr ‘.’] id ‘=’ Expr
242242
| PrefixOperator SimpleExpr ‘=’ Expr
243+
| InfixExpr id [nl] `=' Expr -- only if language.postfixOps is enabled
243244
| SimpleExpr ArgumentExprs ‘=’ Expr
244245
| PostfixExpr [Ascription]
245246
| ‘inline’ InfixExpr MatchClause

tests/pos/vec-access-syntax.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import scala.language.postfixOps
2+
3+
class Vector(values: Int*) {
4+
val data = values.toArray
5+
class Getter(i: Int) {
6+
def `>_=`(x: Int) =
7+
data(i) = x
8+
def > : Int =
9+
data(i)
10+
}
11+
def < (i:Int) = new Getter(i)
12+
override def toString = data.mkString("<", ", ", ">")
13+
}
14+
15+
object Test {
16+
def main(args: Array[String]): Unit = {
17+
val v = new Vector(1, 2, 3)
18+
println(v) // prints <1, 2, 3>
19+
v<1> = 10 // assign 10 to element at index 1
20+
println(v) // prints <1, 10, 3>
21+
println(v<1>) // prints: value at 1 is 10
22+
}
23+
}

0 commit comments

Comments
 (0)