From b7f5aa30383730dc1d2b34f9773695d0f5669bcd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 25 Sep 2013 15:02:59 +0200 Subject: Sereval more bugfixes to typer and type handling. Several of these avoided stackoverflows/cyclic references --- src/dotty/tools/dotc/core/Denotations.scala | 8 +------- src/dotty/tools/dotc/core/SymDenotations.scala | 7 +++++++ src/dotty/tools/dotc/core/TypeComparer.scala | 7 ++++++- src/dotty/tools/dotc/core/Types.scala | 16 +++++++++++----- src/dotty/tools/dotc/typer/Namer.scala | 18 ++++++++++-------- tests/pos/inferred.scala | 8 +++++++- 6 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 1b0981ad3..89c0b3861 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -460,14 +460,8 @@ object Denotations { def current(implicit ctx: Context): SingleDenotation = { val currentPeriod = ctx.period val valid = myValidFor - def stillValid(denot: SymDenotation): Boolean = - if (denot is ValidForever) true - else if (denot.owner is PackageClass) - (denot.owner.decls.lookup(denot.name) eq denot.symbol) || - (denot is ModuleClass) && stillValid(denot.sourceModule) // !!! DEBUG - we should check why module classes are not entered - else stillValid(denot.owner) def bringForward(): SingleDenotation = this match { - case denot: SymDenotation if stillValid(denot) => + case denot: SymDenotation if ctx.stillValid(denot) => var d: SingleDenotation = denot do { d.validFor = Period(currentPeriod.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 01e403120..845672149 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -30,6 +30,13 @@ trait SymDenotations { this: Context => result.validFor = stablePeriod result } + + def stillValid(denot: SymDenotation): Boolean = + if (denot is ValidForever) true + else if (denot.owner is PackageClass) + (denot.owner.decls.lookup(denot.name) eq denot.symbol) || + (denot is ModuleClass) && stillValid(denot.sourceModule) // !!! DEBUG - we should check why module classes are not entered + else stillValid(denot.owner) } object SymDenotations { diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index e07410a89..f723dca48 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -21,7 +21,7 @@ class TypeComparer(initctx: Context) extends DotClass { private var pendingSubTypes: mutable.Set[(Type, Type)] = null private var recCount = 0 - private var frozenConstraint = false + protected var frozenConstraint = false private var myAnyClass: ClassSymbol = null private var myNothingClass: ClassSymbol = null @@ -572,6 +572,11 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) { super.glb(tp1, tp2) } + override def addConstraint(param: PolyParam, bounds: TypeBounds): Boolean = + traceIndented(s"add constraint $param $bounds $frozenConstraint") { + super.addConstraint(param, bounds) + } + override def copyIn(ctx: Context) = new ExplainingTypeComparer(ctx) override def toString = diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 5a6307751..ddb42916e 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -337,7 +337,10 @@ object Types { /** The member of this type with the given name */ final def member(name: Name)(implicit ctx: Context): Denotation = - findMember(name, this, EmptyFlags) + try findMember(name, this, EmptyFlags) + catch { + case ex: Throwable => println(s"error occurred during: $this member $name"); throw ex // DEBUG + } /** The non-private member of this type with the given name. */ final def nonPrivateMember(name: Name)(implicit ctx: Context): Denotation = @@ -353,9 +356,11 @@ object Types { val pdenot = tp.parent.findMember(name, pre, excluded) if (name eq tp.refinedName) { val rinfo = tp.refinedInfo.substThis(tp, pre) - if (name.isTypeName) // simplified case that runs more efficiently + if (name.isTypeName) {// simplified case that runs more efficiently + val info = if (pdenot.symbol is TypeParam) rinfo else pdenot.info & rinfo pdenot.asInstanceOf[SingleDenotation].derivedSingleDenotation( - pdenot.symbol, pdenot.info & rinfo) + pdenot.symbol, info) + } else pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre) } @@ -386,7 +391,7 @@ object Types { l.findMember(name, pre, excluded) | (r.findMember(name, pre, excluded), pre) case ErrorType => ctx.newErrorSymbol(pre.classSymbol orElse defn.RootClass, name) - case NoType => + case _ => NoDenotation } /* !!! DEBUG ensuring { denot => denot.alternatives forall (_.symbol.name == name) @@ -1165,7 +1170,7 @@ object Types { private def computeDenot(implicit ctx: Context): Denotation = { val denot = lastDenotationOrSym match { - case d: SymDenotation if d is ValidForever => + case d: SymDenotation if ctx.stillValid(d) => d.current case d: Denotation => if (d.validFor.runId == ctx.period.runId) d.current @@ -1292,6 +1297,7 @@ object Types { case _ => false } + //assert(name.toString != "scala$collection$LinearSeqLike$$Repr", s"sel pre = $prefix") override def computeHash = doHash(name, prefix) } diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index ca284edf7..a803903bb 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -368,14 +368,16 @@ class Namer { typer: Typer => val site = sym.owner.thisType val inherited = { // TODO: Look only at member of supertype instead? - ((NoType: Type) /: sym.owner.info.baseClasses.tail) { (tp, cls) => - val itpe = cls.info - .nonPrivateDecl(sym.name) - .matchingDenotation(site, schema) - .asSeenFrom(site) - .info.finalResultType - tp & itpe - } + if (sym.owner.isTerm) NoType + else + ((NoType: Type) /: sym.owner.info.baseClasses.tail) { (tp, cls) => + val itpe = cls.info + .nonPrivateDecl(sym.name) + .matchingDenotation(site, schema) + .asSeenFrom(site) + .info.finalResultType + tp & itpe + } } inherited orElse typedAheadExpr(mdef.rhs).tpe.widen } diff --git a/tests/pos/inferred.scala b/tests/pos/inferred.scala index 03bd7ee6c..48889dc48 100644 --- a/tests/pos/inferred.scala +++ b/tests/pos/inferred.scala @@ -23,6 +23,12 @@ object Inferred { val ints: List[Int] = Nil prepend 1 - // val a = if (1 == 0) Nil else ints + val a = if (1 == 0) Nil else ints + + val n2 = scala.collection.immutable.Nil + + val ints2: scala.collection.immutable.List[String] = "abc" :: n2 + + val ints3 = "abc" :: n2 } \ No newline at end of file -- cgit v1.2.3