Skip to content

Commit f73a73a

Browse files
committed
Auto-boxing of arguments of applied types
1 parent 7066ef7 commit f73a73a

File tree

8 files changed

+20
-18
lines changed

8 files changed

+20
-18
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ extension (tp: Type)
4343

4444
def boxed(using Context): Type = tp.dealias match
4545
case tp @ CapturingType(parent, refs) =>
46-
def boxedTp = CapturingType(parent, refs, boxed = true)
46+
def boxedTp = parent.boxed match
47+
case CapturingType(parent1, refs1) =>
48+
CapturingType(parent1, refs ++ refs1, boxed = true)
49+
case parent1 =>
50+
CapturingType(parent1, refs, boxed = true)
4751
if tp.isBoxed || refs.isAlwaysEmpty then tp
4852
else tp.annot match
4953
case ann: CaptureAnnotation =>
@@ -57,6 +61,12 @@ extension (tp: Type)
5761
case _ =>
5862
tp
5963

64+
def boxedUnlessFun(tycon: Type)(using Context) =
65+
if ctx.phase != Phases.checkCapturesPhase || defn.isFunctionClass(tycon.typeSymbol)
66+
then tp
67+
else tp.boxed
68+
//.showing(i"boxedUF $tp in $tycon = $result")
69+
6070
/** The boxed capture set of a type */
6171
def boxedCaptured(using Context): CaptureSet =
6272
def getBoxed(tp: Type): CaptureSet = tp match

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,5 @@ object Config {
246246
*/
247247
inline val ccAllowUnsoundMaps = false
248248

249-
@annotation.internal.sharable var checkBoxes = true
249+
val checkBoxes = true
250250
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Names._
1212
import Flags.{Module, Provisional}
1313
import dotty.tools.dotc.config.Config
1414
import cc.CaptureSet.IdentityCaptRefMap
15+
import cc.boxedUnlessFun
1516

1617
object TypeApplications {
1718

@@ -494,7 +495,7 @@ class TypeApplications(val self: Type) extends AnyVal {
494495
* Existential types in arguments are returned as TypeBounds instances.
495496
*/
496497
final def argInfos(using Context): List[Type] = self.stripped match {
497-
case AppliedType(tycon, args) => args
498+
case AppliedType(tycon, args) => args.mapconserve(_.boxedUnlessFun(tycon))
498499
case _ => Nil
499500
}
500501

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import typer.ProtoTypes.constrained
2323
import typer.Applications.productSelectorTypes
2424
import reporting.trace
2525
import annotation.constructorOnly
26-
import cc.{CapturingType, derivedCapturingType, CaptureSet, stripCapturing, isBoxedCapturing}
26+
import cc.{CapturingType, derivedCapturingType, CaptureSet, stripCapturing, isBoxedCapturing, boxedUnlessFun}
2727

2828
/** Provides methods to compare types.
2929
*/
@@ -1635,7 +1635,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
16351635
else if v > 0 then isSubType(arg1, arg2)
16361636
else isSameType(arg2, arg1)
16371637

1638-
isSubArg(args1.head, args2.head)
1638+
isSubArg(args1.head.boxedUnlessFun(tp1), args2.head.boxedUnlessFun(tp1))
16391639
} && recurArgs(args1.tail, args2.tail, tparams2.tail)
16401640

16411641
recurArgs(args1, args2, tparams2)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import config.Printers.{core, typr, matchTypes}
3636
import reporting.{trace, Message}
3737
import java.lang.ref.WeakReference
3838
import compiletime.uninitialized
39-
import cc.{CapturingType, CaptureSet, derivedCapturingType, retainedElems, isBoxedCapturing, EventuallyCapturingType}
39+
import cc.{CapturingType, CaptureSet, derivedCapturingType, retainedElems, isBoxedCapturing, EventuallyCapturingType, boxedUnlessFun}
4040
import CaptureSet.{CompareResult, IdempotentCaptRefMap, IdentityCaptRefMap}
4141

4242
import scala.annotation.internal.sharable
@@ -2538,15 +2538,15 @@ object Types {
25382538
val cls = tparam.owner
25392539
val base = pre.baseType(cls)
25402540
base.stripped match {
2541-
case AppliedType(_, allArgs) =>
2541+
case AppliedType(tycon, allArgs) =>
25422542
var tparams = cls.typeParams
25432543
var args = allArgs
25442544
var idx = 0
25452545
while (tparams.nonEmpty && args.nonEmpty) {
25462546
if (tparams.head.eq(tparam))
25472547
return args.head match {
25482548
case _: TypeBounds if !widenAbstract => TypeRef(pre, tparam)
2549-
case arg => arg
2549+
case arg => arg.boxedUnlessFun(tycon)
25502550
}
25512551
tparams = tparams.tail
25522552
args = args.tail

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ class CheckCaptures extends Recheck, SymTransformer:
121121
// ^^^ TODO: Can we avoid doing overrides checks twice?
122122
// We need to do them here since only at this phase CaptureTypes are relevant
123123
// But maybe we can then elide the check during the RefChecks phase if -Ycc is set?
124-
Config.checkBoxes = false // !!!
125124
checkAllOverrides(ctx.owner.asClass)
126-
Config.checkBoxes = true // !!!
127125
case _ =>
128126
traverseChildren(t)
129127

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@
1515
| ^^^^^^
1616
| The expression's type box {*} String -> String is not allowed to capture the root capability `*`.
1717
| This usually means that a capability persists longer than its allowed lifetime.
18-
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:21:13 -----------------------------------------
19-
21 | b = List(g) // error !!! Probably spurious due to box comparison
20-
| ^
21-
| Found: Seq[{cap3} String -> ? String]
22-
| Required: Seq[box {cap3} (x$0: ? String) -> ? String]
23-
|
24-
| longer explanation available when compiling with `-explain`
2518
-- Error: tests/neg-custom-args/captures/vars.scala:30:8 ---------------------------------------------------------------
2619
30 | local { cap3 => // error
2720
| ^

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def test(cap1: Cap, cap2: Cap) =
1818
val cap3: Cap = CC()
1919
def g(x: String): String = if cap3 == cap3 then "" else "a"
2020
a = g
21-
b = List(g) // error !!! Probably spurious due to box comparison
21+
b = List(g)
2222
val gc = g
2323
g
2424

0 commit comments

Comments
 (0)