Skip to content

Commit c8eb14f

Browse files
oderskysmarter
authored andcommitted
Replace singleton bounds before doing implicit search
Before searching for implicit arguments, if a the constraint contains a type parameter ``` P >: A <: B ``` where `P` occurs in the searched-for type and `A =:= B`, change the constraint to ``` P := B ``` instead. This improves the implicit search by making the searched-for type have fewer uninstantiated type variables.
1 parent bd54027 commit c8eb14f

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,31 @@ object Inferencing {
138138
}
139139
}
140140

141+
/** For all type parameters occurring in `tp`:
142+
* If the bounds of `tp` in the current constraint are equal wrt =:=,
143+
* instantiate the type parameter to the lower bound's approximation
144+
* (approximation because of possible F-bounds).
145+
*/
146+
def replaceSingletons(tp: Type)(implicit ctx: Context): Unit = {
147+
val tr = new TypeTraverser {
148+
def traverse(tp: Type): Unit = {
149+
tp match {
150+
case param: TypeParamRef =>
151+
val constraint = ctx.typerState.constraint
152+
if (constraint.contains(param) &&
153+
(ctx.typerComparer.fullUpperBound(param) frozen_<:< ctx.typecomparer.fullLowerBound(param))) {
154+
typr.println(i"replace singleton $param := ${ctx.typeComparer.fullLowerBound(param)}")
155+
ctx.typerState.constraint = constraint.replace(param,
156+
ctx.typeComparer.approximation(param, fromBelow = true))
157+
}
158+
case _ =>
159+
}
160+
traverseChildren(tp)
161+
}
162+
}
163+
tr.traverse(tp)
164+
}
165+
141166
/** If `tree` has a type lambda type, infer its type parameters by comparing with expected type `pt` */
142167
def inferTypeParams(tree: Tree, pt: Type)(implicit ctx: Context): Tree = tree.tpe match {
143168
case tl: TypeLambda =>

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2607,7 +2607,11 @@ class Typer extends Namer
26072607
def adaptNoArgsImplicitMethod(wtp: MethodType): Tree = {
26082608
assert(wtp.isImplicitMethod)
26092609
val tvarsToInstantiate = tvarsInParams(tree, locked).distinct
2610-
wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
2610+
def instantiate(tp: Type): Unit = {
2611+
instantiateSelected(tp, tvarsToInstantiate)
2612+
replaceSingletons(tp)
2613+
}
2614+
wtp.paramInfos.foreach(instantiate)
26112615
val constr = ctx.typerState.constraint
26122616

26132617
def dummyArg(tp: Type) = untpd.Ident(nme.???).withTypeUnchecked(tp)

0 commit comments

Comments
 (0)