Skip to content

Commit fd9e895

Browse files
committed
Re-enable handleEtaExpansionsSpecially setting
This gives better error messages. Previously we thought this would make reach capabilities unsound, but I don't see an issue with the latest design.
1 parent e6b08de commit fd9e895

File tree

8 files changed

+44
-38
lines changed

8 files changed

+44
-38
lines changed

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,12 @@ object ccConfig:
2727
*/
2828
inline val allowUnsoundMaps = false
2929

30-
/** If true, when computing the memberinfo of a refined type created
31-
* by addCaptureRefinements take the refineInfo directly without intersecting
32-
* with the parent info.
33-
*/
34-
inline val optimizedRefinements = false
35-
3630
/** If enabled, use a special path in recheckClosure for closures
3731
* that are eta expansions. This can improve some error messages but
3832
* currently leads to unsoundess for handling reach capabilities.
3933
* TODO: The unsoundness needs followin up.
4034
*/
41-
inline val handleEtaExpansionsSpecially = false
35+
inline val handleEtaExpansionsSpecially = true
4236

4337
/** If true, use existential capture set variables */
4438
def useExistentials(using Context) =

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -863,23 +863,19 @@ object Types extends TypeUtils {
863863
}
864864
else
865865
val isRefinedMethod = rinfo.isInstanceOf[MethodOrPoly]
866-
rinfo match
867-
case CapturingType(_, refs: CaptureSet.RefiningVar) if ccConfig.optimizedRefinements =>
868-
pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
866+
val joint = pdenot.meet(
867+
new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId), pre, isRefinedMethod),
868+
pre,
869+
safeIntersection = ctx.base.pendingMemberSearches.contains(name))
870+
joint match
871+
case joint: SingleDenotation
872+
if isRefinedMethod
873+
&& (rinfo <:< joint.info
874+
|| name == nme.apply && defn.isFunctionType(tp.parent)) =>
875+
// use `rinfo` to keep the right parameter names for named args. See i8516.scala.
876+
joint.derivedSingleDenotation(joint.symbol, rinfo, pre, isRefinedMethod)
869877
case _ =>
870-
val joint = pdenot.meet(
871-
new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId), pre, isRefinedMethod),
872-
pre,
873-
safeIntersection = ctx.base.pendingMemberSearches.contains(name))
874-
joint match
875-
case joint: SingleDenotation
876-
if isRefinedMethod
877-
&& (rinfo <:< joint.info
878-
|| name == nme.apply && defn.isFunctionType(tp.parent)) =>
879-
// use `rinfo` to keep the right parameter names for named args. See i8516.scala.
880-
joint.derivedSingleDenotation(joint.symbol, rinfo, pre, isRefinedMethod)
881-
case _ =>
882-
joint
878+
joint
883879
}
884880

885881
def goApplied(tp: AppliedType, tycon: HKTypeLambda) =

tests/neg-custom-args/captures/effect-swaps-explicit.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@
2525
-- Error: tests/neg-custom-args/captures/effect-swaps-explicit.scala:68:15 ---------------------------------------------
2626
68 | Result.make: //lbl ?=> // error, escaping label from Result
2727
| ^^^^^^^^^^^
28-
|local reference contextual$9 from (using contextual$9: boundary.Label[Result[box Future[box T^?]^{fr, contextual$9, contextual$9}, box E^?]]^):
29-
| box Future[box T^?]^{fr, contextual$9, contextual$9} leaks into outer capture set of type parameter T of method make in object Result
28+
|local reference contextual$9 from (using contextual$9: boundary.Label[Result[box Future[box T^?]^{fr, contextual$9}, box E^?]]^):
29+
| box Future[box T^?]^{fr, contextual$9} leaks into outer capture set of type parameter T of method make in object Result

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@
66
|
77
| longer explanation available when compiling with `-explain`
88
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21614.scala:12:12 ---------------------------------------
9-
12 | files.map(new Logger(_)) // error, Q: can we improve the error message?
9+
12 | files.map(new Logger(_)) // error, Q: can we improve the error message? // error
1010
| ^^^^^^^^^^^^^
11-
| Found: Logger{val f: (_$1 : File^{files*})}^
12-
| Required: Logger{val f: File^?}^?
11+
| Found: (_$1: box File^{files*}) ->{files*} (ex$4: caps.Exists) -> Logger{val f: File^{_$1}}^{ex$4}
12+
| Required: (_$1: box File^{files*}) -><fluid> box Logger{val f: File^?}^{ex$4, ex$4²}
1313
|
14-
| Note that the universal capability `cap`
15-
| cannot be included in capture set ?
14+
| where: ex$4 is a reference to a value parameter
15+
| ex$4² is a reference to a value parameter
16+
|
17+
|
18+
| Note that the universal capability `cap`
19+
| cannot be included in capture set ?
1620
|
1721
| longer explanation available when compiling with `-explain`
22+
-- Error: tests/neg-custom-args/captures/i21614.scala:12:8 -------------------------------------------------------------
23+
12 | files.map(new Logger(_)) // error, Q: can we improve the error message? // error
24+
| ^^^^^^^^^
25+
| escaping local reference ex$4.type

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ def mkLoggers1[F <: File^](@use files: List[F]): List[Logger^] =
99
files.map((f: F) => new Logger(f)) // error, Q: can we make this pass (see #19076)?
1010

1111
def mkLoggers2(@use files: List[File^]): List[Logger^] =
12-
files.map(new Logger(_)) // error, Q: can we improve the error message?
12+
files.map(new Logger(_)) // error, Q: can we improve the error message? // error

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
| that type captures the root capability `cap`.
66
| This is often caused by a local capability in an argument of constructor Ref
77
| leaking as part of its result.
8-
-- Error: tests/neg-custom-args/captures/levels.scala:24:11 ------------------------------------------------------------
8+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/levels.scala:24:11 ---------------------------------------
99
24 | r.setV(g) // error
1010
| ^
11-
| reference (cap3 : CC^) is not included in the allowed capture set ? of value r
11+
| Found: box (x: String) ->{cap3} String
12+
| Required: box (x$0: String) ->? String
1213
|
1314
| Note that reference (cap3 : CC^), defined in method scope
1415
| cannot be included in outer capture set ? of value r
16+
|
17+
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/vars-simple.check

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
| since at least one of their capture sets contains the root capability `cap`
99
|
1010
| longer explanation available when compiling with `-explain`
11-
-- Error: tests/neg-custom-args/captures/vars-simple.scala:16:8 --------------------------------------------------------
11+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars-simple.scala:16:8 -----------------------------------
1212
16 | a = g // error
1313
| ^
14-
| reference (cap3 : Cap) is not included in the allowed capture set {cap1, cap2}
15-
| of an enclosing function literal with expected type box String ->{cap1, cap2} String
14+
| Found: box (x: String) ->{cap3} String
15+
| Required: box (x: String) ->{cap1, cap2} String
16+
|
17+
| longer explanation available when compiling with `-explain`
1618
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars-simple.scala:17:12 ----------------------------------
1719
17 | b = List(g) // error
1820
| ^^^^^^^

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
|
66
| Note that reference (cap3 : Cap), defined in method scope
77
| cannot be included in outer capture set {cap1} of variable a
8-
-- Error: tests/neg-custom-args/captures/vars.scala:25:8 ---------------------------------------------------------------
8+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:25:8 ------------------------------------------
99
25 | a = g // error
1010
| ^
11-
| reference (cap3 : Cap) is not included in the allowed capture set {cap1} of variable a
11+
| Found: (x: String) ->{cap3} String
12+
| Required: (x$0: String) ->{cap1} String
1213
|
1314
| Note that reference (cap3 : Cap), defined in method scope
1415
| cannot be included in outer capture set {cap1} of variable a
16+
|
17+
| longer explanation available when compiling with `-explain`
1518
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:27:12 -----------------------------------------
1619
27 | b = List(g) // error
1720
| ^^^^^^^

0 commit comments

Comments
 (0)