aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala3
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala5
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala19
-rw-r--r--src/dotty/tools/dotc/typer/FrontEnd.scala1
-rw-r--r--test/dotc/tests.scala3
-rw-r--r--tests/neg/i0583-skolemize.scala27
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)
+ }
+}
+