diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/EtaExpansion.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 43 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 44 | ||||
-rw-r--r-- | test/dotc/tests.scala | 1 | ||||
-rw-r--r-- | tests/pos/pickleinf.scala | 9 |
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) + } +} |