Skip to content

Commit 4651177

Browse files
committed
Fix #7249: Search for hidden givens only at whole type
Don't try to find a hidden implicit for a part of type type that was searched for, unless that part is fully defined. The reason is that any type variables in a subtype might be associated with constraints that are lost at the point of issuing a the hidden givens addendum. The commit also contains a tweak to "isFullyDefined" which makes an uninstantiated type variable that is not bound in the current constraint count as "not fully defined", where previously it was "fully defined".
1 parent 19b4216 commit 4651177

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

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

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import Constants._
2525
import ProtoTypes._
2626
import ErrorReporting._
2727
import reporting.diagnostic.Message
28-
import Inferencing.fullyDefinedType
28+
import Inferencing.{fullyDefinedType, isFullyDefined}
2929
import Trees._
3030
import transform.SymUtils._
3131
import transform.TypeUtils._
@@ -392,7 +392,8 @@ object Implicits {
392392
def whyNoConversion(implicit ctx: Context): String = ""
393393
}
394394

395-
class NoMatchingImplicits(val expectedType: Type, val argument: Tree, constraint: Constraint = OrderingConstraint.empty) extends SearchFailureType {
395+
class NoMatchingImplicits(val expectedType: Type, val argument: Tree, constraint: Constraint = OrderingConstraint.empty)
396+
extends SearchFailureType {
396397

397398
/** Replace all type parameters in constraint by their bounds, to make it clearer
398399
* what was expected
@@ -1215,15 +1216,21 @@ trait Implicits { self: Typer =>
12151216
if (ctx == NoContext) ctx
12161217
else ctx.freshOver(FindHiddenImplicitsCtx(ctx.outer)).addMode(Mode.FindHiddenImplicits)
12171218

1218-
inferImplicit(fail.expectedType, fail.argument, arg.span)(
1219-
FindHiddenImplicitsCtx(ctx)) match {
1220-
case s: SearchSuccess => hiddenImplicitNote(s)
1221-
case f: SearchFailure =>
1222-
f.reason match {
1223-
case ambi: AmbiguousImplicits => hiddenImplicitNote(ambi.alt1)
1224-
case r => ""
1225-
}
1226-
}
1219+
if (fail.expectedType eq pt) || isFullyDefined(fail.expectedType, ForceDegree.none) then
1220+
inferImplicit(fail.expectedType, fail.argument, arg.span)(
1221+
FindHiddenImplicitsCtx(ctx)) match {
1222+
case s: SearchSuccess => hiddenImplicitNote(s)
1223+
case f: SearchFailure =>
1224+
f.reason match {
1225+
case ambi: AmbiguousImplicits => hiddenImplicitNote(ambi.alt1)
1226+
case r => ""
1227+
}
1228+
}
1229+
else
1230+
// It's unsafe to search for parts of the expected type if they are not fully defined,
1231+
// since these come with nested contexts that are lost at this point. See #7249 for an
1232+
// example where searching for a nested type causes an infinite loop.
1233+
""
12271234
}
12281235
msg(userDefined.getOrElse(
12291236
em"no implicit argument of type $pt was found${location("for")}"))() ++

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ object Inferencing {
104104
def apply(x: Boolean, tp: Type): Boolean = tp.dealias match {
105105
case _: WildcardType | _: ProtoType =>
106106
false
107-
case tvar: TypeVar
108-
if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
109-
force.appliesTo(tvar) && {
107+
case tvar: TypeVar if !tvar.isInstantiated =>
108+
force.appliesTo(tvar)
109+
&& ctx.typerState.constraint.contains(tvar)
110+
&& {
110111
val direction = instDirection(tvar.origin)
111112
def avoidBottom =
112113
!force.allowBottom &&

tests/neg/i7249.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Predef.{$conforms => _, _}
2+
3+
trait F[H, T]
4+
5+
6+
object Test extends App {
7+
given f[H, T](given h: H, t: T): F[H, T] = ???
8+
summon[F[Int, Unit]] // error
9+
}

0 commit comments

Comments
 (0)