Skip to content

Commit de9f642

Browse files
committed
Fix liftIfHK
Could create orphan paramrefs before.
1 parent f5b0894 commit de9f642

File tree

3 files changed

+45
-50
lines changed

3 files changed

+45
-50
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,8 +1287,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12871287
tl.integrate(tparams1, tparam1.paramInfoAsSeenFrom(tp1)).bounds &
12881288
tl.integrate(tparams2, tparam2.paramInfoAsSeenFrom(tp2)).bounds),
12891289
resultTypeExp = tl =>
1290-
original(tl.integrate(tparams1, tp1).appliedTo(tl.paramRefs),
1291-
tl.integrate(tparams2, tp2).appliedTo(tl.paramRefs)))
1290+
original(tp1.appliedTo(tl.paramRefs), tp2.appliedTo(tl.paramRefs)))
12921291
}
12931292

12941293
/** Try to distribute `&` inside type, detect and handle conflicts

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

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,26 @@ class TreePickler(pickler: TastyPickler) {
119119
pickleType(c.symbolValue.termRef)
120120
}
121121

122-
def pickleType(tpe0: Type, richTypes: Boolean = false)(implicit ctx: Context): Unit = try {
122+
def pickleType(tpe0: Type, richTypes: Boolean = false)(implicit ctx: Context): Unit = {
123123
val tpe = tpe0.stripTypeVar
124-
val prev = pickledTypes.get(tpe)
125-
if (prev == null) {
126-
pickledTypes.put(tpe, currentAddr)
127-
pickleNewType(tpe, richTypes)
128-
}
129-
else {
130-
writeByte(SHARED)
131-
writeRef(prev.asInstanceOf[Addr])
124+
try {
125+
val prev = pickledTypes.get(tpe)
126+
if (prev == null) {
127+
pickledTypes.put(tpe, currentAddr)
128+
pickleNewType(tpe, richTypes)
129+
}
130+
else {
131+
writeByte(SHARED)
132+
writeRef(prev.asInstanceOf[Addr])
133+
}
134+
} catch {
135+
case ex: AssertionError =>
136+
println(i"error when pickling type $tpe")
137+
throw ex
132138
}
133-
} catch {
134-
case ex: AssertionError =>
135-
println(i"error when pickling type $tpe0")
136-
throw ex
137139
}
138140

139-
private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = try { tpe match {
141+
private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = tpe match {
140142
case AppliedType(tycon, args) =>
141143
writeByte(APPLIEDtype)
142144
withLength { pickleType(tycon); args.foreach(pickleType(_)) }
@@ -241,21 +243,10 @@ class TreePickler(pickler: TastyPickler) {
241243
pickleMethodic(POLYtype, tpe)
242244
case tpe: MethodType if richTypes =>
243245
pickleMethodic(METHODtype, tpe)
244-
case tpe: TypeParamRef =>
245-
if (!pickleParamRef(tpe))
246-
// TODO figure out why this case arises in e.g. pickling AbstractFileReader.
247-
ctx.typerState.constraint.entry(tpe) match {
248-
case TypeBounds(lo, hi) if lo eq hi => pickleNewType(lo, richTypes)
249-
case _ => assert(false, s"orphan poly parameter: $tpe")
250-
}
251-
case tpe: TermParamRef =>
252-
assert(pickleParamRef(tpe), s"orphan method parameter: $tpe")
246+
case tpe: ParamRef =>
247+
assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe")
253248
case tpe: LazyRef =>
254249
pickleType(tpe.ref)
255-
}} catch {
256-
case ex: AssertionError =>
257-
println(i"error while pickling type $tpe")
258-
throw ex
259250
}
260251

261252
def picklePackageRef(pkg: Symbol)(implicit ctx: Context): Unit = {

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

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import core.Decorators._
1818
import core.TypeErasure.isErasedType
1919
import core.Phases.Phase
2020
import core.Mode
21+
import SymUtils._
2122
import typer._
2223
import typer.ErrorReporting._
2324
import reporting.ThrowingReporter
@@ -45,7 +46,7 @@ import scala.util.control.NonFatal
4546
*/
4647
class TreeChecker extends Phase with SymTransformer {
4748
import ast.tpd._
48-
49+
import TreeChecker._
4950

5051
private val seenClasses = collection.mutable.HashMap[String, Symbol]()
5152
private val seenModuleVals = collection.mutable.HashMap[String, Symbol]()
@@ -288,26 +289,6 @@ class TreeChecker extends Phase with SymTransformer {
288289
res
289290
}
290291

291-
/** Check that TypeParamRefs and MethodParams refer to an enclosing type */
292-
def checkNoOrphans(tp: Type)(implicit ctx: Context) = new TypeMap() {
293-
val definedBinders = mutable.Set[Type]()
294-
def apply(tp: Type): Type = {
295-
tp match {
296-
case tp: BindingType =>
297-
definedBinders += tp
298-
mapOver(tp)
299-
definedBinders -= tp
300-
case tp: ParamRef =>
301-
assert(definedBinders.contains(tp.binder), s"orphan param: $tp")
302-
case tp: TypeVar =>
303-
apply(tp.underlying)
304-
case _ =>
305-
mapOver(tp)
306-
}
307-
tp
308-
}
309-
}.apply(tp)
310-
311292
def checkNotRepeated(tree: Tree)(implicit ctx: Context): tree.type = {
312293
def allowedRepeated = (tree.symbol.flags is Case) && tree.tpe.widen.isRepeatedParam
313294

@@ -467,3 +448,27 @@ class TreeChecker extends Phase with SymTransformer {
467448
}
468449
}
469450
}
451+
452+
object TreeChecker {
453+
/** Check that TypeParamRefs and MethodParams refer to an enclosing type */
454+
def checkNoOrphans(tp0: Type, tree: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = new TypeMap() {
455+
val definedBinders = new java.util.IdentityHashMap[Type, Any]
456+
def apply(tp: Type): Type = {
457+
tp match {
458+
case tp: BindingType =>
459+
definedBinders.put(tp, tp)
460+
mapOver(tp)
461+
definedBinders.remove(tp)
462+
case tp: ParamRef =>
463+
assert(definedBinders.get(tp.binder) != null, s"orphan param: ${tp.show}, hash of binder = ${System.identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0")
464+
case tp: TypeVar =>
465+
apply(tp.underlying)
466+
case tp: TypeRef if tp.info.isAlias && tp.symbol.isAliasPreferred =>
467+
apply(tp.superType)
468+
case _ =>
469+
mapOver(tp)
470+
}
471+
tp
472+
}
473+
}.apply(tp0)
474+
}

0 commit comments

Comments
 (0)