Skip to content

Commit 21cc1b6

Browse files
committed
Change unapply error reporting
1 parent 26de50a commit 21cc1b6

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,11 @@ trait Applications extends Compatibility {
10641064
if (!tree.tpe.isError && tree.tpe.isErroneous) tree
10651065
else errorTree(tree, NotAnExtractor(qual))
10661066

1067+
def reportErrors(tree: Tree, state: TyperState) =
1068+
assert(state.reporter.hasErrors)
1069+
state.reporter.flush()
1070+
tree
1071+
10671072
/** If this is a term ref tree, try to typecheck with its type name.
10681073
* If this refers to a type alias, follow the alias, and if
10691074
* one finds a class, reference the class companion module.
@@ -1097,42 +1102,52 @@ trait Applications extends Compatibility {
10971102
* overloaded unapply does *not* need to be applicable to its argument
10981103
* whereas overloaded variants need to have a conforming variant.
10991104
*/
1100-
def trySelectUnapply(qual: untpd.Tree)(fallBack: Tree => Tree): Tree = {
1105+
def trySelectUnapply(qual: untpd.Tree)(fallBack: (Tree, TyperState) => Tree): Tree = {
11011106
// try first for non-overloaded, then for overloaded ocurrences
1102-
def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree = {
1107+
def tryWithName(name: TermName)(fallBack: (Tree, TyperState) => Tree)(implicit ctx: Context): Tree = {
11031108
def tryWithProto(pt: Type)(implicit ctx: Context) = {
11041109
val result = typedExpr(untpd.Select(qual, name), new UnapplyFunProto(pt, this))
1105-
if (!result.symbol.exists || result.symbol.name == name) result
1110+
if !result.symbol.exists
1111+
|| result.symbol.name == name
1112+
|| ctx.reporter.hasErrors
1113+
then result
11061114
else notAnExtractor(result)
11071115
// It might be that the result of typedExpr is an `apply` selection or implicit conversion.
11081116
// Reject in this case.
11091117
}
11101118
tryEither {
11111119
tryWithProto(selType)
11121120
} {
1113-
(sel, _) =>
1121+
(sel, state) =>
11141122
tryEither {
11151123
tryWithProto(WildcardType)
11161124
} {
1117-
(_, _) => fallBack(sel)
1125+
(_, _) => fallBack(sel, state)
11181126
}
11191127
}
11201128
}
11211129

11221130
// try first for unapply, then for unapplySeq
11231131
tryWithName(nme.unapply) {
1124-
sel => tryWithName(nme.unapplySeq)(_ => fallBack(sel)) // for backwards compatibility; will be dropped
1132+
(sel, state) =>
1133+
tryWithName(nme.unapplySeq) {
1134+
(_, _) => fallBack(sel, state)
1135+
}
11251136
}
11261137
}
11271138

11281139
/** Produce a typed qual.unapply or qual.unapplySeq tree, or
11291140
* else if this fails follow a type alias and try again.
11301141
*/
1131-
var unapplyFn = trySelectUnapply(qual) { sel =>
1132-
val qual1 = followTypeAlias(qual)
1133-
if (qual1.isEmpty) notAnExtractor(sel)
1134-
else trySelectUnapply(qual1)(_ => notAnExtractor(sel))
1135-
}
1142+
var unapplyFn =
1143+
trySelectUnapply(qual) {
1144+
(sel, state) =>
1145+
val qual1 = followTypeAlias(qual)
1146+
if (qual1.isEmpty) reportErrors(sel, state)
1147+
else trySelectUnapply(qual1) {
1148+
(_, state) => reportErrors(sel, state)
1149+
}
1150+
}
11361151

11371152
/** Add a `Bind` node for each `bound` symbol in a type application `unapp` */
11381153
def addBinders(unapp: Tree, bound: List[Symbol]) = unapp match {

0 commit comments

Comments
 (0)