aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala1
-rw-r--r--src/dotty/tools/dotc/typer/EtaExpansion.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala43
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala1
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala44
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/pos/pickleinf.scala9
7 files changed, 59 insertions, 44 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index c7d8acb37..87ad0831c 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -21,6 +21,7 @@ import Names._
import StdNames._
import ProtoTypes._
import EtaExpansion._
+import Inferencing._
import collection.mutable
import config.Printers._
import TypeApplications._
diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 4fa3d78eb..89415024e 100644
--- a/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -13,6 +13,7 @@ import Decorators._
import Names._
import StdNames._
import Trees._
+import Inferencing._
import util.Positions._
import collection.mutable
@@ -24,7 +25,8 @@ object EtaExpansion {
if (isPureExpr(expr)) expr
else {
val name = ctx.freshName(prefix).toTermName
- val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, expr.tpe.widen, coord = positionCoord(expr.pos))
+ val liftedType = fullyDefinedType(expr.tpe.widen, "lifted expression", expr.pos)
+ val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, liftedType, coord = positionCoord(expr.pos))
defs += ValDef(sym, expr)
ref(sym.valRef)
}
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 0a76f45c5..81a302717 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -20,7 +20,7 @@ import config.Printers._
import annotation.tailrec
import collection.mutable
-trait Inferencing { this: Checking =>
+object Inferencing {
import tpd._
@@ -197,47 +197,6 @@ trait Inferencing { this: Checking =>
case _ => NoType
}
- /** Ensure that the first type in a list of parent types Ps points to a non-trait class.
- * If that's not already the case, add one. The added class type CT is determined as follows.
- * First, let C be the unique class such that
- * - there is a parent P_i such that P_i derives from C, and
- * - for every class D: If some parent P_j, j <= i derives from D, then C derives from D.
- * Then, let CT be the smallest type which
- * - has C as its class symbol, and
- * - for all parents P_i: If P_i derives from C then P_i <:< CT.
- */
- def ensureFirstIsClass(parents: List[Type])(implicit ctx: Context): List[Type] = {
- def realClassParent(cls: Symbol): ClassSymbol =
- if (!cls.isClass) defn.ObjectClass
- else if (!(cls is Trait)) cls.asClass
- else cls.asClass.classParents match {
- case parentRef :: _ => realClassParent(parentRef.symbol)
- case nil => defn.ObjectClass
- }
- def improve(candidate: ClassSymbol, parent: Type): ClassSymbol = {
- val pcls = realClassParent(parent.classSymbol)
- if (pcls derivesFrom candidate) pcls else candidate
- }
- parents match {
- case p :: _ if p.classSymbol.isRealClass => parents
- case _ =>
- val pcls = (defn.ObjectClass /: parents)(improve)
- typr.println(i"ensure first is class $parents%, % --> ${parents map (_ baseTypeWithArgs pcls)}%, %")
- val ptype = ctx.typeComparer.glb(
- defn.ObjectType :: (parents map (_ baseTypeWithArgs pcls)))
- ptype :: parents
- }
- }
-
- /** Ensure that first parent tree refers to a real class. */
- def ensureFirstIsClass(parents: List[Tree], pos: Position)(implicit ctx: Context): List[Tree] = parents match {
- case p :: ps if p.tpe.classSymbol.isRealClass => parents
- case _ =>
- // add synthetic class type
- val first :: _ = ensureFirstIsClass(parents.tpes)
- TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents
- }
-
/** Interpolate those undetermined type variables in the widened type of this tree
* which are introduced by type application contained in the tree.
* If such a variable appears covariantly in type `tp` or does not appear at all,
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index c1341a9ae..d97bbff91 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -16,6 +16,7 @@ import ErrorReporting._
import tpd.ListOfTreeDecorator
import config.Printers._
import Annotations._
+import Inferencing._
import transform.ValueClasses._
import language.implicitConversions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 3bb7a6505..1bd4152e9 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -21,6 +21,7 @@ import Flags._
import Decorators._
import ErrorReporting._
import Checking._
+import Inferencing._
import EtaExpansion.etaExpand
import dotty.tools.dotc.transform.Erasure.Boxing
import util.Positions._
@@ -55,7 +56,7 @@ object Typer {
assert(tree.pos.exists, s"position not set for $tree # ${tree.uniqueId}")
}
-class Typer extends Namer with TypeAssigner with Applications with Implicits with Inferencing with Checking {
+class Typer extends Namer with TypeAssigner with Applications with Implicits with Checking {
import Typer._
import tpd.{cpy => _, _}
@@ -977,6 +978,47 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
// 4. Polymorphic type defs override nothing.
}
+ /** Ensure that the first type in a list of parent types Ps points to a non-trait class.
+ * If that's not already the case, add one. The added class type CT is determined as follows.
+ * First, let C be the unique class such that
+ * - there is a parent P_i such that P_i derives from C, and
+ * - for every class D: If some parent P_j, j <= i derives from D, then C derives from D.
+ * Then, let CT be the smallest type which
+ * - has C as its class symbol, and
+ * - for all parents P_i: If P_i derives from C then P_i <:< CT.
+ */
+ def ensureFirstIsClass(parents: List[Type])(implicit ctx: Context): List[Type] = {
+ def realClassParent(cls: Symbol): ClassSymbol =
+ if (!cls.isClass) defn.ObjectClass
+ else if (!(cls is Trait)) cls.asClass
+ else cls.asClass.classParents match {
+ case parentRef :: _ => realClassParent(parentRef.symbol)
+ case nil => defn.ObjectClass
+ }
+ def improve(candidate: ClassSymbol, parent: Type): ClassSymbol = {
+ val pcls = realClassParent(parent.classSymbol)
+ if (pcls derivesFrom candidate) pcls else candidate
+ }
+ parents match {
+ case p :: _ if p.classSymbol.isRealClass => parents
+ case _ =>
+ val pcls = (defn.ObjectClass /: parents)(improve)
+ typr.println(i"ensure first is class $parents%, % --> ${parents map (_ baseTypeWithArgs pcls)}%, %")
+ val ptype = ctx.typeComparer.glb(
+ defn.ObjectType :: (parents map (_ baseTypeWithArgs pcls)))
+ ptype :: parents
+ }
+ }
+
+ /** Ensure that first parent tree refers to a real class. */
+ def ensureFirstIsClass(parents: List[Tree], pos: Position)(implicit ctx: Context): List[Tree] = parents match {
+ case p :: ps if p.tpe.classSymbol.isRealClass => parents
+ case _ =>
+ // add synthetic class type
+ val first :: _ = ensureFirstIsClass(parents.tpes)
+ TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents
+ }
+
/** If this is a real class, make sure its first parent is a
* constructor call. Cannot simply use a type. Overridden in ReTyper.
*/
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 2b5b86be1..cf213033d 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -53,6 +53,7 @@ class tests extends CompilerTest {
// This directory doesn't exist anymore
// @Test def pickle_pickling = compileDir(coreDir, "pickling", testPickling)
@Test def pickle_ast = compileDir(dotcDir, "ast", testPickling)
+ @Test def pickle_inf = compileFile(posDir, "pickleinf", testPickling)
//@Test def pickle_core = compileDir(dotcDir, "core", testPickling, xerrors = 2) // two spurious comparison errors in Types and TypeOps
diff --git a/tests/pos/pickleinf.scala b/tests/pos/pickleinf.scala
new file mode 100644
index 000000000..9132f1a17
--- /dev/null
+++ b/tests/pos/pickleinf.scala
@@ -0,0 +1,9 @@
+class Bar[N] {
+ def bar(name: N, dummy: Int = 42): N = name
+}
+
+object Test {
+ def test(): Unit = {
+ (new Bar).bar(10)
+ }
+}