Skip to content

Commit d29d5e3

Browse files
committed
Simplify expandAliases
1 parent ac8971e commit d29d5e3

File tree

5 files changed

+39
-67
lines changed

5 files changed

+39
-67
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ import collection.mutable
1616

1717
private val Captures: Key[CaptureSet] = Key()
1818

19-
/** RetainingType will be boxed when it gets turned into a capturing type */
20-
private val NeedsBox: Key[Unit] = Key()
21-
2219
object ccConfig:
2320

2421
/** Switch whether unpickled function types and byname types should be mapped to
@@ -375,4 +372,4 @@ extension (tp: AnnotatedType)
375372
/** Is this a boxed capturing type? */
376373
def isBoxed(using Context): Boolean = tp.annot match
377374
case ann: CaptureAnnotation => ann.boxed
378-
case ann => ann.tree.hasAttachment(NeedsBox)
375+
case _ => false

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

Lines changed: 31 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ trait SetupAPI:
2525
def postCheck()(using Context): Unit
2626

2727
object Setup:
28-
case class Box(t: Type) extends UncachedGroundType, TermType:
29-
override def fallbackToText(printer: Printer): Text =
30-
Str("Box(") ~ printer.toText(t) ~ ")"
31-
def derivedBox(t1: Type): Type =
32-
if t1 eq t then this else Box(t1)
3328

3429
/** Recognizer for `res $throws exc`, returning `(res, exc)` in case of success */
3530
object throwsAlias:
@@ -125,9 +120,8 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
125120
case tp @ CapturingType(parent, refs) =>
126121
if tp.isBoxed then tp else tp.boxed
127122
case tp @ AnnotatedType(parent, ann) =>
128-
if ann.symbol == defn.RetainsAnnot then
129-
ann.tree.putAttachment(NeedsBox, ())
130-
tp
123+
if ann.symbol == defn.RetainsAnnot
124+
then CapturingType(parent, ann.tree.toCaptureSet, boxed = true)
131125
else tp.derivedAnnotatedType(box(parent), ann)
132126
case tp1 @ AppliedType(tycon, args) if defn.isNonRefinedFunction(tp1) =>
133127
val res = args.last
@@ -237,8 +231,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
237231
tp.derivedLambdaType(
238232
paramInfos = tp.paramInfos.mapConserve(_.dropAllRetains.bounds),
239233
resType = this(tp.resType))
240-
case Box(tp1) =>
241-
box(this(tp1))
242234
case _ =>
243235
mapOver(tp)
244236
addVar(addCaptureRefinements(normalizeCaptures(tp1)), ctx.owner)
@@ -259,22 +251,23 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
259251
* expands to
260252
* (erased x$0: CanThrow[E1]) ?-> (erased x$1: CanThrow[E1]) ?->{x$0} T
261253
*/
262-
private def expandThrowsAlias(tp: Type, encl: List[MethodType] = Nil): Type = tp match
263-
case throwsAlias(res, exc) =>
264-
val paramType = AnnotatedType(
265-
defn.CanThrowClass.typeRef.appliedTo(exc),
266-
Annotation(defn.ErasedParamAnnot, defn.CanThrowClass.span))
267-
val isLast = throwsAlias.unapply(res).isEmpty
268-
val paramName = nme.syntheticParamName(encl.length)
269-
val mt = ContextualMethodType(paramName :: Nil)(
254+
private def expandThrowsAlias(res: Type, exc: Type, encl: List[MethodType]): Type =
255+
val paramType = AnnotatedType(
256+
defn.CanThrowClass.typeRef.appliedTo(exc),
257+
Annotation(defn.ErasedParamAnnot, defn.CanThrowClass.span))
258+
val resDecomposed = throwsAlias.unapply(res)
259+
val paramName = nme.syntheticParamName(encl.length)
260+
val mt = ContextualMethodType(paramName :: Nil)(
270261
_ => paramType :: Nil,
271-
mt => if isLast then res else expandThrowsAlias(res, mt :: encl))
272-
val fntpe = defn.PolyFunctionOf(mt)
273-
if !encl.isEmpty && isLast then
274-
val cs = CaptureSet(encl.map(_.paramRefs.head)*)
275-
CapturingType(fntpe, cs, boxed = false)
276-
else fntpe
277-
case _ => tp
262+
mt => resDecomposed match
263+
case Some((res1, exc1)) => expandThrowsAlias(res1, exc1, mt :: encl)
264+
case _ => res
265+
)
266+
val fntpe = defn.PolyFunctionOf(mt)
267+
if !encl.isEmpty && resDecomposed.isEmpty then
268+
val cs = CaptureSet(encl.map(_.paramRefs.head)*)
269+
CapturingType(fntpe, cs, boxed = false)
270+
else fntpe
278271

279272
/** Map references to capability classes C to C^ */
280273
private def expandCapabilityClass(tp: Type): Type =
@@ -290,48 +283,30 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
290283
private def recur(t: Type): Type = normalizeCaptures(mapOver(t))
291284

292285
def apply(t: Type) =
293-
val t1 = expandThrowsAlias(t)
294-
if t1 ne t then return this(t1)
295-
val t2 = expandCapabilityClass(t)
296-
if t2 ne t then return t2
297286
t match
298-
case t @ AppliedType(tycon: TypeProxy, args) =>
299-
tycon.underlying match
300-
case TypeAlias(aliasTycon) =>
301-
val args1 =
302-
if defn.isFunctionClass(t.dealias.typeSymbol) then args
303-
else args.map(Box(_))
304-
val alias = aliasTycon.applyIfParameterized(args1)
305-
val transformed = this(alias)
306-
if transformed ne alias then
307-
//println(i"APP ALIAS $t / $alias / $transformed")
308-
transformed
309-
else
310-
//println(i"NO ALIAS $t / $alias / $transformed")
311-
recur(t)
312-
case _ =>
313-
recur(t)
314287
case t @ CapturingType(parent, refs) =>
315288
checkQualifiedRoots(t.annot.tree) // TODO: NEEDED?
316289
t.derivedCapturingType(this(parent), refs)
317290
case t @ AnnotatedType(parent, ann) =>
291+
val parent1 = this(parent)
318292
if ann.symbol == defn.RetainsAnnot then
319-
val parent1 = this(parent)
320293
for tpt <- tptToCheck do
321294
checkQualifiedRoots(ann.tree)
322295
checkWellformedLater(parent1, ann.tree, tpt)
323-
CapturingType(parent1, ann.tree.toCaptureSet, boxed = ann.tree.hasAttachment(NeedsBox))
296+
CapturingType(parent1, ann.tree.toCaptureSet)
324297
else
325-
t.derivedAnnotatedType(this(parent), ann)
326-
case Box(t1) =>
327-
box(this(t1))
298+
t.derivedAnnotatedType(parent1, ann)
299+
case throwsAlias(res, exc) =>
300+
this(expandThrowsAlias(res, exc, Nil))
328301
case t: LazyRef =>
329302
val t1 = this(t.ref)
330303
if t1 ne t.ref then t1 else t
331304
case t: TypeVar =>
332305
this(t.underlying)
333-
case _ =>
334-
recur(t)
306+
case t =>
307+
if t.isCapabilityClassRef
308+
then CapturingType(t, defn.expandedUniversalSet, boxed = false)
309+
else recur(t)
335310
end expandAliases
336311

337312
val tp1 = expandAliases(tp) // TODO: Do we still need to follow aliases?
@@ -342,11 +317,11 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
342317
/** Transform type of type tree, and remember the transformed type as the type the tree */
343318
private def transformTT(tree: TypeTree, boxed: Boolean, exact: Boolean)(using Context): Unit =
344319
if !tree.hasRememberedType then
345-
val tp = if boxed then Box(tree.tpe) else tree.tpe
346-
tree.rememberType(
320+
val transformed =
347321
if tree.isInstanceOf[InferredTypeTree] && !exact
348-
then transformInferredType(tp)
349-
else transformExplicitType(tp, tptToCheck = Some(tree)))
322+
then transformInferredType(tree.tpe)
323+
else transformExplicitType(tree.tpe, tptToCheck = Some(tree))
324+
tree.rememberType(if boxed then box(transformed) else transformed)
350325

351326
/** Substitute parameter symbols in `from` to paramRefs in corresponding
352327
* method or poly types `to`. We use a single BiTypeMap to do everything.

tests/neg-custom-args/captures/box-adapt-boxing.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def main(io: Cap^, fs: Cap^): Unit = {
1717
type Op0[X] = Box[X] -> Unit
1818
type Op1[X] = Unit -> Box[X]
1919
val f: Unit -> (Cap^{io}) -> Unit = ???
20-
val test: Op1[Op0[Cap^{io}]^{io}]^{} = f // error ??? not sure this is correct
20+
val test: Op1[Op0[Cap^{io}]^{io}]^{} = f
2121
// expected: {} Unit -> box {io} (box {io} Cap) -> Unit
2222
// actual: Unit -> ({io} Cap) -> Unit
2323
//
@@ -32,7 +32,7 @@ def main(io: Cap^, fs: Cap^): Unit = {
3232
type Id[X] = Box[X] -> Unit
3333
type Op[X] = Unit -> Box[X]
3434
val f: Unit -> (Cap^{io}) -> Unit = ???
35-
val g: Op[Id[Cap^{io}]^{fs}] = f // error
36-
val h: Op[Id[Cap^{io}]^{io}] = f // error ??? not sure this is correct
35+
val g: Op[Id[Cap^{io}]^{fs}] = f
36+
val h: Op[Id[Cap^{io}]^{io}] = f
3737
}
3838
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
27 | val boxed2 : Observe[C^] = box2(c) // error
2020
| ^^^^^^^
2121
| Found: (C{val arg: C^}^{c} => Unit) ->{c} Unit
22-
| Required: (C^ => Unit) -> Unit
22+
| Required: Observe[C^]
2323
|
2424
| longer explanation available when compiling with `-explain`
2525
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:33:33 ---------------------------------------
2626
33 | val boxed2 : Observe[C]^ = box2(c) // error
2727
| ^^^^^^^
2828
| Found: (C{val arg: C^}^ => Unit) ->? Unit
29-
| Required: (C => Unit) => Unit
29+
| Required: Observe[C]^
3030
|
3131
| longer explanation available when compiling with `-explain`
3232
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15772.scala:44:2 ----------------------------------------

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
-- Error: tests/neg-custom-args/captures/try.scala:30:65 ---------------------------------------------------------------
99
30 | (x: CanThrow[Exception]) => () => raise(new Exception)(using x) // error
1010
| ^
11-
| (x : CT[Exception]^) cannot be referenced here; it is not included in the allowed capture set {}
12-
| of an enclosing function literal with expected type () ->? Nothing
11+
| (x : CanThrow[Exception]) cannot be referenced here; it is not included in the allowed capture set {}
12+
| of an enclosing function literal with expected type () ->? Nothing
1313
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:52:2 -------------------------------------------
1414
47 |val global: () -> Int = handle {
1515
48 | (x: CanThrow[Exception]) =>

0 commit comments

Comments
 (0)