diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Phases.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/FrontEnd.scala | 1 | ||||
-rw-r--r-- | test/dotc/tests.scala | 3 | ||||
-rw-r--r-- | tests/neg/i0583-skolemize.scala | 27 |
6 files changed, 48 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 0ec3320bb..b086308a2 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -285,6 +285,9 @@ object Phases { */ def relaxedTyping: Boolean = false + /** Overridden by FrontEnd */ + def isTyper = false + def exists: Boolean = true private var myPeriod: Period = Periods.InvalidPeriod diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 1f80a8a10..ea815f6c0 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -274,6 +274,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case _ => thirdTry(tp1, tp2) } + case tp1: SkolemType => + tp2 match { + case tp2: SkolemType if !ctx.phase.isTyper && tp1.info <:< tp2.info => true + case _ => thirdTry(tp1, tp2) + } case tp1: TypeVar => isSubType(tp1.underlying, tp2) case tp1: WildcardType => diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index fb641f247..7c371a96e 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -13,19 +13,19 @@ import ast.tpd._ trait TypeOps { this: Context => // TODO: Make standalone object. final def asSeenFrom(tp: Type, pre: Type, cls: Symbol): Type = { - val m = if (pre.isStable || ctx.isAfterTyper) null else new AsSeenFromMap(pre, cls) - asSeenFrom(tp, pre, cls, null) + val m = if (pre.isStable || !ctx.phase.isTyper) null else new AsSeenFromMap(pre, cls) + var res = asSeenFrom(tp, pre, cls, m) + if (m != null && m.unstable) asSeenFrom(tp, SkolemType(pre), cls) else res } - + final def asSeenFrom(tp: Type, pre: Type, cls: Symbol, theMap: AsSeenFromMap): Type = { def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ ctx.conditionalTraceIndented(TypeOps.track, s"toPrefix($pre, $cls, $thiscls)") /*<|<*/ { if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass)) tp else if (thiscls.derivesFrom(cls) && pre.baseTypeRef(thiscls).exists) { - if (!pre.isStable && theMap != null && theMap.currentVariance <= 0) { + if (theMap != null && theMap.currentVariance <= 0 && !pre.isStable) theMap.unstable = true - } pre match { case SuperType(thispre, _) => thispre case _ => pre @@ -43,10 +43,13 @@ trait TypeOps { this: Context => // TODO: Make standalone object. val sym = tp.symbol if (sym.isStatic) tp else { + val prevStable = theMap == null || !theMap.unstable val pre1 = asSeenFrom(tp.prefix, pre, cls, theMap) - if (theMap != null && theMap.unstable) { + if (theMap != null && theMap.unstable && prevStable) { pre1.member(tp.name).info match { - case TypeAlias(alias) => return alias + case TypeAlias(alias) => + theMap.unstable = false + return alias case _ => } } @@ -61,7 +64,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. asSeenFrom(tp.parent, pre, cls, theMap), tp.refinedName, asSeenFrom(tp.refinedInfo, pre, cls, theMap)) - case tp: TypeAlias => + case tp: TypeAlias if theMap == null => // if theMap exists, need to do the variance calculation tp.derivedTypeAlias(asSeenFrom(tp.alias, pre, cls, theMap)) case _ => (if (theMap != null) theMap else new AsSeenFromMap(pre, cls)) diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala index 056a57215..3dda108b0 100644 --- a/src/dotty/tools/dotc/typer/FrontEnd.scala +++ b/src/dotty/tools/dotc/typer/FrontEnd.scala @@ -13,6 +13,7 @@ import scala.util.control.NonFatal class FrontEnd extends Phase { override def phaseName = "frontend" + override def isTyper = true def monitor(doing: String)(body: => Unit)(implicit ctx: Context) = try body diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index b017211a9..de7f48a68 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -133,15 +133,14 @@ class tests extends CompilerTest { @Test def neg_i0091_infpaths = compileFile(negDir, "i0091-infpaths", xerrors = 3) @Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 4) @Test def neg_i0281 = compileFile(negDir, "i0281-null-primitive-conforms", xerrors = 3) + @Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2) @Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4) @Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2) @Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8) @Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 5) - @Test def run_all = runFiles(runDir) - @Test def dotty = compileDir(dottyDir, "tools", "-deep" :: allowDeepSubtypes ++ twice) // note the -deep argument diff --git a/tests/neg/i0583-skolemize.scala b/tests/neg/i0583-skolemize.scala new file mode 100644 index 000000000..e0bb99e5d --- /dev/null +++ b/tests/neg/i0583-skolemize.scala @@ -0,0 +1,27 @@ +import scala.collection.mutable.ListBuffer + +object Test1 { + + class Box[T](x: T) + def box[T](x: T) = new Box[T](x) + + class C[T] { def x: T = ???; def x_=(y: T): Unit = ??? } + + val c: C[Int] = ??? + val d: C[Float] = ??? + + val xs: List[C[_]] = List(c, d) + + xs(0).x = xs(1).x + +} +object Test { + def main(args: Array[String]): Unit = { + val f: ListBuffer[Int] = ListBuffer(1,2) + val g: ListBuffer[Double] = ListBuffer(3.0,4.0) + val lb: ListBuffer[ListBuffer[_]] = ListBuffer(f, g) + lb(0)(0) = lb(1)(0) + val x: Int = f(0) + } +} + |