Skip to content

Commit 275218d

Browse files
committed
Several fixes to boxing
1. Update info of TypeDef symbols to account for boxing. Previously, the changes were made to the tree, but were not propagated to the symbol. 2. Maintain alias types when adding boxes. 3. Don't accidentally widen in addResultBoxes. The boxmap pos test started failing after (1), (2) before the fix (3) was added. Fixes #15749
1 parent 768dba2 commit 275218d

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ extends tpd.TreeTraverser:
4949
def apply(t: Type) = mapOver(t) match
5050
case t1 @ AppliedType(tycon, args) if !defn.isNonRefinedFunction(t1) =>
5151
t1.derivedAppliedType(tycon, args.mapConserve(box))
52+
case t1: AliasingBounds =>
53+
t1.derivedAlias(t1.alias)
5254
case t1 @ TypeBounds(lo, hi) =>
5355
t1.derivedTypeBounds(box(lo), box(hi))
5456
case t1 =>
@@ -337,6 +339,9 @@ extends tpd.TreeTraverser:
337339
then transformInferredType(tree.tpe, boxed)
338340
else transformExplicitType(tree.tpe, boxed))
339341

342+
private def updateInfo(sym: Symbol, tpe: Type)(using Context) =
343+
sym.updateInfoBetween(preRecheckPhase, thisPhase, tpe)
344+
340345
def traverse(tree: Tree)(using Context): Unit =
341346
tree match
342347
case tree: DefDef if isExcluded(tree.symbol) =>
@@ -388,11 +393,10 @@ extends tpd.TreeTraverser:
388393
def complete(denot: SymDenotation)(using Context) =
389394
denot.info = newInfo
390395
recheckDef(tree, sym)
391-
sym.updateInfoBetween(preRecheckPhase, thisPhase, completer)
396+
updateInfo(sym, completer)
392397
case tree: Bind =>
393398
val sym = tree.symbol
394-
sym.updateInfoBetween(preRecheckPhase, thisPhase,
395-
transformInferredType(sym.info, boxed = false))
399+
updateInfo(sym, transformInferredType(sym.info, boxed = false))
396400
case tree: TypeDef if tree.symbol.isClass =>
397401
val cls = tree.symbol.asClass
398402
val cinfo @ ClassInfo(prefix, _, ps, decls, selfInfo) = cls.classInfo
@@ -401,12 +405,18 @@ extends tpd.TreeTraverser:
401405
val newInfo = ClassInfo(prefix, cls, ps, decls,
402406
CapturingType(cinfo.selfType, localRefs)
403407
.showing(i"inferred self type for $cls: $result", capt))
404-
cls.updateInfoBetween(preRecheckPhase, thisPhase, newInfo)
408+
updateInfo(cls, newInfo)
405409
cls.thisType.asInstanceOf[ThisType].invalidateCaches()
406410
if cls.is(ModuleClass) then
407411
val modul = cls.sourceModule
408-
modul.updateInfoBetween(preRecheckPhase, thisPhase,
409-
CapturingType(modul.info, localRefs))
412+
updateInfo(modul, CapturingType(modul.info, localRefs))
410413
modul.termRef.invalidateCaches()
414+
case tree: TypeDef =>
415+
val info = atPhase(preRecheckPhase)(tree.symbol.info)
416+
val newInfo = transformExplicitType(info, boxed = false)
417+
if newInfo ne info then
418+
updateInfo(tree.symbol, newInfo)
419+
capt.println(i"update info of ${tree.symbol} from $info to $newInfo")
420+
411421
case _ =>
412422
end Setup

compiler/src/dotty/tools/dotc/transform/Recheck.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ abstract class Recheck extends Phase, SymTransformer:
138138
excluded = if tree.symbol.is(Private) then EmptyFlags else Private
139139
).suchThat(tree.symbol == _)
140140
constFold(tree, qualType.select(name, mbr))
141-
//.showing(i"recheck select $qualType . $name : ${mbr.symbol.info} = $result")
141+
//.showing(i"recheck select $qualType . $name : ${mbr.info} = $result")
142142

143143
def recheckBind(tree: Bind, pt: Type)(using Context): Type = tree match
144144
case Bind(name, body) =>
@@ -204,6 +204,7 @@ abstract class Recheck extends Phase, SymTransformer:
204204
Nil
205205
val argTypes = recheckArgs(tree.args, formals, fntpe.paramRefs)
206206
constFold(tree, instantiate(fntpe, argTypes, tree.fun.symbol))
207+
//.showing(i"typed app $tree : $fntpe with ${tree.args}%, % : $argTypes%, % = $result")
207208

208209
def recheckTypeApply(tree: TypeApply, pt: Type)(using Context): Type =
209210
recheck(tree.fun).widen match

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,19 @@ class CheckCaptures extends Recheck, SymTransformer:
207207
*/
208208
def addResultBoxes(tp: Type)(using Context): Type =
209209
def includeBoxed(res: Type) = tp.capturing(res.boxedCaptured)
210-
val tpw = tp.widen
211-
val boxedTpw = tpw.dealias match
210+
val tp1 = tp.dealias
211+
val boxedTp = tp1 match
212212
case tp1 @ AppliedType(_, args) if defn.isNonRefinedFunction(tp1) =>
213213
includeBoxed(args.last)
214214
case tp1 @ RefinedType(_, _, rinfo) if defn.isFunctionType(tp1) =>
215215
includeBoxed(rinfo.finalResultType)
216216
case tp1 @ CapturingType(parent, refs) =>
217217
val boxedParent = addResultBoxes(parent)
218-
if boxedParent eq parent then tpw
218+
if boxedParent eq parent then tp1
219219
else boxedParent.capturing(refs)
220220
case _ =>
221-
tpw
222-
if boxedTpw eq tpw then tp else boxedTpw
221+
tp1
222+
if boxedTp eq tp1 then tp else boxedTp
223223
end addResultBoxes
224224

225225
def assertSub(cs1: CaptureSet, cs2: CaptureSet)(using Context) =
@@ -255,7 +255,7 @@ class CheckCaptures extends Recheck, SymTransformer:
255255
selType
256256
else
257257
val qualCs = qualType.captureSet
258-
//println(i"intersect $qualType, ${selType.widen}, $qualCs, $selCs")
258+
capt.println(i"intersect $qualType, ${selType.widen}, $qualCs, $selCs in $tree")
259259
if qualCs.mightSubcapture(selCs) then
260260
selType.widen.stripCapturing.capturing(qualCs)
261261
else
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Unit
2+
object unit extends Unit
3+
4+
type Top = {*} Any
5+
6+
type LazyVal[T] = {*} Unit -> T
7+
8+
class Foo[T](val x: T)
9+
10+
// Foo[□ {*} Unit -> T]
11+
type BoxedLazyVal[T] = Foo[LazyVal[T]]
12+
13+
def force[A](v: BoxedLazyVal[A]): A =
14+
// Γ ⊢ v.x : □ {*} Unit -> A
15+
v.x(unit) // error: (unbox v.x)(unit), where (unbox v.x) should be untypable

0 commit comments

Comments
 (0)