Skip to content

Commit 6bcc318

Browse files
oderskyDarkDimius
authored andcommitted
Improve documentation and minimze test
Documentation around markFree and narrowLiftedOwner was added. i480 was minimzed and dependencies on dotc were removed. (+1 squashed commit) Squashed commits: [1a84054] Test cases for #480
1 parent e0a0c39 commit 6bcc318

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
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/i480.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object O {
2+
val x: Function1[String, String] = a => a
3+
val x2: Function1[String, String] = a => "1"
4+
}

tests/pos/i480a.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test
2+
3+
/** A class defining symbols and types of standard definitions */
4+
class Definitions {
5+
6+
trait LazyType { def complete(): Unit }
7+
8+
def f(vcs: List[Int]): Unit = {
9+
val completer = new LazyType {
10+
def complete(): Unit =
11+
for (i <- 0 until vcs.length if vcs(i) != 0)
12+
f(vcs.updated(i, 0))
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)