Skip to content

Commit be625bc

Browse files
committed
Improve documentation and minimze test
Documentation around markFree and narrowLiftedOwner was added. i480 was minimzed and dependencies on dotc were removed.
1 parent 155e1be commit be625bc

File tree

2 files changed

+26
-58
lines changed

2 files changed

+26
-58
lines changed

src/dotty/tools/dotc/transform/LambdaLift.scala

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
9090
free.getOrElse(sym, Nil).toList.map(pm)
9191
}
9292

93+
/** Set `liftedOwner(sym)` to `owner` if `owner` is more deeply nested
94+
* than the previous value of `liftedowner(sym)`.
95+
*/
9396
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) = {
9497
if (sym.owner.isTerm &&
9598
owner.isProperlyContainedIn(liftedOwner(sym)) &&
@@ -100,12 +103,22 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
100103
}
101104
}
102105

103-
/** Mark symbol `sym` as being free in `enclosure`, unless `sym`
104-
* is defined in `enclosure` or there is a class between `enclosure`s owner
105-
* and the owner of `sym`. Also, update lifted owner of `enclosure` so
106+
/** Mark symbol `sym` as being free in `enclosure`, unless `sym` is defined
107+
* in `enclosure` or there is an intermediate class properly containing `enclosure`
108+
* in which `sym` is also free. Also, update `liftedOwner` of `enclosure` so
106109
* that `enclosure` can access `sym`, or its proxy in an intermediate class.
110+
* This means:
111+
*
112+
* 1. If there is an intermediate class in which `sym` is free, `enclosure`
113+
* must be contained in that class (in order to access the `sym proxy stored
114+
* in the class).
115+
*
116+
* 2. If there is no intermediate class, `enclosure` must be contained
117+
* in the class enclosing `sym`.
118+
*
107119
* Return the closest enclosing intermediate class between `enclosure` and
108-
* the owner of sym, or NoSymbol is none exists.
120+
* the owner of sym, or NoSymbol if none exists.
121+
*
109122
* pre: sym.owner.isTerm, (enclosure.isMethod || enclosure.isClass)
110123
*
111124
* The idea of `markFree` is illustrated with an example:
@@ -139,7 +152,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
139152
ctx.debuglog(i"$enclosure != ${sym.enclosure}")
140153
val intermediate =
141154
if (enclosure.is(PackageClass)) enclosure
142-
else markFree(sym, enclosure.skipConstructor.enclosure)
155+
else markFree(sym, enclosure.skipConstructor.enclosure)
156+
// `enclosure` might be a constructor, in which case we want the enclosure
157+
// of the enclosing class, so skipConstructor is needed here.
143158
if (intermediate.exists) {
144159
narrowLiftedOwner(enclosure, intermediate)
145160
intermediate

tests/pos/i480a.scala

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,15 @@
1-
package dotty.tools
2-
package dotc
3-
package core
4-
5-
import Types._, Contexts._, Symbols._, Denotations._, SymDenotations._, StdNames._, Names._
6-
import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._
7-
import pickling.UnPickler.ensureConstructor
8-
import scala.annotation.{ switch, meta }
9-
import scala.collection.{ mutable, immutable }
10-
import PartialFunction._
11-
import collection.mutable
12-
import scala.reflect.api.{ Universe => ApiUniverse }
13-
14-
object Definitions {
15-
val MaxFunctionArity, MaxTupleArity = 22
16-
}
1+
package test
172

183
/** A class defining symbols and types of standard definitions */
194
class Definitions {
205

21-
/** The HigherKinded trait corresponding to symbols `boundSyms` (which are assumed
22-
* to be the type parameters of a higher-kided type). This is a class symbol that
23-
* would be generated by the following schema.
24-
*
25-
* class LambdaXYZ extends Object with P1 with ... with Pn {
26-
* type v_1 $hk$Arg0; ...; type v_N $hk$ArgN;
27-
* type Apply
28-
* }
29-
*
30-
* Here:
31-
*
32-
* - v_i are the variances of the bound symbols (i.e. +, -, or empty).
33-
* - XYZ is a string of length N with one letter for each variant of a bound symbol,
34-
* using `P` (positive variance), `N` (negative variance), `I` (invariant).
35-
* - for each positive or negative variance v_i there is a parent trait Pj which
36-
* is the same as LambdaXYZ except that it has `I` in i-th position.
37-
*/
38-
def lambdaTrait(vcs: List[Int]): ClassSymbol = {
6+
trait LazyType { def complete(): Unit }
397

8+
def f(vcs: List[Int]): Unit = {
409
val completer = new LazyType {
41-
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
42-
// val cls = denot.asClass.classSymbol
43-
// val paramDecls = newScope
44-
// for (i <- 0 until vcs.length)
45-
// newTypeParam(cls, tpnme.lambdaArgName(i), varianceFlags(vcs(i)), paramDecls)
46-
// newTypeField(cls, tpnme.Apply, Covariant, paramDecls)
47-
val parentTraitRefs =
48-
for (i <- 0 until vcs.length if vcs(i) != 0)
49-
yield lambdaTrait(vcs.updated(i, 0)).typeRef
50-
// denot.info = ClassInfo(
51-
// ScalaPackageClass.thisType, cls, ObjectClass.typeRef :: parentTraitRefs.toList, paramDecls)
52-
}
10+
def complete(): Unit =
11+
for (i <- 0 until vcs.length if vcs(i) != 0)
12+
f(vcs.updated(i, 0))
5313
}
54-
55-
// val traitName = tpnme.lambdaTraitName(vcs)
56-
57-
// def createTrait = ???
58-
59-
???
60-
6114
}
6215
}

0 commit comments

Comments
 (0)