Skip to content

Commit 3552326

Browse files
authored
Merge pull request #1974 from dotty-staging/fix/ctx-capture
Avoid accidental captures of Context
2 parents 6189ffe + 7c4a9ec commit 3552326

File tree

14 files changed

+88
-60
lines changed

14 files changed

+88
-60
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,17 @@ object Annotations {
117117
}
118118

119119
/** Create an annotation where the symbol and the tree are computed lazily. */
120-
def deferredSymAndTree(sym: => Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation =
120+
def deferredSymAndTree(symf: Context => Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation =
121121
new LazyAnnotation {
122-
lazy val symf = sym
123-
124-
override def symbol(implicit ctx: Context): Symbol = symf
122+
private[this] var mySym: Symbol = _
123+
124+
override def symbol(implicit ctx: Context): Symbol = {
125+
if (mySym == null || mySym.defRunId != ctx.runId) {
126+
mySym = symf(ctx)
127+
assert(mySym != null)
128+
}
129+
mySym
130+
}
125131
def complete(implicit ctx: Context) = treeFn(ctx)
126132
}
127133

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,12 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
401401
def forwardRefs(from: Symbol, to: Type, prefs: List[TypeRef]) = to match {
402402
case to @ TypeBounds(lo1, hi1) if lo1 eq hi1 =>
403403
for (pref <- prefs) {
404-
def forward(): Unit =
404+
def forward()(implicit ctx: Context): Unit =
405405
for (argSym <- pref.decls)
406406
if (argSym is BaseTypeArg)
407407
forwardRef(argSym, from, to, cls, decls)
408408
pref.info match {
409-
case info: TempClassInfo => info.addSuspension(forward)
409+
case info: TempClassInfo => info.addSuspension(implicit ctx => forward())
410410
case _ => forward()
411411
}
412412
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3088,14 +3088,14 @@ object Types {
30883088
* be no longer temporary. These actions will be performed once `cls` gets a real
30893089
* ClassInfo.
30903090
*/
3091-
private var suspensions: List[() => Unit] = Nil
3091+
private var suspensions: List[Context => Unit] = Nil
30923092

3093-
def addSuspension(suspension: () => Unit): Unit = suspensions ::= suspension
3093+
def addSuspension(suspension: Context => Unit): Unit = suspensions ::= suspension
30943094

30953095
/** Install classinfo with known parents in `denot` and resume all suspensions */
30963096
def finalize(denot: SymDenotation, parents: List[TypeRef])(implicit ctx: Context) = {
30973097
denot.info = derivedClassInfo(classParents = parents)
3098-
suspensions.foreach(_())
3098+
suspensions.foreach(_(ctx))
30993099
}
31003100
}
31013101

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ class ClassfileParser(
806806
def classSymbol(externalName: Name)(implicit ctx: Context): Symbol = {
807807
/** Return the symbol of `innerName`, having the given `externalName`. */
808808
def innerSymbol(externalName: Name, innerName: Name, static: Boolean): Symbol = {
809-
def getMember(sym: Symbol, name: Name): Symbol =
809+
def getMember(sym: Symbol, name: Name)(implicit ctx: Context): Symbol =
810810
if (static)
811811
if (sym == classRoot.symbol) staticScope.lookup(name)
812812
else sym.companionModule.info.member(name).symbol

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
554554
val end = readEnd()
555555
val tp = readType()
556556
val lazyAnnotTree = readLater(end, rdr => ctx => rdr.readTerm()(ctx))
557-
annots += Annotation.deferredSymAndTree(tp.typeSymbol, _ => lazyAnnotTree.complete)
557+
annots += Annotation.deferredSymAndTree(
558+
implicit ctx => tp.typeSymbol,
559+
implicit ctx => lazyAnnotTree.complete)
558560
case tag =>
559561
assert(false, s"illegal modifier tag $tag at $currentAddr, end = $end")
560562
}
@@ -769,7 +771,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
769771
cls.setApplicableFlags(fork.indexStats(end))
770772
val constr = readIndexedDef().asInstanceOf[DefDef]
771773

772-
def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree]): (List[Tree], List[Tree]) =
774+
def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree])(implicit ctx: Context): (List[Tree], List[Tree]) =
773775
(tparams, stats) match {
774776
case (tparam :: tparams1, (alias: TypeDef) :: stats1)
775777
if tparam.name == alias.name.expandedName(cls) =>

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,9 +932,10 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
932932
protected def deferredAnnot(end: Int)(implicit ctx: Context): Annotation = {
933933
val start = readIndex
934934
val atp = readTypeRef()
935+
val phase = ctx.phase
935936
Annotation.deferred(
936-
atp.typeSymbol, implicit ctx1 =>
937-
atReadPos(start, () => readAnnotationContents(end)(ctx1.withPhase(ctx.phase))))
937+
atp.typeSymbol, implicit ctx =>
938+
atReadPos(start, () => readAnnotationContents(end)(ctx.withPhase(phase))))
938939
}
939940

940941
/* Read an abstract syntax tree */

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annot
77
import StdNames.{nme, tpnme}
88
import ast.Trees._, ast._
99
import typer.Implicits._
10+
import typer.ImportInfo
1011
import config.Config
1112
import java.lang.Integer.toOctalString
1213
import config.Config.summarizeDepth
@@ -503,6 +504,17 @@ class PlainPrinter(_ctx: Context) extends Printer {
503504
"?Unknown Implicit Result?"
504505
}
505506

507+
def toText(importInfo: ImportInfo): Text = {
508+
val siteStr = importInfo.site.show
509+
val exprStr = if (siteStr endsWith ".type") siteStr dropRight 5 else siteStr
510+
val selectorStr = importInfo.selectors match {
511+
case Ident(name) :: Nil => name.show
512+
case _ => "{...}"
513+
}
514+
s"import $exprStr.$selectorStr"
515+
}
516+
517+
506518
private var maxSummarized = Int.MaxValue
507519

508520
def summarized[T](depth: Int)(op: => T): T = {

compiler/src/dotty/tools/dotc/printing/Printer.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Texts._, ast.Trees._
66
import Types.Type, Symbols.Symbol, Contexts.Context, Scopes.Scope, Constants.Constant,
77
Names.Name, Denotations._, Annotations.Annotation
88
import typer.Implicits.SearchResult
9+
import typer.ImportInfo
910

1011
/** The base class of all printers
1112
*/
@@ -98,6 +99,9 @@ abstract class Printer {
9899
/** Textual representation of implicit search result */
99100
def toText(result: SearchResult): Text
100101

102+
/** Textual representation of info relating to an import clause */
103+
def toText(result: ImportInfo): Text
104+
101105
/** Perform string or text-producing operation `op` so that only a
102106
* summarized text with given recursion depth is shown
103107
*/

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
119119
// now this speculatively transforms tree and throws away result in many cases
120120
val rhsSemiTransformed = {
121121
val transformer = new TailRecElimination(origMeth, dd.tparams, owner, thisTpe, mandatory, label, abstractOverClass = defIsTopLevel)
122-
val rhs = atGroupEnd(transformer.transform(dd.rhs)(_))
122+
val rhs = atGroupEnd(implicit ctx => transformer.transform(dd.rhs))
123123
rewrote = transformer.rewrote
124124
rhs
125125
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
683683
*
684684
* { val xs = es; e' = e' + args }
685685
*/
686-
def typedOpAssign: Tree = track("typedOpAssign") {
686+
def typedOpAssign(implicit ctx: Context): Tree = track("typedOpAssign") {
687687
val Apply(Select(lhs, name), rhss) = tree
688688
val lhs1 = typedExpr(lhs)
689689
val liftedDefs = new mutable.ListBuffer[Tree]
@@ -805,16 +805,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
805805
* whereas overloaded variants need to have a conforming variant.
806806
*/
807807
def trySelectUnapply(qual: untpd.Tree)(fallBack: Tree => Tree): Tree = {
808-
val genericProto = new UnapplyFunProto(WildcardType, this)
809-
def specificProto = new UnapplyFunProto(selType, this)
810808
// try first for non-overloaded, then for overloaded ocurrences
811809
def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree =
812-
tryEither {
813-
implicit ctx => typedExpr(untpd.Select(qual, name), specificProto)
810+
tryEither { implicit ctx =>
811+
val specificProto = new UnapplyFunProto(selType, this)
812+
typedExpr(untpd.Select(qual, name), specificProto)
814813
} {
815814
(sel, _) =>
816-
tryEither {
817-
implicit ctx => typedExpr(untpd.Select(qual, name), genericProto)
815+
tryEither { implicit ctx =>
816+
val genericProto = new UnapplyFunProto(WildcardType, this)
817+
typedExpr(untpd.Select(qual, name), genericProto)
818818
} {
819819
(_, _) => fallBack(sel)
820820
}

0 commit comments

Comments
 (0)