diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 0b6688c6f5fe..d6b23e886529 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -396,7 +396,7 @@ object ProtoTypes { args: List[untpd.Tree] = this.args, resultType: Type = this.resultType, typer: Typer = this.typer, - constrainResultDeep: Boolean = this.constrainResultDeep): FunProto = + constrainResultDeep: Boolean = this.constrainResultDeep)(using Context): FunProto = if (args eq this.args) && (resultType eq this.resultType) && (typer eq this.typer) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 10a061ab8fc4..7181976fd389 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -54,6 +54,7 @@ import transform.CheckUnused.OriginalName import scala.annotation.{unchecked as _, *} import dotty.tools.dotc.util.chaining.* import dotty.tools.dotc.ast.untpd.Mod +import dotty.tools.dotc.reporting.Reporter.NoReporter object Typer { @@ -4357,6 +4358,27 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer else formals1 implicitArgs(formals2, argIndex + 1, pt) + + def doesntContainsWildcards = { + val newCtx = ctx.fresh.setNewScope.setReporter(new reporting.ThrowingReporter(NoReporter)) + val pt1 = pt.deepenProtoTrans(using newCtx) + try { + !pt1.containsWildcardTypes(using newCtx) + } catch { + case _: UnhandledError => false + } + } + val pt1 = pt.deepenProtoTrans + if (pt1 `ne` pt) + && (pt1 ne sharpenedPt) + && formal.typeSymbol != defn.ClassTagClass + && !isFullyDefined(formal, ForceDegree.none) + && !formal.existsPart(ty => { + val dty = ty.dealias + (dty ne ty) && ty.isInstanceOf[TypeVar] && dty.isInstanceOf[TypeVar] + }, StopAt.Static, forceLazy = false) + && doesntContainsWildcards then + constrainResult(tree.symbol, wtp, pt1) val arg = inferImplicitArg(formal, tree.span.endPos) def canProfitFromMoreConstraints = @@ -4367,7 +4389,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer arg.tpe match case failed: SearchFailureType if canProfitFromMoreConstraints => - val pt1 = pt.deepenProtoTrans if (pt1 `ne` pt) && (pt1 ne sharpenedPt) && constrainResult(tree.symbol, wtp, pt1) then return implicitArgs(formals, argIndex, pt1) case _ =>