Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ trait ShowMatchTrace(tps: Type*)(using Context) extends Message:
override def msgPostscript(using Context): String =
super.msgPostscript ++ matchReductionAddendum(tps*)

abstract class TypeMismatchMsg(found: Type, expected: Type)(errorId: ErrorMessageID)(using Context)
abstract class TypeMismatchMsg(found: Type, val expected: Type)(errorId: ErrorMessageID)(using Context)
extends Message(errorId), ShowMatchTrace(found, expected):
def kind = MessageKind.TypeMismatch
def explain(using Context) = err.whyNoMatchStr(found, expected)
Expand Down
21 changes: 13 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -427,21 +427,25 @@ object ProtoTypes {
* - t2 is a ascription (t22: T) and t1 is at the outside of t22
* - t2 is a closure (...) => t22 and t1 is at the outside of t22
*/
def hasInnerErrors(t: Tree)(using Context): Boolean = t match
case Typed(expr, tpe) => hasInnerErrors(expr)
case closureDef(mdef) => hasInnerErrors(mdef.rhs)
def hasInnerErrors(t: Tree, argType: Option[Type])(using Context): Boolean = t match
case Typed(expr, tpe) => hasInnerErrors(expr, argType)
case closureDef(mdef) => hasInnerErrors(mdef.rhs, argType)
case _ =>
t.existsSubTree { t1 =>
if t1.typeOpt.isError
&& t.span.toSynthetic != t1.span.toSynthetic
&& t.typeOpt != t1.typeOpt then
typr.println(i"error subtree $t1 of $t with ${t1.typeOpt}, spans = ${t1.span}, ${t.span}")
true
t1.typeOpt match
case errorType: ErrorType if errorType.msg.isInstanceOf[TypeMismatchMsg] =>
val typeMismtachMsg = errorType.msg.asInstanceOf[TypeMismatchMsg]
!argType.contains(typeMismtachMsg.expected)
case _ => true
else
false
}

private def cacheTypedArg(arg: untpd.Tree, typerFn: untpd.Tree => Tree, force: Boolean)(using Context): Tree = {
private def cacheTypedArg(arg: untpd.Tree, typerFn: untpd.Tree => Tree, force: Boolean, argType: Option[Type])(using Context): Tree = {
var targ = state.typedArg(arg)
if (targ == null)
untpd.functionWithUnknownParamType(arg) match {
Expand All @@ -459,7 +463,7 @@ object ProtoTypes {
targ = typerFn(arg)
// TODO: investigate why flow typing is not working on `targ`
if ctx.reporter.hasUnreportedErrors then
if hasInnerErrors(targ.nn) then
if hasInnerErrors(targ.nn, argType) then
state.errorArgs += arg
else
state.typedArg = state.typedArg.updated(arg, targ.nn)
Expand Down Expand Up @@ -487,7 +491,7 @@ object ProtoTypes {
val protoTyperState = ctx.typerState
val oldConstraint = protoTyperState.constraint
val args1 = args.mapWithIndexConserve((arg, idx) =>
cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false))
cacheTypedArg(arg, arg => typer.typed(norm(arg, idx)), force = false, None))
val newConstraint = protoTyperState.constraint

if !args1.exists(arg => isUndefined(arg.tpe)) then state.typedArgs = args1
Expand Down Expand Up @@ -534,7 +538,8 @@ object ProtoTypes {
val locked = ctx.typerState.ownedVars
val targ = cacheTypedArg(arg,
typer.typedUnadapted(_, wideFormal, locked)(using argCtx),
force = true)
force = true,
Some(wideFormal))
val targ1 = typer.adapt(targ, wideFormal, locked)
if wideFormal eq formal then targ1
else checkNoWildcardCaptureForCBN(targ1)
Expand Down
Loading