Skip to content

Commit bea9aa2

Browse files
committed
Move Inferencing out of the Typer cake
1 parent 8532c98 commit bea9aa2

File tree

4 files changed

+46
-43
lines changed

4 files changed

+46
-43
lines changed

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Names._
2121
import StdNames._
2222
import ProtoTypes._
2323
import EtaExpansion._
24+
import Inferencing._
2425
import collection.mutable
2526
import config.Printers._
2627
import TypeApplications._

src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import config.Printers._
2020
import annotation.tailrec
2121
import collection.mutable
2222

23-
trait Inferencing { this: Checking =>
23+
object Inferencing {
2424

2525
import tpd._
2626

@@ -197,47 +197,6 @@ trait Inferencing { this: Checking =>
197197
case _ => NoType
198198
}
199199

200-
/** Ensure that the first type in a list of parent types Ps points to a non-trait class.
201-
* If that's not already the case, add one. The added class type CT is determined as follows.
202-
* First, let C be the unique class such that
203-
* - there is a parent P_i such that P_i derives from C, and
204-
* - for every class D: If some parent P_j, j <= i derives from D, then C derives from D.
205-
* Then, let CT be the smallest type which
206-
* - has C as its class symbol, and
207-
* - for all parents P_i: If P_i derives from C then P_i <:< CT.
208-
*/
209-
def ensureFirstIsClass(parents: List[Type])(implicit ctx: Context): List[Type] = {
210-
def realClassParent(cls: Symbol): ClassSymbol =
211-
if (!cls.isClass) defn.ObjectClass
212-
else if (!(cls is Trait)) cls.asClass
213-
else cls.asClass.classParents match {
214-
case parentRef :: _ => realClassParent(parentRef.symbol)
215-
case nil => defn.ObjectClass
216-
}
217-
def improve(candidate: ClassSymbol, parent: Type): ClassSymbol = {
218-
val pcls = realClassParent(parent.classSymbol)
219-
if (pcls derivesFrom candidate) pcls else candidate
220-
}
221-
parents match {
222-
case p :: _ if p.classSymbol.isRealClass => parents
223-
case _ =>
224-
val pcls = (defn.ObjectClass /: parents)(improve)
225-
typr.println(i"ensure first is class $parents%, % --> ${parents map (_ baseTypeWithArgs pcls)}%, %")
226-
val ptype = ctx.typeComparer.glb(
227-
defn.ObjectType :: (parents map (_ baseTypeWithArgs pcls)))
228-
ptype :: parents
229-
}
230-
}
231-
232-
/** Ensure that first parent tree refers to a real class. */
233-
def ensureFirstIsClass(parents: List[Tree], pos: Position)(implicit ctx: Context): List[Tree] = parents match {
234-
case p :: ps if p.tpe.classSymbol.isRealClass => parents
235-
case _ =>
236-
// add synthetic class type
237-
val first :: _ = ensureFirstIsClass(parents.tpes)
238-
TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents
239-
}
240-
241200
/** Interpolate those undetermined type variables in the widened type of this tree
242201
* which are introduced by type application contained in the tree.
243202
* If such a variable appears covariantly in type `tp` or does not appear at all,

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import ErrorReporting._
1616
import tpd.ListOfTreeDecorator
1717
import config.Printers._
1818
import Annotations._
19+
import Inferencing._
1920
import transform.ValueClasses._
2021
import language.implicitConversions
2122

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Flags._
2121
import Decorators._
2222
import ErrorReporting._
2323
import Checking._
24+
import Inferencing._
2425
import EtaExpansion.etaExpand
2526
import dotty.tools.dotc.transform.Erasure.Boxing
2627
import util.Positions._
@@ -55,7 +56,7 @@ object Typer {
5556
assert(tree.pos.exists, s"position not set for $tree # ${tree.uniqueId}")
5657
}
5758

58-
class Typer extends Namer with TypeAssigner with Applications with Implicits with Inferencing with Checking {
59+
class Typer extends Namer with TypeAssigner with Applications with Implicits with Checking {
5960

6061
import Typer._
6162
import tpd.{cpy => _, _}
@@ -977,6 +978,47 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
977978
// 4. Polymorphic type defs override nothing.
978979
}
979980

981+
/** Ensure that the first type in a list of parent types Ps points to a non-trait class.
982+
* If that's not already the case, add one. The added class type CT is determined as follows.
983+
* First, let C be the unique class such that
984+
* - there is a parent P_i such that P_i derives from C, and
985+
* - for every class D: If some parent P_j, j <= i derives from D, then C derives from D.
986+
* Then, let CT be the smallest type which
987+
* - has C as its class symbol, and
988+
* - for all parents P_i: If P_i derives from C then P_i <:< CT.
989+
*/
990+
def ensureFirstIsClass(parents: List[Type])(implicit ctx: Context): List[Type] = {
991+
def realClassParent(cls: Symbol): ClassSymbol =
992+
if (!cls.isClass) defn.ObjectClass
993+
else if (!(cls is Trait)) cls.asClass
994+
else cls.asClass.classParents match {
995+
case parentRef :: _ => realClassParent(parentRef.symbol)
996+
case nil => defn.ObjectClass
997+
}
998+
def improve(candidate: ClassSymbol, parent: Type): ClassSymbol = {
999+
val pcls = realClassParent(parent.classSymbol)
1000+
if (pcls derivesFrom candidate) pcls else candidate
1001+
}
1002+
parents match {
1003+
case p :: _ if p.classSymbol.isRealClass => parents
1004+
case _ =>
1005+
val pcls = (defn.ObjectClass /: parents)(improve)
1006+
typr.println(i"ensure first is class $parents%, % --> ${parents map (_ baseTypeWithArgs pcls)}%, %")
1007+
val ptype = ctx.typeComparer.glb(
1008+
defn.ObjectType :: (parents map (_ baseTypeWithArgs pcls)))
1009+
ptype :: parents
1010+
}
1011+
}
1012+
1013+
/** Ensure that first parent tree refers to a real class. */
1014+
def ensureFirstIsClass(parents: List[Tree], pos: Position)(implicit ctx: Context): List[Tree] = parents match {
1015+
case p :: ps if p.tpe.classSymbol.isRealClass => parents
1016+
case _ =>
1017+
// add synthetic class type
1018+
val first :: _ = ensureFirstIsClass(parents.tpes)
1019+
TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents
1020+
}
1021+
9801022
/** If this is a real class, make sure its first parent is a
9811023
* constructor call. Cannot simply use a type. Overridden in ReTyper.
9821024
*/

0 commit comments

Comments
 (0)