Skip to content

Commit 61b6c39

Browse files
committed
Take bindingTree into account before implicit search
Take bindingTree into account when deciding which type variables to instantiate before an implicit search. The additions to i3945.scala fail without this change. Also two other tweaks.
1 parent 2b3768d commit 61b6c39

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ object Inferencing {
166166
case Apply(fn, _) => boundVars(fn, acc)
167167
case TypeApply(fn, targs) =>
168168
val tvars = targs.tpes.collect {
169-
case tvar: TypeVar if !tvar.isInstantiated => tvar
169+
case tvar: TypeVar if !tvar.isInstantiated && targs.contains(tvar.bindingTree) => tvar
170170
}
171171
boundVars(fn, acc ::: tvars)
172172
case Select(pre, _) => boundVars(pre, acc)
@@ -399,8 +399,8 @@ trait Inferencing { this: Typer =>
399399
def uninstBoundVars(tree: Tree)(implicit ctx: Context): List[TypeVar] = {
400400
val buf = new mutable.ListBuffer[TypeVar]
401401
tree.foreachSubTree {
402-
case arg: TypeTree =>
403-
arg.tpe match {
402+
case TypeApply(_, args) =>
403+
args.tpes.foreach {
404404
case tv: TypeVar if !tv.isInstantiated && tree.contains(tv.bindingTree) => buf += tv
405405
case _ =>
406406
}

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,7 @@ class Typer extends Namer
19701970
if (!tree.denot.isOverloaded) {
19711971
// for overloaded trees: resolve overloading before simplifying
19721972
if (tree.isDef) interpolateUndetVars(tree, tree.symbol, pt)
1973-
else if (!tree.tpe.widen.isInstanceOf[LambdaType]) interpolateUndetVars(tree, NoSymbol, pt)
1973+
else if (!tree.tpe.widen.isInstanceOf[MethodOrPoly]) interpolateUndetVars(tree, NoSymbol, pt)
19741974
tree.overwriteType(tree.tpe.simplified)
19751975
}
19761976
adaptInterpolated(tree, pt)
@@ -2106,8 +2106,10 @@ class Typer extends Namer
21062106
def adaptNoArgsImplicitMethod(wtp: MethodType): Tree = {
21072107
assert(wtp.isImplicitMethod)
21082108
val tvarsToInstantiate = tvarsInParams(tree)
2109+
println(i"adaptNoArgsImpl $tvarsToInstantiate%, %, ${ctx.typerState.constraint}")
21092110
wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
21102111
val constr = ctx.typerState.constraint
2112+
println(i"new constr = $constr")
21112113

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

tests/pos/i3945.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
object Test {
22
def int[A](k: String => A)(s: String)(x: Int): A = ???
33

4-
// composing directly: ok in scalac, error in dotc
4+
// composing directly: ok in scalac, now also in dotc
55
val c: (String => String) => (String) => (Int) => (Int) => String = (int[Int => String](_)).compose(int[String](_))
66

77
// unwrapping composition: ok in scalac, ok in dotc
88
val q: (String => Int => String) => (String) => (Int) => (Int => String) = int[Int => String]
99
val p: (String => String) => (String) => (Int) => String = int
1010
val c2: (String => String) => (String) => (Int) => (Int) => String = q.compose(p)
11+
12+
class B
13+
class C extends B
14+
implicit def iC: C => Unit = ???
15+
16+
// making sure A is not instantiated before implicit search
17+
def f[A](k: String => A)(s: String)(x: Int)(implicit y: A => Unit): A = ???
18+
val r: (String => C) => (String) => (Int) => B = f
1119
}

0 commit comments

Comments
 (0)