Skip to content

Commit 8aa4103

Browse files
committed
Avoid printing root capture set
Use ^ and => shorthands instead.
1 parent d16c0f8 commit 8aa4103

24 files changed

+116
-102
lines changed

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,15 @@ class PlainPrinter(_ctx: Context) extends Printer {
155155
else if !cs.isConst && cs.elems.isEmpty then "?"
156156
else "{" ~ Text(cs.elems.toList.map(toTextCaptureRef), ", ") ~ "}"
157157

158+
/** Print capturing type, overridden in RefinedPrinter to account for
159+
* capturing function types.
160+
*/
158161
protected def toTextCapturing(parent: Type, refsText: Text, boxText: Text): Text =
159-
changePrec(InfixPrec)(boxText ~ toTextLocal(parent) ~ "^" ~ refsText)
162+
changePrec(InfixPrec):
163+
boxText ~ toTextLocal(parent) ~ "^"
164+
~ (refsText provided refsText != rootSetText)
165+
166+
final protected def rootSetText = Str("{*}")
160167

161168
def toText(tp: Type): Text = controlled {
162169
homogenize(tp) match {
@@ -214,7 +221,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
214221
}.close
215222
case tp @ EventuallyCapturingType(parent, refs) =>
216223
val boxText: Text = Str("box ") provided tp.isBoxed //&& ctx.settings.YccDebug.value
217-
toTextCapturing(parent, toTextCaptureSet(refs), boxText)
224+
val refsText = if refs.isUniversal then rootSetText else toTextCaptureSet(refs)
225+
toTextCapturing(parent, refsText, boxText)
218226
case tp: PreviousErrorType if ctx.settings.XprintTypes.value =>
219227
"<error>" // do not print previously reported error message because they may try to print this error type again recuresevely
220228
case tp: ErrorType =>

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
148148
val AppliedType(tycon, args) = (tp: @unchecked)
149149
val tsym = tycon.typeSymbol
150150
val isGiven = tsym.name.isContextFunction
151-
val isPure = Feature.pureFunsEnabled && !tsym.name.isImpureFunction
151+
val capturesRoot = refs == rootSetText
152+
val isPure =
153+
Feature.pureFunsEnabled && !tsym.name.isImpureFunction && !capturesRoot
152154
changePrec(GlobalPrec) {
153155
val argStr: Text =
154156
if args.length == 2
@@ -160,17 +162,21 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
160162
"("
161163
~ argsText(args.init)
162164
~ ")"
163-
argStr ~ " " ~ arrow(isGiven, isPure) ~ refs ~ " " ~ argText(args.last)
165+
argStr
166+
~ " " ~ arrow(isGiven, isPure)
167+
~ (refs provided !capturesRoot)
168+
~ " " ~ argText(args.last)
164169
}
165170

166171
private def toTextMethodAsFunction(info: Type, isPure: Boolean, refs: Text = Str("")): Text = info match
167172
case info: MethodType =>
173+
val capturesRoot = refs == rootSetText
168174
changePrec(GlobalPrec) {
169175
"("
170176
~ paramsText(info)
171177
~ ") "
172-
~ arrow(info.isImplicitMethod, isPure)
173-
~ refs
178+
~ arrow(info.isImplicitMethod, isPure && !capturesRoot)
179+
~ (refs provided !capturesRoot)
174180
~ " "
175181
~ toTextMethodAsFunction(info.resultType, isPure)
176182
}

tests/neg-custom-args/captures/capt1.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@
4141
32 | val z2 = h[() -> Cap](() => x) // error
4242
| ^^^^^^^
4343
| Found: () ->{x} Cap
44-
| Required: () -> box C^{*}
44+
| Required: () -> box C^
4545
|
4646
| longer explanation available when compiling with `-explain`
4747
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:33:5 -----------------------------------------
4848
33 | (() => C()) // error
4949
| ^^^^^^^^^
5050
| Found: () ->? Cap
51-
| Required: () -> box C^{*}
51+
| Required: () -> box C^
5252
|
5353
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/cc-this3.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this3.scala:8:6 ---------------------------------------
22
8 |class B extends A: // error
33
| ^
4-
| illegal inheritance: self type B^{*} of class B does not conform to self type A^{}
4+
| illegal inheritance: self type B^ of class B does not conform to self type A^{}
55
| of parent class A
66
|
77
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/cc-this3.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ class A:
66
val x: A = this
77

88
class B extends A: // error
9-
this: B^{*} =>
9+
this: B^ =>
1010

1111
class C(val f: () => Int) extends A // error
1212

1313
class A2
1414

1515
class B2 extends A2: // ok
16-
this: B2^{*} =>
16+
this: B2^ =>
1717

1818
class C2(val f: () => Int) extends A2 // ok

tests/neg-custom-args/captures/curried-simplified.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/curried-simplified.scala:9:28 ----------------------------
99
9 | def y2: () -> () => Int = x2 // error
1010
| ^^
11-
| Found: () ->{x} () ->{*} Int
11+
| Found: () ->{x} () => Int
1212
| Required: () -> () => Int
1313
|
1414
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/exception-definitions.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
2 |class Err extends Exception: // error
33
|^
44
|reference (scala.caps.* : Any) is not included in allowed capture set {} of pure base class class Throwable
5-
3 | self: Err^{*} =>
5+
3 | self: Err^ =>
66
-- Error: tests/neg-custom-args/captures/exception-definitions.scala:10:6 ----------------------------------------------
7-
10 |class Err4(c: Any^{*}) extends AnyVal // error
8-
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9-
|reference (Err4.this.c : Any^{*}) is not included in allowed capture set {} of pure base class class AnyVal
7+
10 |class Err4(c: Any^) extends AnyVal // error
8+
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9+
|reference (Err4.this.c : Any^) is not included in allowed capture set {} of pure base class class AnyVal
1010
-- Error: tests/neg-custom-args/captures/exception-definitions.scala:7:12 ----------------------------------------------
1111
7 | val x = c // error
1212
| ^
13-
|(c : Any^{*}) cannot be referenced here; it is not included in the allowed capture set {} of pure base class class Throwable
13+
|(c : Any^) cannot be referenced here; it is not included in the allowed capture set {} of pure base class class Throwable
1414
-- Error: tests/neg-custom-args/captures/exception-definitions.scala:8:8 -----------------------------------------------
15-
8 | class Err3(c: Any^{*}) extends Exception // error
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17-
| reference (Err3.this.c : Any^{*}) is not included in allowed capture set {} of pure base class class Throwable
15+
8 | class Err3(c: Any^) extends Exception // error
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
| reference (Err3.this.c : Any^) is not included in allowed capture set {} of pure base class class Throwable
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

22
class Err extends Exception: // error
3-
self: Err^{*} =>
3+
self: Err^ =>
44

5-
def test(c: Any^{*}) =
5+
def test(c: Any^) =
66
class Err2 extends Exception:
77
val x = c // error
8-
class Err3(c: Any^{*}) extends Exception // error
8+
class Err3(c: Any^) extends Exception // error
99

10-
class Err4(c: Any^{*}) extends AnyVal // error
10+
class Err4(c: Any^) extends AnyVal // error
1111

1212

tests/neg-custom-args/captures/i15116.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
5 | val x = Foo(m) // error
1010
| ^^^^^^^^^^^^^^
1111
| Non-local value x cannot have an inferred type
12-
| Foo{val m: String^{*}}^{Baz.this}
12+
| Foo{val m: String^}^{Baz.this}
1313
| with non-empty capture set {Baz.this}.
1414
| The type needs to be declared explicitly.
1515
-- Error: tests/neg-custom-args/captures/i15116.scala:7:6 --------------------------------------------------------------
@@ -23,6 +23,6 @@
2323
9 | val x = Foo(m) // error
2424
| ^^^^^^^^^^^^^^
2525
| Non-local value x cannot have an inferred type
26-
| Foo{val m: String^{*}}^{Baz2.this}
26+
| Foo{val m: String^}^{Baz2.this}
2727
| with non-empty capture set {Baz2.this}.
2828
| The type needs to be declared explicitly.
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
class Foo(m: String^{*})
2-
class Bar(val m: String^{*}):
1+
class Foo(m: String^)
2+
class Bar(val m: String^):
33
val x = Foo(m) // error
4-
trait Baz(val m: String^{*}):
4+
trait Baz(val m: String^):
55
val x = Foo(m) // error
6-
class Bar1(m: String^{*}):
6+
class Bar1(m: String^):
77
val x = Foo(m) // error
8-
trait Baz2(m: String^{*}):
8+
trait Baz2(m: String^):
99
val x = Foo(m) // error

tests/neg-custom-args/captures/i15772.check

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:20:49 ---------------------------------------
2-
20 | val boxed1 : ((C^{*}) => Unit) -> Unit = box1(c) // error
3-
| ^^^^^^^
4-
| Found: (C{val arg: C^{*}}^{c} ->{*} Unit) ->{c} Unit
5-
| Required: (C^{*} => Unit) -> Unit
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:20:46 ---------------------------------------
2+
20 | val boxed1 : ((C^) => Unit) -> Unit = box1(c) // error
3+
| ^^^^^^^
4+
| Found: (C{val arg: C^}^{c} => Unit) ->{c} Unit
5+
| Required: (C^ => Unit) -> Unit
66
|
77
| longer explanation available when compiling with `-explain`
8-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:27:38 ---------------------------------------
9-
27 | val boxed2 : Observe[C^{*}] = box2(c) // error
10-
| ^^^^^^^
11-
| Found: (C{val arg: C^{*}}^{c} ->{*} Unit) ->{c} Unit
12-
| Required: Observe[C^{*}]
8+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:27:35 ---------------------------------------
9+
27 | val boxed2 : Observe[C^] = box2(c) // error
10+
| ^^^^^^^
11+
| Found: (C{val arg: C^}^{c} => Unit) ->{c} Unit
12+
| Required: Observe[C^]
1313
|
1414
| longer explanation available when compiling with `-explain`
15-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:33:37 ---------------------------------------
16-
33 | val boxed2 : Observe[C]^{*} = box2(c) // error
17-
| ^
18-
| Found: C^{*}
19-
| Required: box C{val arg: C^?}^{*}
15+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:33:34 ---------------------------------------
16+
33 | val boxed2 : Observe[C]^ = box2(c) // error
17+
| ^
18+
| Found: C^
19+
| Required: box C{val arg: C^?}^
2020
|
2121
| longer explanation available when compiling with `-explain`
2222
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:44:2 ----------------------------------------

tests/neg-custom-args/captures/i15772.scala

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type Observe[T] = (T => Unit) -> Unit
22

3-
def unsafe(cap: C^{*}) = cap.bad()
3+
def unsafe(cap: C^) = cap.bad()
44

55
def box1[T](v: T) : (T => Unit) -> Unit = {
66
(fn: T => Unit) => fn(v)
@@ -10,34 +10,34 @@ def box2[T](v: T) : Observe[T] = {
1010
(fn: T => Unit) => fn(v)
1111
}
1212

13-
class C(val arg: C^{*}) {
13+
class C(val arg: C^) {
1414
def bad() = println("I've gone bad!")
1515
}
1616

17-
def main1(x: C^{*}) : () -> Int =
17+
def main1(x: C^) : () -> Int =
1818
() =>
1919
val c : C^{x} = new C(x)
20-
val boxed1 : ((C^{*}) => Unit) -> Unit = box1(c) // error
21-
boxed1((cap: C^{*}) => unsafe(c))
20+
val boxed1 : ((C^) => Unit) -> Unit = box1(c) // error
21+
boxed1((cap: C^) => unsafe(c))
2222
0
2323

24-
def main2(x: C^{*}) : () -> Int =
24+
def main2(x: C^) : () -> Int =
2525
() =>
2626
val c : C^{x} = new C(x)
27-
val boxed2 : Observe[C^{*}] = box2(c) // error
28-
boxed2((cap: C^{*}) => unsafe(c))
27+
val boxed2 : Observe[C^] = box2(c) // error
28+
boxed2((cap: C^) => unsafe(c))
2929
0
3030

31-
def main3(x: C^{*}) =
32-
def c : C^{*} = new C(x)
33-
val boxed2 : Observe[C]^{*} = box2(c) // error
34-
boxed2((cap: C^{*}) => unsafe(c))
31+
def main3(x: C^) =
32+
def c : C^ = new C(x)
33+
val boxed2 : Observe[C]^ = box2(c) // error
34+
boxed2((cap: C^) => unsafe(c))
3535
0
3636

3737
trait File:
3838
def write(s: String): Unit
3939

40-
def main(io: Any^{*}) =
40+
def main(io: Any^) =
4141
val sayHello: ((File^{io}) => Unit) = (file: File^{io}) => file.write("Hello World!\r\n")
4242
val filesList : List[File]^{io} = ???
4343
val x = () => filesList.foreach(sayHello)

tests/neg-custom-args/captures/lazylist.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:35:29 -------------------------------------
99
35 | val ref1c: LazyList[Int] = ref1 // error
1010
| ^^^^
11-
| Found: (ref1 : lazylists.LazyCons[Int]{val xs: () ->{cap1} lazylists.LazyList[Int]^{*}}^{cap1})
12-
| Required: lazylists.LazyList[Int]
11+
| Found: (ref1 : lazylists.LazyCons[Int]{val xs: () ->{cap1} lazylists.LazyList[Int]^}^{cap1})
12+
| Required: lazylists.LazyList[Int]
1313
|
1414
| longer explanation available when compiling with `-explain`
1515
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:37:36 -------------------------------------
@@ -34,9 +34,9 @@
3434
|
3535
| longer explanation available when compiling with `-explain`
3636
-- [E164] Declaration Error: tests/neg-custom-args/captures/lazylist.scala:22:6 ----------------------------------------
37-
22 | def tail: LazyList[Nothing]^{*} = ??? // error overriding
37+
22 | def tail: LazyList[Nothing]^ = ??? // error overriding
3838
| ^
3939
| error overriding method tail in class LazyList of type -> lazylists.LazyList[Nothing];
40-
| method tail of type -> lazylists.LazyList[Nothing]^{*} has incompatible type
40+
| method tail of type -> lazylists.LazyList[Nothing]^ has incompatible type
4141
|
4242
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/lazylist.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package lazylists
22

33
abstract class LazyList[+T]:
4-
this: LazyList[T]^{*} =>
4+
this: LazyList[T]^ =>
55

66
def isEmpty: Boolean
77
def head: T
@@ -11,21 +11,21 @@ abstract class LazyList[+T]:
1111
if isEmpty then LazyNil
1212
else LazyCons(f(head), () => tail.map(f))
1313

14-
class LazyCons[+T](val x: T, val xs: () => LazyList[T]^{*}) extends LazyList[T]:
14+
class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]:
1515
def isEmpty = false
1616
def head = x
1717
def tail = xs() // error
1818

1919
object LazyNil extends LazyList[Nothing]:
2020
def isEmpty = true
2121
def head = ???
22-
def tail: LazyList[Nothing]^{*} = ??? // error overriding
22+
def tail: LazyList[Nothing]^ = ??? // error overriding
2323

24-
def map[A, B](xs: LazyList[A]^{*}, f: A => B): LazyList[B]^{f, xs} =
24+
def map[A, B](xs: LazyList[A]^, f: A => B): LazyList[B]^{f, xs} =
2525
xs.map(f)
2626

2727
class CC
28-
type Cap = CC^{*}
28+
type Cap = CC^
2929

3030
def test(cap1: Cap, cap2: Cap, cap3: Cap) =
3131
def f[T](x: LazyList[T]): LazyList[T] = if cap1 == cap1 then x else LazyNil

tests/neg-custom-args/captures/lazylists-exceptions.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- Error: tests/neg-custom-args/captures/lazylists-exceptions.scala:36:2 -----------------------------------------------
22
36 | try // error
33
| ^
4-
| The expression's type LazyList[Int]^{*} is not allowed to capture the root capability `*`.
4+
| The expression's type LazyList[Int]^ is not allowed to capture the root capability `*`.
55
| This usually means that a capability persists longer than its allowed lifetime.
66
37 | tabulate(10) { i =>
77
38 | if i > 9 then throw Ex1()

tests/neg-custom-args/captures/lazylists-exceptions.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ object LazyNil extends LazyList[Nothing]:
1212
def head = ???
1313
def tail = ???
1414

15-
final class LazyCons[+T](val x: T, val xs: () => LazyList[T]^{*}) extends LazyList[T]:
16-
this: LazyList[T]^{*} =>
15+
final class LazyCons[+T](val x: T, val xs: () => LazyList[T]^) extends LazyList[T]:
16+
this: LazyList[T]^ =>
1717

1818
def isEmpty = false
1919
def head = x
2020
def tail: LazyList[T]^{this} = xs()
2121
end LazyCons
2222

2323
extension [A](x: A)
24-
def #:(xs1: => LazyList[A]^{*}): LazyList[A]^{xs1} =
24+
def #:(xs1: => LazyList[A]^): LazyList[A]^{xs1} =
2525
LazyCons(x, () => xs1)
2626

2727
def tabulate[A](n: Int)(gen: Int => A): LazyList[A]^{gen} =

tests/neg-custom-args/captures/lazyref.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:21:35 --------------------------------------
99
21 | val ref2c: LazyRef[Int]^{cap2} = ref2 // error
1010
| ^^^^
11-
| Found: (ref2 : LazyRef[Int]{val elem: () ->{*} Int}^{cap2, ref1})
11+
| Found: (ref2 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1})
1212
| Required: LazyRef[Int]^{cap2}
1313
|
1414
| longer explanation available when compiling with `-explain`
1515
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:23:35 --------------------------------------
1616
23 | val ref3c: LazyRef[Int]^{ref1} = ref3 // error
1717
| ^^^^
18-
| Found: (ref3 : LazyRef[Int]{val elem: () ->{*} Int}^{cap2, ref1})
18+
| Found: (ref3 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1})
1919
| Required: LazyRef[Int]^{ref1}
2020
|
2121
| longer explanation available when compiling with `-explain`
2222
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:25:35 --------------------------------------
2323
25 | val ref4c: LazyRef[Int]^{cap1} = ref4 // error
2424
| ^^^^
25-
| Found: (ref4 : LazyRef[Int]{val elem: () ->{*} Int}^{cap2, cap1})
25+
| Found: (ref4 : LazyRef[Int]{val elem: () => Int}^{cap2, cap1})
2626
| Required: LazyRef[Int]^{cap1}
2727
|
2828
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)