@@ -29,7 +29,7 @@ import config.Printers.{overload, typr, unapp}
2929import TypeApplications ._
3030
3131import reporting .diagnostic .Message
32- import reporting .diagnostic .messages .{UnexpectedPatternForSummonFrom , NotAMember }
32+ import reporting .diagnostic .messages .{UnexpectedPatternForSummonFrom , NotAMember , MissingIdent }
3333import reporting .trace
3434import Constants .{Constant , IntTag , LongTag }
3535import dotty .tools .dotc .reporting .diagnostic .messages .{UnapplyInvalidReturnType , NotAnExtractor , UnapplyInvalidNumberOfArguments }
@@ -819,12 +819,13 @@ trait Applications extends Compatibility {
819819 tryEither {
820820 typedExpr(fn, pt)
821821 } { (result, tstate) =>
822- def fallBack = {
823- tstate.commit()
822+ def fallBack (nuState : TyperState ) =
823+ if (nuState ne ctx.typerState) && ! saysNotFound(nuState, EmptyTypeName )
824+ then nuState.commit() // nuState messages are more interesting that tstate's "not found"
825+ else tstate.commit() // it's "not found" both ways; keep original message
824826 result
825- }
826- if (untpd.isPath(fn)) tryNew(untpd)(fn, pt, fallBack)
827- else fallBack
827+ if untpd.isPath(fn) then tryNew(untpd)(fn, pt, fallBack)
828+ else fallBack(ctx.typerState)
828829 }
829830
830831 /** Typecheck application. Result could be an `Apply` node,
@@ -1056,6 +1057,21 @@ trait Applications extends Compatibility {
10561057 tree
10571058 }
10581059
1060+ /** Does `state` contain a single "NotAMember" or "MissingIdent" message as
1061+ * pending error message that says `$memberName is not a member of ...` or
1062+ * `Not found: $memberName`? If memberName is empty, any name will do.
1063+ */
1064+ def saysNotFound (state : TyperState , memberName : Name )(using Context ): Boolean =
1065+ state.reporter.pendingMessages match
1066+ case msg :: Nil =>
1067+ msg.contained match
1068+ case NotAMember (_, name, _, _) =>
1069+ memberName.isEmpty || name == memberName
1070+ case MissingIdent (_, _, name) =>
1071+ memberName.isEmpty || name == memberName.toString
1072+ case _ => false
1073+ case _ => false
1074+
10591075 def typedUnApply (tree : untpd.Apply , selType : Type )(implicit ctx : Context ): Tree = {
10601076 record(" typedUnApply" )
10611077 val Apply (qual, args) = tree
@@ -1066,25 +1082,14 @@ trait Applications extends Compatibility {
10661082 if (! tree.tpe.isError && tree.tpe.isErroneous) tree
10671083 else errorTree(tree, NotAnExtractor (qual))
10681084
1069- /** Does `state` contain a single "NotAMember" message as pending error message
1070- * that says `$membername is not a member of ...` ?
1071- */
1072- def saysNotAMember (state : TyperState , memberName : TermName ): Boolean =
1073- state.reporter.pendingMessages match
1074- case msg :: Nil =>
1075- msg.contained match
1076- case NotAMember (_, name, _, _) => name == memberName
1077- case _ => false
1078- case _ => false
1079-
10801085 /** Report errors buffered in state.
10811086 * @pre state has errors to report
10821087 * If there is a single error stating that "unapply" is not a member, print
10831088 * the more informative "notAnExtractor" message instead.
10841089 */
10851090 def reportErrors (tree : Tree , state : TyperState ): Tree =
10861091 assert(state.reporter.hasErrors)
1087- if saysNotAMember (state, nme.unapply) then notAnExtractor(tree)
1092+ if saysNotFound (state, nme.unapply) then notAnExtractor(tree)
10881093 else
10891094 state.reporter.flush()
10901095 tree
@@ -1154,7 +1159,7 @@ trait Applications extends Compatibility {
11541159 (sel2, state2) =>
11551160 // if both fail, return unapply error, unless that is simply a
11561161 // "not a member", and the unapplySeq error is more refined.
1157- if saysNotAMember (state, nme.unapply) && ! saysNotAMember (state2, nme.unapplySeq)
1162+ if saysNotFound (state, nme.unapply) && ! saysNotFound (state2, nme.unapplySeq)
11581163 then fallBack(sel2, state2)
11591164 else fallBack(sel, state)
11601165 }
0 commit comments