diff --git a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala index a4551fa2b86c..dec1a381e94c 100644 --- a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala +++ b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala @@ -1076,9 +1076,12 @@ class CheckCaptures extends Recheck, SymTransformer: tree.tpt match case tpt: InferredTypeTree if !canUseInferred => val expected = tpt.tpe.dropAllRetains - todoAtPostCheck += (() => checkConformsExpr(tp, expected, tree.rhs, addenda(expected))) - // The check that inferred <: expected is done after recheck so that it - // does not interfere with normal rechecking by constraining capture set variables. + todoAtPostCheck += { () => + withCapAsRoot: + checkConformsExpr(tp, expected, tree.rhs, addenda(expected)) + // The check that inferred <: expected is done after recheck so that it + // does not interfere with normal rechecking by constraining capture set variables. + } case _ => tp end checkInferredResult diff --git a/compiler/src/dotty/tools/dotc/cc/root.scala b/compiler/src/dotty/tools/dotc/cc/root.scala index ee668efa8378..472dd37aa543 100644 --- a/compiler/src/dotty/tools/dotc/cc/root.scala +++ b/compiler/src/dotty/tools/dotc/cc/root.scala @@ -340,6 +340,7 @@ object root: x || t.dealiasKeepAnnots.match case Fresh(_) => false case t: TermRef => t.isCap || this(x, t.widen) + case CapturingType(t1, refs) => refs.containsCap || this(x, t1) case x: ThisType => false case _ => foldOver(x, t) @@ -349,7 +350,9 @@ object root: case refs: CaptureSet => refs.elems.exists(_.stripReadOnly.isCap) - if refs.exists(containsCap) then ctx.withProperty(PrintFresh, Some(())) - else ctx + if refs.exists(containsCap) then + ctx.withProperty(PrintFresh, Some(())) + else + ctx end printContext end root \ No newline at end of file diff --git a/tests/neg-custom-args/captures/capt-depfun.check b/tests/neg-custom-args/captures/capt-depfun.check index 7cd838d72dc0..d7ad819fb423 100644 --- a/tests/neg-custom-args/captures/capt-depfun.check +++ b/tests/neg-custom-args/captures/capt-depfun.check @@ -2,7 +2,7 @@ 11 | val dc: ((Str^{y, z}) => Str^{y, z}) = ac(g()) // error // error: separatioon | ^^^^^^^ | Found: Str^{} ->{ac, y, z} Str^{y, z} - | Required: Str^{y, z} ->{fresh} Str^{y, z} + | Required: Str^{y, z} => Str^{y, z} | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/capt-depfun.scala:11:24 ------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/cc-existential-conformance.check b/tests/neg-custom-args/captures/cc-existential-conformance.check index bc94b97fc327..65367fad1df1 100644 --- a/tests/neg-custom-args/captures/cc-existential-conformance.check +++ b/tests/neg-custom-args/captures/cc-existential-conformance.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:8:24 -------------------- 8 | val y: A -> Fun[B^] = x // error | ^ - | Found: (x : A -> (x²: A) -> B^{localcap}) - | Required: A -> A -> B^{fresh} + | Found: (x : A -> (x²: A) -> B^) + | Required: A -> A -> B^ | | where: x is a value in method test | x² is a reference to a value parameter @@ -21,8 +21,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:13:19 ------------------- 13 | val y: Fun[B^] = x // error | ^ - | Found: (x : (x²: A) -> B^{localcap}) - | Required: A -> B^{fresh} + | Found: (x : (x²: A) -> B^) + | Required: A -> B^ | | where: x is a value in method test2 | x² is a reference to a value parameter diff --git a/tests/neg-custom-args/captures/i19330.check b/tests/neg-custom-args/captures/i19330.check index 06a074c40a10..91ba7f234845 100644 --- a/tests/neg-custom-args/captures/i19330.check +++ b/tests/neg-custom-args/captures/i19330.check @@ -14,7 +14,7 @@ 22 | val bad: bar.T = foo(bar) // error | ^^^^^^^^ | Found: bar.T - | Required: () => Logger^ + | Required: () ->{fresh} Logger^{fresh} | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/i19330.scala:16:14 ------------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/i21614.check b/tests/neg-custom-args/captures/i21614.check index 6f1a2a4e23fa..e8d4c9f03102 100644 --- a/tests/neg-custom-args/captures/i21614.check +++ b/tests/neg-custom-args/captures/i21614.check @@ -8,8 +8,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21614.scala:15:12 --------------------------------------- 15 | files.map(new Logger(_)) // error, Q: can we improve the error message? | ^^^^^^^^^^^^^ - | Found: (_$1: box File^{files*}) ->{files*} box Logger{val f: File^{_$1}}^{localcap.rd, _$1} - | Required: (_$1: box File^{files*}) ->{fresh} box Logger{val f: File^?}^? + | Found: (_$1: box File^{files*}) ->{files*} box Logger{val f: File^{_$1}}^{cap.rd, _$1} + | Required: (_$1: box File^{files*}) => box Logger{val f: File^?}^? | | Note that reference .rd | cannot be included in outer capture set ? diff --git a/tests/pos-custom-args/captures/i23027.scala b/tests/pos-custom-args/captures/i23027.scala new file mode 100644 index 000000000000..b7fc06d2bf27 --- /dev/null +++ b/tests/pos-custom-args/captures/i23027.scala @@ -0,0 +1,12 @@ +import language.experimental.captureChecking + +trait Test { + def foo(x: Test): Test = + Test.bar + ??? +} + +object Test { + val _bar: Any => Any = identity + def bar[T] = _bar.asInstanceOf[T => T] // error +}