@@ -885,22 +885,31 @@ trait ContextErrors {
885
885
val WrongNumber, NoParams, ArgsDoNotConform = Value
886
886
}
887
887
888
- private def issueAmbiguousTypeErrorUnlessErroneous (pos : Position , pre : Type , sym1 : Symbol , sym2 : Symbol , rest : String ): Unit =
889
- if (! (pre.isErroneous || sym1.isErroneous || sym2.isErroneous)) {
890
- if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) {
891
- val methodName = nme.defaultGetterToMethod(sym1.name)
892
- context.issueAmbiguousError(AmbiguousTypeError (sym1.enclClass.pos,
893
- " in " + sym1.enclClass + " , multiple overloaded alternatives of " + methodName +
894
- " define default arguments" ))
895
- } else {
896
- context.issueAmbiguousError(AmbiguousTypeError (pos,
897
- (" ambiguous reference to overloaded definition,\n " +
898
- " both " + sym1 + sym1.locationString + " of type " + pre.memberType(sym1) +
899
- " \n and " + sym2 + sym2.locationString + " of type " + pre.memberType(sym2) +
900
- " \n match " + rest)
901
- ))
902
- }
903
- }
888
+ private def issueAmbiguousTypeErrorUnlessErroneous (pos : Position , pre : Type , sym1 : Symbol , sym2 : Symbol , rest : String ): Unit = {
889
+ // To avoid stack overflows (SI-8890), we MUST (at least) report when either `validTargets` OR `ambiguousSuppressed`
890
+ // More details:
891
+ // If `!context.ambiguousErrors`, `reporter.issueAmbiguousError` (which `context.issueAmbiguousError` forwards to)
892
+ // buffers ambiguous errors. In this case, to avoid looping, we must issue even if `!validTargets`. (TODO: why?)
893
+ // When not buffering (and thus reporting to the user), we shouldn't issue unless `validTargets`,
894
+ // otherwise we report two different errors that trace back to the same root cause,
895
+ // and unless `validTargets`, we don't know for sure the ambiguity is real anyway.
896
+ val validTargets = ! (pre.isErroneous || sym1.isErroneous || sym2.isErroneous)
897
+ val ambiguousBuffered = ! context.ambiguousErrors
898
+ if (validTargets || ambiguousBuffered)
899
+ context.issueAmbiguousError(
900
+ if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) {
901
+ val methodName = nme.defaultGetterToMethod(sym1.name)
902
+ AmbiguousTypeError (sym1.enclClass.pos,
903
+ s " in ${sym1.enclClass}, multiple overloaded alternatives of $methodName define default arguments " )
904
+
905
+ } else {
906
+ AmbiguousTypeError (pos,
907
+ " ambiguous reference to overloaded definition,\n " +
908
+ s " both ${sym1.fullLocationString} of type ${pre.memberType(sym1)}\n " +
909
+ s " and ${sym2.fullLocationString} of type ${pre.memberType(sym2)}\n " +
910
+ s " match $rest" )
911
+ })
912
+ }
904
913
905
914
def AccessError (tree : Tree , sym : Symbol , ctx : Context , explanation : String ): AbsTypeError =
906
915
AccessError (tree, sym, ctx.enclClass.owner.thisType, ctx.enclClass.owner, explanation)
0 commit comments