@@ -24,6 +24,7 @@ import Constants._
24
24
import Applications ._
25
25
import ProtoTypes ._
26
26
import ErrorReporting ._
27
+ import reporting .diagnostic .MessageContainer
27
28
import Inferencing .fullyDefinedType
28
29
import Trees ._
29
30
import Hashable ._
@@ -212,6 +213,8 @@ object Implicits {
212
213
/** A "no matching implicit found" failure */
213
214
case object NoImplicitMatches extends SearchFailure
214
215
216
+ case object DivergingImplicit extends SearchFailure
217
+
215
218
/** A search failure that can show information about the cause */
216
219
abstract class ExplainedSearchFailure extends SearchFailure {
217
220
protected def pt : Type
@@ -233,9 +236,35 @@ object Implicits {
233
236
" \n " + explanation
234
237
}
235
238
236
- class NonMatchingImplicit (ref : TermRef , val pt : Type , val argument : tpd.Tree ) extends ExplainedSearchFailure {
237
- def explanation (implicit ctx : Context ): String =
238
- em " ${err.refStr(ref)} does not $qualify"
239
+ class NonMatchingImplicit (ref : TermRef ,
240
+ val pt : Type ,
241
+ val argument : tpd.Tree ,
242
+ trail : List [MessageContainer ]) extends ExplainedSearchFailure {
243
+ private val separator = " \n **** because ****\n "
244
+
245
+ /** Replace repeated parts beginning with `separator` by ... */
246
+ private def elideRepeated (str : String ): String = {
247
+ val startIdx = str.indexOfSlice(separator)
248
+ val nextIdx = str.indexOfSlice(separator, startIdx + separator.length)
249
+ if (nextIdx < 0 ) str
250
+ else {
251
+ val prefix = str.take(startIdx)
252
+ val first = str.slice(startIdx, nextIdx)
253
+ var rest = str.drop(nextIdx)
254
+ if (rest.startsWith(first)) {
255
+ rest = rest.drop(first.length)
256
+ val dots = " \n\n ...\n "
257
+ if (! rest.startsWith(dots)) rest = dots ++ rest
258
+ }
259
+ prefix ++ first ++ rest
260
+ }
261
+ }
262
+
263
+ def explanation (implicit ctx : Context ): String = {
264
+ val headMsg = em " ${err.refStr(ref)} does not $qualify"
265
+ val trailMsg = trail.map(mc => i " $separator ${mc.message}" ).mkString
266
+ elideRepeated(headMsg ++ trailMsg)
267
+ }
239
268
}
240
269
241
270
class ShadowedImplicit (ref : TermRef , shadowing : Type , val pt : Type , val argument : tpd.Tree ) extends ExplainedSearchFailure {
@@ -587,7 +616,7 @@ trait Implicits { self: Typer =>
587
616
val wildProto = implicitProto(pt, wildApprox(_))
588
617
589
618
/** Search failures; overridden in ExplainedImplicitSearch */
590
- protected def nonMatchingImplicit (ref : TermRef ): SearchFailure = NoImplicitMatches
619
+ protected def nonMatchingImplicit (ref : TermRef , trail : List [ MessageContainer ] ): SearchFailure = NoImplicitMatches
591
620
protected def divergingImplicit (ref : TermRef ): SearchFailure = NoImplicitMatches
592
621
protected def shadowedImplicit (ref : TermRef , shadowing : Type ): SearchFailure = NoImplicitMatches
593
622
protected def failedSearch : SearchFailure = NoImplicitMatches
@@ -628,7 +657,7 @@ trait Implicits { self: Typer =>
628
657
{ implicits.println(i " invalid eqAny[ $tp1, $tp2] " ); false }
629
658
}
630
659
if (ctx.reporter.hasErrors)
631
- nonMatchingImplicit(ref)
660
+ nonMatchingImplicit(ref, ctx.reporter.removeBufferedMessages )
632
661
else if (contextual && ! ctx.mode.is(Mode .ImplicitShadowing ) &&
633
662
! shadowing.tpe.isError && ! refMatches(shadowing)) {
634
663
implicits.println(i " SHADOWING $ref in ${ref.termSymbol.owner} is shadowed by $shadowing in ${shadowing.symbol.owner}" )
@@ -637,7 +666,7 @@ trait Implicits { self: Typer =>
637
666
else generated1 match {
638
667
case TypeApply (fn, targs @ (arg1 :: arg2 :: Nil ))
639
668
if fn.symbol == defn.Predef_eqAny && ! validEqAnyArgs(arg1.tpe, arg2.tpe) =>
640
- nonMatchingImplicit(ref)
669
+ nonMatchingImplicit(ref, Nil )
641
670
case _ =>
642
671
SearchSuccess (generated1, ref, ctx.typerState)
643
672
}
@@ -743,8 +772,8 @@ trait Implicits { self: Typer =>
743
772
fail
744
773
}
745
774
def failures = myFailures.toList
746
- override def nonMatchingImplicit (ref : TermRef ) =
747
- record(new NonMatchingImplicit (ref, pt, argument))
775
+ override def nonMatchingImplicit (ref : TermRef , trail : List [ MessageContainer ] ) =
776
+ record(new NonMatchingImplicit (ref, pt, argument, trail ))
748
777
override def divergingImplicit (ref : TermRef ) =
749
778
record(new DivergingImplicit (ref, pt, argument))
750
779
override def shadowedImplicit (ref : TermRef , shadowing : Type ): SearchFailure =
0 commit comments