@@ -26,6 +26,7 @@ import Constants._
26
26
import Applications ._
27
27
import ProtoTypes ._
28
28
import ErrorReporting ._
29
+ import Annotations .Annotation
29
30
import reporting .diagnostic .{Message , MessageContainer }
30
31
import Inferencing .fullyDefinedType
31
32
import Trees ._
@@ -696,22 +697,44 @@ trait Implicits { self: Typer =>
696
697
}
697
698
}
698
699
def location (preposition : String ) = if (where.isEmpty) " " else s " $preposition $where"
700
+ def userDefinedMessage (annot : Annotation , params : List [String ], args : List [Type ]): Option [String ] =
701
+ for (Trees .Literal (Constant (raw : String )) <- annot.argument(0 )) yield {
702
+ err.userDefinedErrorString(
703
+ raw,
704
+ params,
705
+ args)
706
+ }
699
707
arg.tpe match {
700
708
case ambi : AmbiguousImplicits =>
701
- msg(s " ambiguous implicit arguments: ${ambi.explanation}${location(" of" )}" )(
702
- s " ambiguous implicit arguments of type ${pt.show} found ${location(" for" )}" )
703
- case _ =>
704
- val userDefined =
705
- for {
706
- notFound <- pt.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot )
707
- Trees .Literal (Constant (raw : String )) <- notFound.argument(0 )
709
+ val maybeAnnot = ambi.alt1.ref.symbol.getAnnotation(defn.ImplicitAmbiguousAnnot ).map(
710
+ (_, ambi.alt1)
711
+ ).orElse(
712
+ ambi.alt2.ref.symbol.getAnnotation(defn.ImplicitAmbiguousAnnot ).map(
713
+ (_, ambi.alt2)
714
+ )
715
+ )
716
+ val userDefined = maybeAnnot.flatMap { case (annot, alt) =>
717
+ val params = alt.ref.underlying match {
718
+ case lambda : TypeLambda => lambda.typeParams.map(_.paramName.unexpandedName.toString)
719
+ case _ => Nil
708
720
}
709
- yield {
710
- err.implicitNotFoundString(
711
- raw,
712
- pt.typeSymbol.typeParams.map(_.name.unexpandedName.toString),
713
- pt.argInfos)
721
+ alt.tstate.commit()
722
+ val args = alt.tree match {
723
+ case TypeApply (_, targs) if params.nonEmpty =>
724
+ targs.map(a => fullyDefinedType(a.typeOpt, " type parameter" , a.pos))
725
+ case _ =>
726
+ Nil
714
727
}
728
+ userDefinedMessage(annot, params, args)
729
+ }
730
+ userDefined.map(msg(_)()).getOrElse(
731
+ msg(s " ambiguous implicit arguments: ${ambi.explanation}${location(" of" )}" )(
732
+ s " ambiguous implicit arguments of type ${pt.show} found ${location(" for" )}" )
733
+ )
734
+ case _ =>
735
+ val userDefined = pt.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot ).flatMap(
736
+ userDefinedMessage(_, pt.typeSymbol.typeParams.map(_.name.unexpandedName.toString), pt.argInfos)
737
+ )
715
738
msg(userDefined.getOrElse(em " no implicit argument of type $pt was found ${location(" for" )}" ))()
716
739
}
717
740
}
0 commit comments