@@ -3626,7 +3626,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
36263626
36273627 private def adapt1 (tree : Tree , pt : Type , locked : TypeVars )(using Context ): Tree = {
36283628 assert(pt.exists && ! pt.isInstanceOf [ExprType ] || ctx.reporter.errorsReported, i " tree: $tree, pt: $pt" )
3629- def methodStr = err.refStr(methPart(tree).tpe)
36303629
36313630 def readapt (tree : Tree )(using Context ) = adapt(tree, pt, locked)
36323631 def readaptSimplified (tree : Tree )(using Context ) = readapt(simplify(tree, pt, locked))
@@ -3803,49 +3802,37 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38033802 arg :: inferArgsAfter(arg)
38043803 end implicitArgs
38053804
3806- val args = implicitArgs(wtp.paramInfos, 0 , pt)
3807-
3808- def propagatedFailure (args : List [Tree ]): Type = args match {
3809- case arg :: args1 =>
3810- arg.tpe match {
3811- case ambi : AmbiguousImplicits =>
3812- propagatedFailure(args1) match {
3813- case NoType | (_ : AmbiguousImplicits ) => ambi
3814- case failed => failed
3815- }
3816- case failed : SearchFailureType => failed
3817- case _ => propagatedFailure(args1)
3818- }
3819- case Nil => NoType
3820- }
3821-
3822- val propFail = propagatedFailure(args)
3823-
3824- def issueErrors (): Tree = {
3825- def paramSymWithMethodTree (paramName : TermName ) =
3826- if tree.symbol.exists then
3827- tree.symbol.paramSymss.flatten
3828- .map(sym => sym.name -> sym)
3829- .toMap
3830- .get(paramName)
3831- .map((_, tree))
3832- else
3833- None
3805+ /** Reports errors for arguments of `appTree` that have a
3806+ * `SearchFailureType`.
3807+ */
3808+ def issueErrors (fun : Tree , args : List [Tree ]): Tree =
3809+ def firstFailure = args.tpes.find(_.isInstanceOf [SearchFailureType ]).getOrElse(NoType )
3810+ val errorType =
3811+ firstFailure match
3812+ case tp : AmbiguousImplicits =>
3813+ AmbiguousImplicits (tp.alt1, tp.alt2, tp.expectedType, tp.argument, nested = true )
3814+ case tp =>
3815+ tp
3816+ val res = untpd.Apply (fun, args).withType(errorType)
38343817
38353818 wtp.paramNames.lazyZip(wtp.paramInfos).lazyZip(args).foreach { (paramName, formal, arg) =>
3836- arg.tpe match {
3819+ arg.tpe match
38373820 case failure : SearchFailureType =>
3821+ val methodStr = err.refStr(methPart(fun).tpe)
3822+ val paramStr = implicitParamString(paramName, methodStr, fun)
3823+ val paramSym = fun.symbol.paramSymss.flatten.find(_.name == paramName)
3824+ val paramSymWithMethodCallTree = paramSym.map((_, res))
38383825 report.error(
3839- missingArgMsg(arg, formal, implicitParamString(paramName, methodStr, tree), paramSymWithMethodTree(paramName) ),
3840- tree.srcPos.endPos
3841- )
3826+ missingArgMsg(arg, formal, paramStr, paramSymWithMethodCallTree ),
3827+ tree.srcPos.endPos
3828+ )
38423829 case _ =>
3843- }
38443830 }
3845- untpd.Apply (tree, args).withType(propFail)
3846- }
38473831
3848- if (propFail.exists) {
3832+ res
3833+
3834+ val args = implicitArgs(wtp.paramInfos, 0 , pt)
3835+ if (args.tpes.exists(_.isInstanceOf [SearchFailureType ])) {
38493836 // If there are several arguments, some arguments might already
38503837 // have influenced the context, binding variables, but later ones
38513838 // might fail. In that case the constraint and instantiated variables
@@ -3854,15 +3841,28 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38543841
38553842 // If method has default params, fall back to regular application
38563843 // where all inferred implicits are passed as named args.
3857- if hasDefaultParams && ! propFail.isInstanceOf [AmbiguousImplicits ] then
3858- val namedArgs = wtp.paramNames.lazyZip(args).flatMap { (pname, arg) =>
3859- if (arg.tpe.isError) Nil else untpd.NamedArg (pname, untpd.TypedSplice (arg)) :: Nil
3860- }
3844+ if hasDefaultParams then
3845+ // Only keep the arguments that don't have an error type, or that
3846+ // have an `AmbiguousImplicits` error type. The later ensures that a
3847+ // default argument can't override an ambiguous implicit. See tests
3848+ // `given-ambiguous-default*` and `19414*`.
3849+ val namedArgs =
3850+ wtp.paramNames.lazyZip(args)
3851+ .filter((_, arg) => ! arg.tpe.isError || arg.tpe.isInstanceOf [AmbiguousImplicits ])
3852+ .map((pname, arg) => untpd.NamedArg (pname, untpd.TypedSplice (arg)))
3853+
38613854 val app = cpy.Apply (tree)(untpd.TypedSplice (tree), namedArgs)
38623855 if (wtp.isContextualMethod) app.setApplyKind(ApplyKind .Using )
38633856 typr.println(i " try with default implicit args $app" )
3864- typed(app, pt, locked)
3865- else issueErrors()
3857+ val retyped = typed(app, pt, locked)
3858+
3859+ // If the retyped tree still has an error type and is an `Apply`
3860+ // node, we can report the errors for each argument nicely.
3861+ // Otherwise, we don't report anything here.
3862+ retyped match
3863+ case Apply (tree, args) if retyped.tpe.isError => issueErrors(tree, args)
3864+ case _ => retyped
3865+ else issueErrors(tree, args)
38663866 }
38673867 else tree match {
38683868 case tree : Block =>
0 commit comments