Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1041,18 +1041,28 @@ class CheckCaptures extends Recheck, SymTransformer:
checkConformsExpr(argType, paramType, param)
.showing(i"compared expected closure formal $argType against $param with ${paramTpt.nuType}", capt)
if resType.isValueType && isFullyDefined(resType, ForceDegree.none) then
val localResType = pt match

def updateTpt(localResType: Type) =
mdef.tpt.updNuType(localResType)
// Make sure we affect the info of the anonfun by the previous updNuType
// unless the info is already defined in a previous phase and does not change.
assert(!anonfun.isCompleted || anonfun.denot.validFor.firstPhaseId != thisPhase.id)

pt match
case RefinedType(_, _, mt: MethodType) =>
inContext(ctx.withOwner(anonfun)):
Internalize(mt)(resType)
case _ => resType
mdef.tpt.updNuType(localResType)
// Make sure we affect the info of the anonfun by the previous updNuType
// unless the info is already defined in a previous phase and does not change.
assert(!anonfun.isCompleted || anonfun.denot.validFor.firstPhaseId != thisPhase.id)
//println(i"updating ${mdef.tpt} to $localResType/${mdef.tpt.nuType}")
if !mt.isResultDependent then
// If mt is result dependent we could compensate this by
// internalizing `resType.substParams(mt, params.tpes)`.
// But this tends to give worse error messages, so we refrain
// from doing that and don't update the local result type instead.
val localResType = inContext(ctx.withOwner(anonfun)):
Internalize(mt)(resType)
updateTpt(localResType)
case _ =>
updateTpt(resType)
case _ =>
case Nil =>
end matchParamsAndResult

openClosures = (anonfun, pt) :: openClosures
// openClosures is needed for errors but currently makes no difference
Expand Down
9 changes: 5 additions & 4 deletions tests/neg-custom-args/captures/filevar.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/filevar.scala:15:12 --------------------------------------
15 | withFile: f => // error with level checking, was OK under both schemes before
| ^
|Found: (f: File^'s1) ->'s2 Unit
|Required: (f: File^{l}) => Unit
|Found: (l: scala.caps.Capability^) ?->'s1 File^'s2 ->'s3 Unit
|Required: (l: scala.caps.Capability^) ?-> (f: File^{l}) => Unit
|
|Note that capability l cannot be included in outer capture set 's1 of parameter f.
|Note that capability l cannot be included in outer capture set 's4 of parameter f.
|
|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
|where: => refers to a root capability associated with the result type of (using l: scala.caps.Capability^): (f: File^{l}) => Unit
| ^ refers to the universal root capability
16 | val o = Service()
17 | o.file = f
18 | o.log
Expand Down
21 changes: 6 additions & 15 deletions tests/neg-custom-args/captures/i15923.check
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:27:23 ---------------------------------------
27 | val leak = withCap(cap => mkId(cap)) // error (was: no error here since type aliases don't box)
| ^^^^^^^^^^^^^^^^
|Found: (cap: test2.Cap^'s1) ->'s2 [T] => (op: test2.Cap^'s3 ->'s4 T) ->'s5 T
|Required: test2.Cap^{lcap} => [T] => (op: test2.Cap^'s6 ->'s7 T) ->'s8 T
|
|Note that capability lcap cannot be included in outer capture set 's1 of parameter cap.
|
|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
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:12:21 ---------------------------------------
12 | val leak = withCap(cap => mkId(cap)) // error
| ^^^^^^^^^^^^^^^^
|Found: (cap: Cap^'s9) ->'s10 Id[Cap^'s11]^'s12
|Required: Cap^{lcap} => Id[Cap^'s13]^'s14
|Found: (lcap: scala.caps.Capability^) ?->'s1 Cap^'s2 ->'s3 Id[Cap^'s4]^'s5
|Required: (lcap: scala.caps.Capability^) ?-> Cap^{lcap} => Id[Cap^'s6]^'s7
|
|Note that capability lcap cannot be included in outer capture set 's9 of parameter cap.
|Note that capability cap cannot be included in outer capture set 's6.
|
|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
|where: => refers to a root capability associated with the result type of (using lcap: scala.caps.Capability^): Cap^{lcap} => Id[Cap^'s6]^'s7
| ^ refers to the universal root capability
| cap is a root capability associated with the result type of (x$0: Cap^'s2): Id[Cap^'s4]^'s5
|
| longer explanation available when compiling with `-explain`
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/i15923.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ object test2:
result
}

val leak = withCap(cap => mkId(cap)) // error (was: no error here since type aliases don't box)
val leak = withCap(cap => mkId(cap)) // no error here since type aliases don't box
leak { cap => cap.use() }
}
1 change: 1 addition & 0 deletions tests/pos-custom-args/captures/i23727.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
object Test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test file is empty.

Loading