@@ -391,21 +391,28 @@ object ProtoTypes {
391
391
* - t2 is a ascription (t22: T) and t1 is at the outside of t22
392
392
* - t2 is a closure (...) => t22 and t1 is at the outside of t22
393
393
*/
394
- def hasInnerErrors (t : Tree )(using Context ): Boolean = t match
395
- case Typed (expr, tpe) => hasInnerErrors(expr)
396
- case closureDef(mdef) => hasInnerErrors(mdef.rhs)
394
+ def hasInnerErrors (t : Tree , argType : Type )(using Context ): Boolean = t match
395
+ case Typed (expr, tpe) => hasInnerErrors(expr, argType )
396
+ case closureDef(mdef) => hasInnerErrors(mdef.rhs, argType )
397
397
case _ =>
398
398
t.existsSubTree { t1 =>
399
399
if t1.typeOpt.isError
400
400
&& t.span.toSynthetic != t1.span.toSynthetic
401
401
&& t.typeOpt != t1.typeOpt then
402
402
typr.println(i " error subtree $t1 of $t with ${t1.typeOpt}, spans = ${t1.span}, ${t.span}" )
403
- true
403
+ t1.typeOpt match
404
+ case errorType : ErrorType if errorType.msg.isInstanceOf [TypeMismatchMsg ] =>
405
+ // if error is caused by an argument type mismatch,
406
+ // then return false to try to find an extension.
407
+ // see i20335.scala for test case.
408
+ val typeMismtachMsg = errorType.msg.asInstanceOf [TypeMismatchMsg ]
409
+ argType != typeMismtachMsg.expected
410
+ case _ => true
404
411
else
405
412
false
406
413
}
407
414
408
- private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean )(using Context ): Tree = {
415
+ private def cacheTypedArg (arg : untpd.Tree , typerFn : untpd.Tree => Tree , force : Boolean , argType : Type )(using Context ): Tree = {
409
416
var targ = state.typedArg(arg)
410
417
if (targ == null )
411
418
untpd.functionWithUnknownParamType(arg) match {
@@ -423,7 +430,7 @@ object ProtoTypes {
423
430
targ = typerFn(arg)
424
431
// TODO: investigate why flow typing is not working on `targ`
425
432
if ctx.reporter.hasUnreportedErrors then
426
- if hasInnerErrors(targ.nn) then
433
+ if hasInnerErrors(targ.nn, argType ) then
427
434
state.errorArgs += arg
428
435
else
429
436
state.typedArg = state.typedArg.updated(arg, targ.nn)
@@ -451,7 +458,7 @@ object ProtoTypes {
451
458
val protoTyperState = ctx.typerState
452
459
val oldConstraint = protoTyperState.constraint
453
460
val args1 = args.mapWithIndexConserve((arg, idx) =>
454
- cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false ))
461
+ cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false , NoType ))
455
462
val newConstraint = protoTyperState.constraint
456
463
457
464
if ! args1.exists(arg => isUndefined(arg.tpe)) then state.typedArgs = args1
@@ -498,7 +505,8 @@ object ProtoTypes {
498
505
val locked = ctx.typerState.ownedVars
499
506
val targ = cacheTypedArg(arg,
500
507
typer.typedUnadapted(_, wideFormal, locked)(using argCtx),
501
- force = true )
508
+ force = true ,
509
+ wideFormal)
502
510
val targ1 = typer.adapt(targ, wideFormal, locked)
503
511
if wideFormal eq formal then targ1
504
512
else checkNoWildcardCaptureForCBN(targ1)
0 commit comments