Skip to content

Commit b8a3608

Browse files
committed
Do expected type widening only in final classes
Alex found a counter-example why this is required. See map5 in neg-customargs/captures/lazylists2.scala
1 parent facd751 commit b8a3608

File tree

5 files changed

+29
-9
lines changed

5 files changed

+29
-9
lines changed

compiler/src/dotty/tools/dotc/typer/CheckCaptures.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ class CheckCaptures extends Recheck:
325325
override def recheckRHS(tree: Tree, pt: Type, sym: Symbol)(using Context): Type =
326326
val pt1 = pt match
327327
case CapturingType(core, refs, _)
328-
if sym.owner.isClass && refs.elems.contains(sym.owner.thisType) =>
328+
if sym.owner.isClass && !sym.owner.isExtensibleClass
329+
&& refs.elems.contains(sym.owner.thisType) =>
329330
val paramCaptures =
330331
sym.paramSymss.flatten.foldLeft(CaptureSet.empty) { (cs, p) =>
331332
val pcs = p.info.captureSet

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
longer explanation available when compiling with `-explain`
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:18:4 ------------------------------------
9-
18 | class Mapped extends LazyList[B]: // error
9+
18 | final class Mapped extends LazyList[B]: // error
1010
| ^
1111
| Found: {f, xs} LazyList[B]
1212
| Required: {f} LazyList[B]
@@ -18,7 +18,7 @@ longer explanation available when compiling with `-explain`
1818

1919
longer explanation available when compiling with `-explain`
2020
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:27:4 ------------------------------------
21-
27 | class Mapped extends LazyList[B]: // error
21+
27 | final class Mapped extends LazyList[B]: // error
2222
| ^
2323
| Found: {f, xs} LazyList[B]
2424
| Required: {xs} LazyList[B]
@@ -36,3 +36,10 @@ longer explanation available when compiling with `-explain`
3636
| Required: {xs} LazyList[B]
3737

3838
longer explanation available when compiling with `-explain`
39+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:59:48 -----------------------------------
40+
59 | def tail: {this} LazyList[B] = xs.tail.map(f) // error
41+
| ^^^^^^^^^^^^^^
42+
| Found: {f} LazyList[B]
43+
| Required: {Mapped.this} LazyList[B]
44+
45+
longer explanation available when compiling with `-explain`

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

+16-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object LazyNil extends LazyList[Nothing]:
1515

1616
extension [A](xs: {*} LazyList[A])
1717
def map[B](f: {*} A => B): {f} LazyList[B] =
18-
class Mapped extends LazyList[B]: // error
18+
final class Mapped extends LazyList[B]: // error
1919
this: ({xs, f} Mapped) =>
2020

2121
def isEmpty = false
@@ -24,7 +24,7 @@ extension [A](xs: {*} LazyList[A])
2424
new Mapped
2525

2626
def map2[B](f: {*} A => B): {xs} LazyList[B] =
27-
class Mapped extends LazyList[B]: // error
27+
final class Mapped extends LazyList[B]: // error
2828
this: ({xs, f} Mapped) =>
2929

3030
def isEmpty = false
@@ -33,7 +33,7 @@ extension [A](xs: {*} LazyList[A])
3333
new Mapped
3434

3535
def map3[B](f: {*} A => B): {xs} LazyList[B] =
36-
class Mapped extends LazyList[B]:
36+
final class Mapped extends LazyList[B]:
3737
this: ({xs} Mapped) =>
3838

3939
def isEmpty = false
@@ -42,11 +42,23 @@ extension [A](xs: {*} LazyList[A])
4242
new Mapped
4343

4444
def map4[B](f: {*} A => B): {xs} LazyList[B] =
45-
class Mapped extends LazyList[B]:
45+
final class Mapped extends LazyList[B]:
4646
this: ({xs, f} Mapped) =>
4747

4848
def isEmpty = false
4949
def head: B = f(xs.head)
5050
def tail: {xs, f} LazyList[B] = xs.tail.map(f) // error
5151
new Mapped
5252

53+
def map5[B](f: {*} A => B): LazyList[B] =
54+
class Mapped extends LazyList[B]:
55+
this: ({xs, f} Mapped) =>
56+
57+
def isEmpty = false
58+
def head: B = f(xs.head)
59+
def tail: {this} LazyList[B] = xs.tail.map(f) // error
60+
class Mapped2 extends Mapped:
61+
this: Mapped =>
62+
new Mapped2
63+
64+

tests/pos-custom-args/captures/lazylists.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object LazyNil extends LazyList[Nothing]:
1515

1616
extension [A](xs: {*} LazyList[A])
1717
def map[B](f: {*} A => B): {xs, f} LazyList[B] =
18-
class Mapped extends LazyList[B]:
18+
final class Mapped extends LazyList[B]:
1919
this: ({xs, f} Mapped) =>
2020

2121
def isEmpty = false

tests/pos-custom-args/captures/lazylists1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ object LazyNil extends LazyList[Nothing]:
1313
def head = ???
1414
def tail = ???
1515

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

1919
def isEmpty = false

0 commit comments

Comments
 (0)