Skip to content

Commit 79d2034

Browse files
authored
Merge pull request #7300 from dotty-staging/fix-#7249
Fix #7249: Search for hidden givens only at whole type
2 parents 71234eb + e7d1cf0 commit 79d2034

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-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/i7248.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test extends App {
2+
given f[H](given h: H): H = h
3+
summon[Int] // error
4+
}

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)