@@ -427,21 +427,28 @@ object ProtoTypes {
427
427
* - t2 is a ascription (t22: T) and t1 is at the outside of t22
428
428
* - t2 is a closure (...) => t22 and t1 is at the outside of t22
429
429
*/
430
- def hasInnerErrors (t : Tree )(using Context ): Boolean = t match
431
- case Typed (expr, tpe) => hasInnerErrors(expr)
432
- case closureDef(mdef) => hasInnerErrors(mdef.rhs)
430
+ def hasInnerErrors (t : Tree , argType : Type )(using Context ): Boolean = t match
431
+ case Typed (expr, tpe) => hasInnerErrors(expr, argType )
432
+ case closureDef(mdef) => hasInnerErrors(mdef.rhs, argType )
433
433
case _ =>
434
434
t.existsSubTree { t1 =>
435
435
if t1.typeOpt.isError
436
436
&& t.span.toSynthetic != t1.span.toSynthetic
437
437
&& t.typeOpt != t1.typeOpt then
438
438
typr.println(i " error subtree $t1 of $t with ${t1.typeOpt}, spans = ${t1.span}, ${t.span}" )
439
- true
439
+ t1.typeOpt match
440
+ case errorType : ErrorType if errorType.msg.isInstanceOf [TypeMismatchMsg ] =>
441
+ // if error is caused by an argument type mismatch,
442
+ // then return false to try to find an extension.
443
+ // see i20335.scala for test case.
444
+ val typeMismtachMsg = errorType.msg.asInstanceOf [TypeMismatchMsg ]
445
+ argType != typeMismtachMsg.expected
446
+ case _ => true
440
447
else
441
448
false
442
449
}
443
450
444
- private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean )(using Context ): Tree = {
451
+ private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean , argType : Type )(using Context ): Tree = {
445
452
var targ = state.typedArg(arg)
446
453
if (targ == null )
447
454
untpd.functionWithUnknownParamType(arg) match {
@@ -459,7 +466,7 @@ object ProtoTypes {
459
466
targ = typerFn(arg)
460
467
// TODO: investigate why flow typing is not working on `targ`
461
468
if ctx.reporter.hasUnreportedErrors then
462
- if hasInnerErrors(targ.nn) then
469
+ if hasInnerErrors(targ.nn, argType ) then
463
470
state.errorArgs += arg
464
471
else
465
472
state.typedArg = state.typedArg.updated(arg, targ.nn)
@@ -487,7 +494,7 @@ object ProtoTypes {
487
494
val protoTyperState = ctx.typerState
488
495
val oldConstraint = protoTyperState.constraint
489
496
val args1 = args.mapWithIndexConserve((arg, idx) =>
490
- cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false ))
497
+ cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false , NoType ))
491
498
val newConstraint = protoTyperState.constraint
492
499
493
500
if ! args1.exists(arg => isUndefined(arg.tpe)) then state.typedArgs = args1
@@ -534,7 +541,8 @@ object ProtoTypes {
534
541
val locked = ctx.typerState.ownedVars
535
542
val targ = cacheTypedArg(arg,
536
543
typer.typedUnadapted(_, wideFormal, locked)(using argCtx),
537
- force = true )
544
+ force = true ,
545
+ wideFormal)
538
546
val targ1 = typer.adapt(targ, wideFormal, locked)
539
547
if wideFormal eq formal then targ1
540
548
else checkNoWildcardCaptureForCBN(targ1)
0 commit comments