Skip to content

Commit 9253f3b

Browse files
committed
Add missing substitution when typing closure blocks
Fix typing closure blocks where the expected result type refers to a closure parameter. A substitution was missing in this case. Fixes scala#23727
1 parent 4689288 commit 9253f3b

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ class CheckCaptures extends Recheck, SymTransformer:
10441044
val localResType = pt match
10451045
case RefinedType(_, _, mt: MethodType) =>
10461046
inContext(ctx.withOwner(anonfun)):
1047-
Internalize(mt)(resType)
1047+
Internalize(mt)(resType.substParams(mt, params.tpes))
10481048
case _ => resType
10491049
mdef.tpt.updNuType(localResType)
10501050
// Make sure we affect the info of the anonfun by the previous updNuType

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
|Found: (f: File^'s1) ->'s2 Unit
55
|Required: (f: File^{l}) => Unit
66
|
7-
|Note that capability l cannot be included in outer capture set 's1 of parameter f.
7+
|Note that capability l is not included in capture set {cap}.
88
|
9-
|where: => refers to a fresh root capability created in anonymous function of type (using l: scala.caps.Capability): File^{l} -> Unit when instantiating expected result type (f: File^{l}) ->{cap} Unit of function literal
9+
|where: => refers to a fresh root capability created in anonymous function of type (using l²: scala.caps.Capability): File^{l²} -> Unit when instantiating expected result type (f: File^{l²}) ->{cap²} Unit of function literal
10+
| cap is a fresh root capability in the type of variable file
1011
16 | val o = Service()
1112
17 | o.file = f
1213
18 | o.log
Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:27:23 ---------------------------------------
22
27 | val leak = withCap(cap => mkId(cap)) // error (was: no error here since type aliases don't box)
33
| ^^^^^^^^^^^^^^^^
4-
|Found: (cap: test2.Cap^'s1) ->'s2 [T] => (op: test2.Cap^'s3 ->'s4 T) ->'s5 T
5-
|Required: test2.Cap^{lcap} => [T] => (op: test2.Cap^'s6 ->'s7 T) ->'s8 T
4+
|Found: (lcap: scala.caps.Capability^) ?->'s1 test2.Cap^{lcap} => [T] => (op: test2.Cap^{lcap} ->'s2 T) ->'s3 T
5+
|Required: (lcap: scala.caps.Capability^) ?-> test2.Cap^{lcap} =>² [T] => (op: test2.Cap^{lcap²} ->'s2 T) ->'s3 T
66
|
7-
|Note that capability lcap cannot be included in outer capture set 's1 of parameter cap.
7+
|Note that capability lcap cannot be included in outer capture set {lcap²}.
88
|
9-
|where: => refers to a fresh root capability created in anonymous function of type (using lcap: scala.caps.Capability): test2.Cap^{lcap} -> [T] => (op: test2.Cap^{lcap} => T) -> T when instantiating expected result type test2.Cap^{lcap} ->{cap²} [T] => (op: test2.Cap^'s6 ->'s7 T) ->'s8 T of function literal
9+
|where: => refers to a root capability associated with the result type of (using lcap: scala.caps.Capability^): test2.Cap^{lcap} => [T] => (op: test2.Cap^{lcap} ->'s2 T) ->'s3 T
10+
| =>² refers to a root capability associated with the result type of (using lcap: scala.caps.Capability^): test2.Cap^{lcap} =>² [T] => (op: test2.Cap^{lcap²} ->'s2 T) ->'s3 T
11+
| ^ refers to the universal root capability
12+
| lcap is a reference to a value parameter
13+
| lcap² is a parameter in an anonymous function in method bar
1014
|
1115
| longer explanation available when compiling with `-explain`
1216
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:12:21 ---------------------------------------
1317
12 | val leak = withCap(cap => mkId(cap)) // error
1418
| ^^^^^^^^^^^^^^^^
15-
|Found: (cap: Cap^'s9) ->'s10 Id[Cap^'s11]^'s12
16-
|Required: Cap^{lcap} => Id[Cap^'s13]^'s14
19+
|Found: (lcap: scala.caps.Capability^) ?->'s4 Cap^{lcap} => Id[Cap^{lcap}]^'s5
20+
|Required: (lcap: scala.caps.Capability^) ?-> Cap^{lcap} =>² Id[Cap^{lcap²}]^'s5
1721
|
18-
|Note that capability lcap cannot be included in outer capture set 's9 of parameter cap.
22+
|Note that capability lcap² is not included in capture set {lcap}.
1923
|
20-
|where: => refers to a fresh root capability created in anonymous function of type (using lcap: scala.caps.Capability): Cap^{lcap} -> Id[Cap] when instantiating expected result type Cap^{lcap} ->{cap²} Id[Cap^'s13]^'s14 of function literal
24+
|where: => refers to a root capability associated with the result type of (using lcap: scala.caps.Capability^): Cap^{lcap} => Id[Cap^{lcap}]^'s5
25+
| =>² refers to a root capability associated with the result type of (using lcap: scala.caps.Capability^): Cap^{lcap} =>² Id[Cap^{lcap²}]^'s5
26+
| ^ refers to the universal root capability
27+
| lcap is a reference to a value parameter
28+
| lcap² is a parameter in an anonymous function in method bar
2129
|
2230
| longer explanation available when compiling with `-explain`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
object Test

0 commit comments

Comments
 (0)