Skip to content

Commit 15f40a9

Browse files
authored
Loosen the "does not match previously inferred" criterion (#23067)
The expected type here is still the one using cap, not fresh. So it's OK if the actual type uses fresh where the expected uses cap. Also: fix hasCap test to establish PrintFresh criterion. This was missing a case, it seems.
2 parents c4531d4 + 627b6e5 commit 15f40a9

File tree

7 files changed

+31
-13
lines changed

7 files changed

+31
-13
lines changed

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,12 @@ class CheckCaptures extends Recheck, SymTransformer:
10811081
tree.tpt match
10821082
case tpt: InferredTypeTree if !canUseInferred =>
10831083
val expected = tpt.tpe.dropAllRetains
1084-
todoAtPostCheck += (() => checkConformsExpr(tp, expected, tree.rhs, addenda(expected)))
1085-
// The check that inferred <: expected is done after recheck so that it
1086-
// does not interfere with normal rechecking by constraining capture set variables.
1084+
todoAtPostCheck += { () =>
1085+
withCapAsRoot:
1086+
checkConformsExpr(tp, expected, tree.rhs, addenda(expected))
1087+
// The check that inferred <: expected is done after recheck so that it
1088+
// does not interfere with normal rechecking by constraining capture set variables.
1089+
}
10871090
case _ =>
10881091
tp
10891092
end checkInferredResult

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ object root:
340340
x || t.dealiasKeepAnnots.match
341341
case Fresh(_) => false
342342
case t: TermRef => t.isCap || this(x, t.widen)
343+
case CapturingType(t1, refs) => refs.containsCap || this(x, t1)
343344
case x: ThisType => false
344345
case _ => foldOver(x, t)
345346

@@ -349,7 +350,9 @@ object root:
349350
case refs: CaptureSet =>
350351
refs.elems.exists(_.stripReadOnly.isCap)
351352

352-
if refs.exists(containsCap) then ctx.withProperty(PrintFresh, Some(()))
353-
else ctx
353+
if refs.exists(containsCap) then
354+
ctx.withProperty(PrintFresh, Some(()))
355+
else
356+
ctx
354357
end printContext
355358
end root

tests/neg-custom-args/captures/capt-depfun.check

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
11 | val dc: ((Str^{y, z}) => Str^{y, z}) = ac(g()) // error // error: separatioon
33
| ^^^^^^^
44
| Found: Str^{} ->{ac, y, z} Str^{y, z}
5-
| Required: Str^{y, z} ->{fresh} Str^{y, z}
5+
| Required: Str^{y, z} => Str^{y, z}
66
|
77
| longer explanation available when compiling with `-explain`
88
-- Error: tests/neg-custom-args/captures/capt-depfun.scala:11:24 -------------------------------------------------------

tests/neg-custom-args/captures/cc-existential-conformance.check

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:8:24 --------------------
22
8 | val y: A -> Fun[B^] = x // error
33
| ^
4-
| Found: (x : A -> (x²: A) -> B^{localcap})
5-
| Required: A -> A -> B^{fresh}
4+
| Found: (x : A -> (x²: A) -> B^)
5+
| Required: A -> A -> B^
66
|
77
| where: x is a value in method test
88
| x² is a reference to a value parameter
@@ -21,8 +21,8 @@
2121
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/cc-existential-conformance.scala:13:19 -------------------
2222
13 | val y: Fun[B^] = x // error
2323
| ^
24-
| Found: (x : (x²: A) -> B^{localcap})
25-
| Required: A -> B^{fresh}
24+
| Found: (x : (x²: A) -> B^)
25+
| Required: A -> B^
2626
|
2727
| where: x is a value in method test2
2828
| x² is a reference to a value parameter

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
22 | val bad: bar.T = foo(bar) // error
1515
| ^^^^^^^^
1616
| Found: bar.T
17-
| Required: () => Logger^
17+
| Required: () ->{fresh} Logger^{fresh}
1818
|
1919
| longer explanation available when compiling with `-explain`
2020
-- Error: tests/neg-custom-args/captures/i19330.scala:16:14 ------------------------------------------------------------

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21614.scala:15:12 ---------------------------------------
99
15 | files.map(new Logger(_)) // error, Q: can we improve the error message?
1010
| ^^^^^^^^^^^^^
11-
| Found: (_$1: box File^{files*}) ->{files*} box Logger{val f: File^{_$1}}^{localcap.rd, _$1}
12-
| Required: (_$1: box File^{files*}) ->{fresh} box Logger{val f: File^?}^?
11+
| Found: (_$1: box File^{files*}) ->{files*} box Logger{val f: File^{_$1}}^{cap.rd, _$1}
12+
| Required: (_$1: box File^{files*}) => box Logger{val f: File^?}^?
1313
|
1414
| Note that reference <cap of (_$1: box File^{files*}): box Logger{val f: File^?}^?>.rd
1515
| cannot be included in outer capture set ?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import language.experimental.captureChecking
2+
3+
trait Test {
4+
def foo(x: Test): Test =
5+
Test.bar
6+
???
7+
}
8+
9+
object Test {
10+
val _bar: Any => Any = identity
11+
def bar[T] = _bar.asInstanceOf[T => T] // error
12+
}

0 commit comments

Comments
 (0)