Skip to content

Commit 12a02c7

Browse files
committed
Merge pull request #1062 from dotty-staging/fix-#859
Fix #859
2 parents 9d8c92d + c7e71b8 commit 12a02c7

File tree

5 files changed

+15
-5
lines changed

5 files changed

+15
-5
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
199199
}
200200
compareWild
201201
case tp2: LazyRef =>
202-
isSubType(tp1, tp2.ref)
202+
!tp2.evaluating && isSubType(tp1, tp2.ref)
203203
case tp2: AnnotatedType =>
204204
isSubType(tp1, tp2.tpe) // todo: refine?
205205
case tp2: ThisType =>
@@ -299,7 +299,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
299299
}
300300
compareWild
301301
case tp1: LazyRef =>
302-
isSubType(tp1.ref, tp2)
302+
// If `tp1` is in train of being evaluated, don't force it
303+
// because that would cause an assertionError. Return false instead.
304+
// See i859.scala for an example where we hit this case.
305+
!tp1.evaluating && isSubType(tp1.ref, tp2)
303306
case tp1: AnnotatedType =>
304307
isSubType(tp1.tpe, tp2)
305308
case AndType(tp11, tp12) =>

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1972,14 +1972,15 @@ object Types {
19721972
case class LazyRef(refFn: () => Type) extends UncachedProxyType with ValueType {
19731973
private var myRef: Type = null
19741974
private var computed = false
1975-
lazy val ref = {
1975+
def ref = {
19761976
if (computed) assert(myRef != null)
19771977
else {
19781978
computed = true
19791979
myRef = refFn()
19801980
}
19811981
myRef
19821982
}
1983+
def evaluating = computed && myRef == null
19831984
override def underlying(implicit ctx: Context) = ref
19841985
override def toString = s"LazyRef($ref)"
19851986
override def equals(other: Any) = other match {

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,12 @@ object Scala2Unpickler {
101101
case cinfo => (Nil, cinfo)
102102
}
103103
val ost =
104-
if ((selfInfo eq NoType) && (denot is ModuleClass))
104+
if ((selfInfo eq NoType) && (denot is ModuleClass) && denot.sourceModule.exists)
105+
// it seems sometimes the source module does not exist for a module class.
106+
// An example is `scala.reflect.internal.Trees.Template$. Without the
107+
// `denot.sourceModule.exists` provision i859.scala crashes in the backend.
105108
denot.owner.thisType select denot.sourceModule
106109
else selfInfo
107-
108110
denot.info = ClassInfo(denot.owner.thisType, denot.classSymbol, Nil, decls, ost) // first rough info to avoid CyclicReferences
109111
var parentRefs = ctx.normalizeToClassRefs(parents, cls, decls)
110112
if (parentRefs.isEmpty) parentRefs = defn.ObjectType :: Nil

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class tests extends CompilerTest {
103103

104104
@Test def pos_i871 = compileFile(posSpecialDir, "i871", scala2mode)
105105
@Test def pos_variancesConstr = compileFile(posSpecialDir, "variances-constr", scala2mode)
106+
@Test def pos_859 = compileFile(posSpecialDir, "i859", scala2mode)(allowDeepSubtypes)
106107

107108
@Test def new_all = compileFiles(newDir, twice)
108109

tests/pos-special/i859.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Analyzer {
2+
def foo: scala.tools.nsc.Global = ???
3+
}

0 commit comments

Comments
 (0)