@@ -29,7 +29,7 @@ import config.Printers.{overload, typr, unapp}
29
29
import TypeApplications ._
30
30
31
31
import reporting .diagnostic .Message
32
- import reporting .diagnostic .messages .{UnexpectedPatternForSummonFrom , NotAMember }
32
+ import reporting .diagnostic .messages .{UnexpectedPatternForSummonFrom , NotAMember , MissingIdent }
33
33
import reporting .trace
34
34
import Constants .{Constant , IntTag , LongTag }
35
35
import dotty .tools .dotc .reporting .diagnostic .messages .{UnapplyInvalidReturnType , NotAnExtractor , UnapplyInvalidNumberOfArguments }
@@ -819,12 +819,13 @@ trait Applications extends Compatibility {
819
819
tryEither {
820
820
typedExpr(fn, pt)
821
821
} { (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
824
826
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)
828
829
}
829
830
830
831
/** Typecheck application. Result could be an `Apply` node,
@@ -1056,6 +1057,21 @@ trait Applications extends Compatibility {
1056
1057
tree
1057
1058
}
1058
1059
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
+
1059
1075
def typedUnApply (tree : untpd.Apply , selType : Type )(implicit ctx : Context ): Tree = {
1060
1076
record(" typedUnApply" )
1061
1077
val Apply (qual, args) = tree
@@ -1066,25 +1082,14 @@ trait Applications extends Compatibility {
1066
1082
if (! tree.tpe.isError && tree.tpe.isErroneous) tree
1067
1083
else errorTree(tree, NotAnExtractor (qual))
1068
1084
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
-
1080
1085
/** Report errors buffered in state.
1081
1086
* @pre state has errors to report
1082
1087
* If there is a single error stating that "unapply" is not a member, print
1083
1088
* the more informative "notAnExtractor" message instead.
1084
1089
*/
1085
1090
def reportErrors (tree : Tree , state : TyperState ): Tree =
1086
1091
assert(state.reporter.hasErrors)
1087
- if saysNotAMember (state, nme.unapply) then notAnExtractor(tree)
1092
+ if saysNotFound (state, nme.unapply) then notAnExtractor(tree)
1088
1093
else
1089
1094
state.reporter.flush()
1090
1095
tree
@@ -1154,7 +1159,7 @@ trait Applications extends Compatibility {
1154
1159
(sel2, state2) =>
1155
1160
// if both fail, return unapply error, unless that is simply a
1156
1161
// "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)
1158
1163
then fallBack(sel2, state2)
1159
1164
else fallBack(sel, state)
1160
1165
}
0 commit comments