diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 63639dcb3c15..4198c78e3288 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -206,7 +206,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { case class Var()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Mutable) - case class Mut()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Mutable) + case class Update()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Mutable) case class Implicit()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Implicit) diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index d6afd8d4b872..a927416c4282 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -553,7 +553,6 @@ object StdNames { val maybeCapability: N = "maybeCapability" val mirror : N = "mirror" val moduleClass : N = "moduleClass" - val mut: N = "mut" val name: N = "name" val nameDollar: N = "$name" val ne: N = "ne" diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index c607d0377d83..bf3fb65900ff 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3291,7 +3291,7 @@ object Parsers { case nme.infix => Mod.Infix() case nme.tracked => Mod.Tracked() case nme.erased if in.erasedEnabled => Mod.Erased() - case nme.mut if Feature.ccEnabled => Mod.Mut() + case nme.update if Feature.ccEnabled => Mod.Update() } } @@ -4708,7 +4708,7 @@ object Parsers { Nil tree match case tree: MemberDef - if !(tree.mods.flags & ModifierFlags).isEmpty && !tree.mods.isMutableVar => // vars are OK, mut defs are not + if !(tree.mods.flags & ModifierFlags).isEmpty && !tree.mods.isMutableVar => // vars are OK, update defs are not fail(em"refinement cannot be ${(tree.mods.flags & ModifierFlags).flagStrings().mkString("`", "`, `", "`")}") case tree: DefDef if tree.termParamss.nestedExists(!_.rhs.isEmpty) => fail(em"refinement cannot have default arguments") diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 2764715a3209..9987eaaa81b9 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -1228,7 +1228,7 @@ object Scanners { && (softModifierNames.contains(name) || name == nme.erased && erasedEnabled || name == nme.tracked && trackedEnabled - || name == nme.mut && Feature.ccEnabled) + || name == nme.update && Feature.ccEnabled) def isSoftModifierInModifierPosition: Boolean = isSoftModifier && inModifierPosition() diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala index 5b9a62fcb7da..d47e6dab005f 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala @@ -299,7 +299,7 @@ object Tokens extends TokensCommon { final val closingParens = BitSet(RPAREN, RBRACKET, RBRACE) - final val softModifierNames = Set(nme.inline, nme.into, nme.opaque, nme.open, nme.transparent, nme.infix) + final val softModifierNames = Set(nme.inline, nme.into, nme.opaque, nme.open, nme.transparent, nme.infix, nme.update) def showTokenDetailed(token: Int): String = debugString(token) diff --git a/docs/_docs/internals/exclusive-capabilities.md b/docs/_docs/internals/exclusive-capabilities.md index 97c6592ac693..938eb5ccdd55 100644 --- a/docs/_docs/internals/exclusive-capabilities.md +++ b/docs/_docs/internals/exclusive-capabilities.md @@ -18,27 +18,27 @@ We introduce a new trait trait Mutable ``` It is used as a base trait for types that define _update methods_ using -a new modifier `mut`. +a new soft modifier `update`. -`mut` can only be used in classes or objects extending `Mutable`. An update method is allowed to access exclusive capabilities in the method's environment. By contrast, a normal method in a type extending `Mutable` may access exclusive capabilities only if they are defined locally or passed to it in parameters. +`update` can only be used in classes or objects extending `Mutable`. An update method is allowed to access exclusive capabilities in the method's environment. By contrast, a normal method in a type extending `Mutable` may access exclusive capabilities only if they are defined locally or passed to it in parameters. **Example:** ```scala class Ref(init: Int) extends Mutable: private var current = init def get: Int = current - mut def put(x: Int): Unit = current = x + update def put(x: Int): Unit = current = x ``` Here, `put` needs to be declared as an update method since it accesses the exclusive write capability of the variable `current` in its environment. -`mut` can also be used on an inner class of a class or object extending `Mutable`. It gives all code in the class the right +`update` can also be used on an inner class of a class or object extending `Mutable`. It gives all code in the class the right to access exclusive capabilities in the class environment. Normal classes can only access exclusive capabilities defined in the class or passed to it in parameters. ```scala object Registry extends Mutable: var count = 0 - mut class Counter: - mut def next: Int = + update class Counter: + update def next: Int = count += 1 count ``` @@ -79,22 +79,22 @@ Consider trait `IterableOnce` from the standard library. ```scala trait IterableOnce[+T] extends Mutable: def iterator: Iterator[T]^{this} - mut def foreach(op: T => Unit): Unit - mut def exists(op: T => Boolean): Boolean + update def foreach(op: T => Unit): Unit + update def exists(op: T => Boolean): Boolean ... ``` -The trait is a mutable type with many update methods, among them `foreach` and `exists`. These need to be classified as `mut` because their implementation in the subtrait `Iterator` uses the update method `next`. +The trait is a mutable type with many update methods, among them `foreach` and `exists`. These need to be classified as `update` because their implementation in the subtrait `Iterator` uses the update method `next`. ```scala trait Iterator[T] extends IterableOnce[T]: def iterator = this def hasNext: Boolean - mut def next(): T - mut def foreach(op: T => Unit): Unit = ... - mut def exists(op; T => Boolean): Boolean = ... + update def next(): T + update def foreach(op: T => Unit): Unit = ... + update def exists(op; T => Boolean): Boolean = ... ... ``` But there are other implementations of `IterableOnce` that are not mutable types (even though they do indirectly extend the `Mutable` trait). Notably, collection classes implement `IterableOnce` by creating a fresh -`iterator` each time one is required. The mutation via `next()` is then restricted to the state of that iterator, whereas the underlying collection is unaffected. These implementations would implement each `mut` method in `IterableOnce` by a normal method without the `mut` modifier. +`iterator` each time one is required. The mutation via `next()` is then restricted to the state of that iterator, whereas the underlying collection is unaffected. These implementations would implement each `update` method in `IterableOnce` by a normal method without the `update` modifier. ```scala trait Iterable[T] extends IterableOnce[T]: @@ -140,7 +140,7 @@ For instance, a matrix multiplication method can be expressed as follows: ```scala class Matrix(nrows: Int, ncols: Int) extends Mutable: - mut def update(i: Int, j: Int, x: Double): Unit = ... + update def update(i: Int, j: Int, x: Double): Unit = ... def apply(i: Int, j: Int): Double = ... def mul(a: Matrix, b: Matrix, c: Matrix^): Unit = @@ -435,7 +435,7 @@ we'd deal with ```scala val x$ = Ref[T](init) def x = x$.get -mut def x_=(y: T) = x$.put(y) +update def x_=(y: T) = x$.put(y) ``` There should be a way to exclude a mutable variable or field from tracking. Maybe an annotation or modifier such as `transparent` or `untracked`? diff --git a/tests/neg-custom-args/captures/contracap.scala b/tests/neg-custom-args/captures/contracap.scala index 0ba1507eb11f..085fff6f4903 100644 --- a/tests/neg-custom-args/captures/contracap.scala +++ b/tests/neg-custom-args/captures/contracap.scala @@ -4,7 +4,7 @@ import caps.* class Ref[T](init: T) extends Mutable: private var value: T = init def get: T = value - mut def set(newValue: T): Unit = value = newValue + update def set(newValue: T): Unit = value = newValue // a library function that assumes that a and b MUST BE separate def swap[T](a: Ref[Int]^, b: Ref[Int]^): Unit = ??? diff --git a/tests/neg-custom-args/captures/linear-buffer-2.scala b/tests/neg-custom-args/captures/linear-buffer-2.scala index 428171c3fab8..78561351838b 100644 --- a/tests/neg-custom-args/captures/linear-buffer-2.scala +++ b/tests/neg-custom-args/captures/linear-buffer-2.scala @@ -2,7 +2,7 @@ import caps.{cap, consume, Mutable} import language.experimental.captureChecking class Buffer[T] extends Mutable: - @consume mut def append(x: T): Buffer[T]^ = this // ok + @consume update def append(x: T): Buffer[T]^ = this // ok def app[T](@consume buf: Buffer[T]^, elem: T): Buffer[T]^ = buf.append(elem) diff --git a/tests/neg-custom-args/captures/linear-buffer.check b/tests/neg-custom-args/captures/linear-buffer.check index 86e6aaaa81a3..0fd18869eb9c 100644 --- a/tests/neg-custom-args/captures/linear-buffer.check +++ b/tests/neg-custom-args/captures/linear-buffer.check @@ -1,6 +1,6 @@ --- Error: tests/neg-custom-args/captures/linear-buffer.scala:5:24 ------------------------------------------------------ -5 | mut def append(x: T): BadBuffer[T]^ = this // error - | ^^^^^^^^^^^^^ +-- Error: tests/neg-custom-args/captures/linear-buffer.scala:5:27 ------------------------------------------------------ +5 | update def append(x: T): BadBuffer[T]^ = this // error + | ^^^^^^^^^^^^^ | Separation failure: method append's result type BadBuffer[T]^ hides non-local this of class class BadBuffer. | The access must be in a @consume method to allow this. -- Error: tests/neg-custom-args/captures/linear-buffer.scala:7:13 ------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/linear-buffer.scala b/tests/neg-custom-args/captures/linear-buffer.scala index a72f69a22dbd..5c6d991579aa 100644 --- a/tests/neg-custom-args/captures/linear-buffer.scala +++ b/tests/neg-custom-args/captures/linear-buffer.scala @@ -2,13 +2,13 @@ import caps.{cap, consume, Mutable} import language.experimental.captureChecking class BadBuffer[T] extends Mutable: - mut def append(x: T): BadBuffer[T]^ = this // error + update def append(x: T): BadBuffer[T]^ = this // error def foo = def bar: BadBuffer[T]^ = this // error bar class Buffer[T] extends Mutable: - @consume mut def append(x: T): Buffer[T]^ = this // ok + @consume update def append(x: T): Buffer[T]^ = this // ok def app[T](@consume buf: Buffer[T]^, elem: T): Buffer[T]^ = buf.append(elem) diff --git a/tests/neg-custom-args/captures/mut-outside-mutable.check b/tests/neg-custom-args/captures/mut-outside-mutable.check index bfc1b5161f0a..d0f61f150565 100644 --- a/tests/neg-custom-args/captures/mut-outside-mutable.check +++ b/tests/neg-custom-args/captures/mut-outside-mutable.check @@ -1,8 +1,8 @@ --- Error: tests/neg-custom-args/captures/mut-outside-mutable.scala:5:10 ------------------------------------------------ -5 | mut def foreach(op: T => Unit): Unit // error - | ^ - | Update methods can only be used as members of classes extending the `Mutable` trait --- Error: tests/neg-custom-args/captures/mut-outside-mutable.scala:9:12 ------------------------------------------------ -9 | mut def baz() = 1 // error - | ^ - | Update methods can only be used as members of classes extending the `Mutable` trait +-- Error: tests/neg-custom-args/captures/mut-outside-mutable.scala:5:13 ------------------------------------------------ +5 | update def foreach(op: T => Unit): Unit // error + | ^ + | Update methods can only be used as members of classes extending the `Mutable` trait +-- Error: tests/neg-custom-args/captures/mut-outside-mutable.scala:9:15 ------------------------------------------------ +9 | update def baz() = 1 // error + | ^ + | Update methods can only be used as members of classes extending the `Mutable` trait diff --git a/tests/neg-custom-args/captures/mut-outside-mutable.scala b/tests/neg-custom-args/captures/mut-outside-mutable.scala index 18c0e59c5bd8..12c47334a422 100644 --- a/tests/neg-custom-args/captures/mut-outside-mutable.scala +++ b/tests/neg-custom-args/captures/mut-outside-mutable.scala @@ -2,9 +2,9 @@ import caps.Mutable trait IterableOnce[T]: def iterator: Iterator[T]^{this} - mut def foreach(op: T => Unit): Unit // error + update def foreach(op: T => Unit): Unit // error trait Foo extends Mutable: def bar = - mut def baz() = 1 // error + update def baz() = 1 // error baz() diff --git a/tests/neg-custom-args/captures/mut-override.scala b/tests/neg-custom-args/captures/mut-override.scala index 848e4d880223..aa2913645e43 100644 --- a/tests/neg-custom-args/captures/mut-override.scala +++ b/tests/neg-custom-args/captures/mut-override.scala @@ -2,18 +2,18 @@ import caps.Mutable trait IterableOnce[T] extends Mutable: def iterator: Iterator[T]^{this} - mut def foreach(op: T => Unit): Unit + update def foreach(op: T => Unit): Unit trait Iterator[T] extends IterableOnce[T]: def iterator = this def hasNext: Boolean - mut def next(): T - mut def foreach(op: T => Unit): Unit = ??? - override mut def toString = ??? // error + update def next(): T + update def foreach(op: T => Unit): Unit = ??? + override update def toString = ??? // error trait Iterable[T] extends IterableOnce[T]: def iterator: Iterator[T] = ??? def foreach(op: T => Unit) = iterator.foreach(op) trait BadIterator[T] extends Iterator[T]: - override mut def hasNext: Boolean // error + override update def hasNext: Boolean // error diff --git a/tests/neg-custom-args/captures/readOnly.scala b/tests/neg-custom-args/captures/readOnly.scala index 4edea6638980..1c8a2bbc351e 100644 --- a/tests/neg-custom-args/captures/readOnly.scala +++ b/tests/neg-custom-args/captures/readOnly.scala @@ -4,7 +4,7 @@ import caps.cap class Ref(init: Int) extends Mutable: private var current = init def get: Int = current - mut def put(x: Int): Unit = current = x + update def put(x: Int): Unit = current = x def Test(c: Object^) = val a: Ref^ = Ref(1) diff --git a/tests/neg-custom-args/captures/sep-box.scala b/tests/neg-custom-args/captures/sep-box.scala index fd9348acc893..218505b8c2ca 100644 --- a/tests/neg-custom-args/captures/sep-box.scala +++ b/tests/neg-custom-args/captures/sep-box.scala @@ -21,7 +21,7 @@ object NIL extends LIST[Nothing]: class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y class Box[+X](val value: X) diff --git a/tests/neg-custom-args/captures/sep-consume.scala b/tests/neg-custom-args/captures/sep-consume.scala index 46c45e8cc6f5..3d167e0674d9 100644 --- a/tests/neg-custom-args/captures/sep-consume.scala +++ b/tests/neg-custom-args/captures/sep-consume.scala @@ -4,7 +4,7 @@ import caps.* class Ref extends Mutable: private var _data = 0 def get: Int = _data - mut def put(x: Int): Unit = _data = x + update def put(x: Int): Unit = _data = x case class Pair[+A, +B](fst: A, snd: B) diff --git a/tests/neg-custom-args/captures/sep-counter.scala b/tests/neg-custom-args/captures/sep-counter.scala index 42bf5afc172a..a2df6cd0e62d 100644 --- a/tests/neg-custom-args/captures/sep-counter.scala +++ b/tests/neg-custom-args/captures/sep-counter.scala @@ -4,7 +4,7 @@ import caps.cap class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y class Pair[+X, +Y](val fst: X, val snd: Y) diff --git a/tests/neg-custom-args/captures/sep-curried.scala b/tests/neg-custom-args/captures/sep-curried.scala index 13a07ad6cca7..2ae424aed9e3 100644 --- a/tests/neg-custom-args/captures/sep-curried.scala +++ b/tests/neg-custom-args/captures/sep-curried.scala @@ -4,7 +4,7 @@ import caps.* class Ref[T](init: T) extends Mutable: private var value: T = init def get: T = value - mut def set(newValue: T): Unit = value = newValue + update def set(newValue: T): Unit = value = newValue // a library function that assumes that a and b MUST BE separate def swap[T](a: Ref[Int]^, b: Ref[Int]^): Unit = ??? diff --git a/tests/neg-custom-args/captures/sep-list.scala b/tests/neg-custom-args/captures/sep-list.scala index 46e9b6988318..b5c379a1e3c7 100644 --- a/tests/neg-custom-args/captures/sep-list.scala +++ b/tests/neg-custom-args/captures/sep-list.scala @@ -21,7 +21,7 @@ object NIL extends LIST[Nothing]: class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y def listFresh(n: Int): LIST[Ref^] = if n == 0 then NIL diff --git a/tests/neg-custom-args/captures/sep-pairs-2.scala b/tests/neg-custom-args/captures/sep-pairs-2.scala index cfe6bfbf8014..ca166c95bb76 100644 --- a/tests/neg-custom-args/captures/sep-pairs-2.scala +++ b/tests/neg-custom-args/captures/sep-pairs-2.scala @@ -4,7 +4,7 @@ import caps.cap class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y class Pair[+X, +Y](val fst: X, val snd: Y) diff --git a/tests/neg-custom-args/captures/sep-pairs.scala b/tests/neg-custom-args/captures/sep-pairs.scala index 298dc2e563c1..0a8635f3ea63 100644 --- a/tests/neg-custom-args/captures/sep-pairs.scala +++ b/tests/neg-custom-args/captures/sep-pairs.scala @@ -4,7 +4,7 @@ import caps.cap class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y class Pair[+X, +Y](val fst: X, val snd: Y) diff --git a/tests/neg-custom-args/captures/sepchecks.scala b/tests/neg-custom-args/captures/sepchecks.scala index 4508b6839781..f84c80da9c54 100644 --- a/tests/neg-custom-args/captures/sepchecks.scala +++ b/tests/neg-custom-args/captures/sepchecks.scala @@ -8,7 +8,7 @@ trait Rdr[T]: class Ref[T](init: T) extends Rdr[T], Mutable: private var current = init def get: T = current - mut def put(x: T): Unit = current = x + update def put(x: T): Unit = current = x def Test(c: Object^): Unit = val a: Ref[Int]^ = Ref(1) @@ -39,7 +39,7 @@ def Test(c: Object^): Unit = class Matrix(nrows: Int, ncols: Int) extends IMatrix, Mutable: val arr = Array.fill(nrows, ncols)(0.0) def apply(i: Int, j: Int): Double = arr(i)(j) - mut def update(i: Int, j: Int, x: Double): Unit = arr(i)(j) = x + update def update(i: Int, j: Int, x: Double): Unit = arr(i)(j) = x def mul(x: IMatrix^{cap.rd}, y: IMatrix^{cap.rd}, z: Matrix^): Matrix^ = ??? diff --git a/tests/neg-custom-args/captures/update-call.scala b/tests/neg-custom-args/captures/update-call.scala index 848e4d880223..aa2913645e43 100644 --- a/tests/neg-custom-args/captures/update-call.scala +++ b/tests/neg-custom-args/captures/update-call.scala @@ -2,18 +2,18 @@ import caps.Mutable trait IterableOnce[T] extends Mutable: def iterator: Iterator[T]^{this} - mut def foreach(op: T => Unit): Unit + update def foreach(op: T => Unit): Unit trait Iterator[T] extends IterableOnce[T]: def iterator = this def hasNext: Boolean - mut def next(): T - mut def foreach(op: T => Unit): Unit = ??? - override mut def toString = ??? // error + update def next(): T + update def foreach(op: T => Unit): Unit = ??? + override update def toString = ??? // error trait Iterable[T] extends IterableOnce[T]: def iterator: Iterator[T] = ??? def foreach(op: T => Unit) = iterator.foreach(op) trait BadIterator[T] extends Iterator[T]: - override mut def hasNext: Boolean // error + override update def hasNext: Boolean // error diff --git a/tests/pos-custom-args/captures/mutRef.scala b/tests/pos-custom-args/captures/mutRef.scala index 5fe82c9b987a..303188678df8 100644 --- a/tests/pos-custom-args/captures/mutRef.scala +++ b/tests/pos-custom-args/captures/mutRef.scala @@ -2,4 +2,4 @@ import caps.Mutable class Ref(init: Int) extends Mutable: private var current = init def get: Int = current - mut def put(x: Int): Unit = current = x + update def put(x: Int): Unit = current = x diff --git a/tests/pos-custom-args/captures/sep-pairs.scala b/tests/pos-custom-args/captures/sep-pairs.scala index df1a3098d22d..494996c12161 100644 --- a/tests/pos-custom-args/captures/sep-pairs.scala +++ b/tests/pos-custom-args/captures/sep-pairs.scala @@ -4,7 +4,7 @@ import caps.{cap, consume, use} class Ref extends Mutable: var x = 0 def get: Int = x - mut def put(y: Int): Unit = x = y + update def put(y: Int): Unit = x = y case class Pair[+A, +B](fst: A, snd: B)