@@ -2784,19 +2784,25 @@ class MissingImplicitArgument(
2784
2784
val idx = paramNames.indexOf(name)
2785
2785
if (idx >= 0 ) Some (i " ${args(idx)}" ) else None
2786
2786
""" \$\{\s*([^}\s]+)\s*\}""" .r.replaceAllIn(raw, (_ : Regex .Match ) match
2787
- case Regex .Groups (v) => quoteReplacement(translate(v).getOrElse(" " )).nn
2787
+ case Regex .Groups (v) => quoteReplacement(translate(v).getOrElse(v )).nn
2788
2788
)
2789
2789
2790
2790
/** @param rawMsg Message template with variables, e.g. "Variable A is ${A}"
2791
2791
* @param sym Symbol of the annotated type or of the method whose parameter was annotated
2792
2792
* @param substituteType Function substituting specific types for abstract types associated with variables, e.g A -> Int
2793
2793
*/
2794
- def formatAnnotationMessage (rawMsg : String , sym : Symbol , substituteType : Type => Type )(using Context ): String =
2794
+ def formatAnnotationMessage (
2795
+ rawMsg : String ,
2796
+ sym : Symbol ,
2797
+ paramNames : List [Name ],
2798
+ args : List [Type ],
2799
+ substituteType : Type => Type ,
2800
+ )(using Context ): String =
2795
2801
val substitutableTypesSymbols = substitutableTypeSymbolsInScope(sym)
2796
2802
userDefinedErrorString(
2797
2803
rawMsg,
2798
- paramNames = substitutableTypesSymbols.map(_.name.unexpandedName.toString),
2799
- args = substitutableTypesSymbols.map(_.typeRef).map(substituteType)
2804
+ paramNames = (paramNames ::: substitutableTypesSymbols.map(_.name)).map(_ .unexpandedName.toString),
2805
+ args = args ::: substitutableTypesSymbols.map(_.typeRef).map(substituteType)
2800
2806
)
2801
2807
2802
2808
/** Extract a user defined error message from a symbol `sym`
@@ -2808,14 +2814,17 @@ class MissingImplicitArgument(
2808
2814
msg <- ann.argumentConstantString(0 )
2809
2815
yield msg
2810
2816
2811
- def userDefinedImplicitNotFoundTypeMessageFor (sym : Symbol )(using Context ): Option [String ] =
2812
- for
2813
- rawMsg <- userDefinedMsg(sym, defn.ImplicitNotFoundAnnot )
2814
- if Feature .migrateTo3 || sym != defn.Function1
2815
- // Don't inherit "No implicit view available..." message if subtypes of Function1 are not treated as implicit conversions anymore
2816
- yield
2817
- val substituteType = (_ : Type ).asSeenFrom(pt, sym)
2818
- formatAnnotationMessage(rawMsg, sym, substituteType)
2817
+ def userDefinedImplicitNotFoundTypeMessageFor (
2818
+ sym : Symbol ,
2819
+ params : List [ParamInfo ] = Nil ,
2820
+ args : List [Type ] = Nil
2821
+ )(using Context ): Option [String ] = for
2822
+ rawMsg <- userDefinedMsg(sym, defn.ImplicitNotFoundAnnot )
2823
+ if Feature .migrateTo3 || sym != defn.Function1
2824
+ // Don't inherit "No implicit view available..." message if subtypes of Function1 are not treated as implicit conversions anymore
2825
+ yield
2826
+ val paramNames = params.map(_.paramName)
2827
+ formatAnnotationMessage(rawMsg, sym, paramNames, args, _.asSeenFrom(pt, sym))
2819
2828
2820
2829
/** Extracting the message from a method parameter, e.g. in
2821
2830
*
@@ -2830,19 +2839,21 @@ class MissingImplicitArgument(
2830
2839
val targs = tpd.typeArgss(applTree).flatten
2831
2840
val methodOwner = fn.symbol.owner
2832
2841
val methodOwnerType = tpd.qualifier(fn).tpe
2833
- val methodTypeParams = fn.symbol.paramSymss.flatten.filter (_.isType)
2842
+ val methodTypeParams = fn.symbol.paramSymss.flatten.withFilter (_.isType).map(_.name )
2834
2843
val methodTypeArgs = targs.map(_.tpe)
2835
- val substituteType = (_ : Type ).asSeenFrom(methodOwnerType, methodOwner).subst(methodTypeParams, methodTypeArgs)
2836
- formatAnnotationMessage(rawMsg, sym.owner, substituteType)
2844
+ formatAnnotationMessage(rawMsg, sym.owner, methodTypeParams, methodTypeArgs, _.asSeenFrom(methodOwnerType, methodOwner))
2837
2845
2838
2846
def userDefinedImplicitNotFoundTypeMessage (using Context ): Option [String ] =
2839
- def recur (tp : Type ): Option [String ] = tp match
2847
+ def recur (tp : Type , args : List [Type ] = Nil ): Option [String ] = tp match
2848
+ case tp : AppliedType =>
2849
+ recur(tp.tycon, tp.args)
2840
2850
case tp : TypeRef =>
2841
- val sym = tp.symbol
2842
- userDefinedImplicitNotFoundTypeMessageFor(sym).orElse(recur(tp.info))
2851
+ val typeParams = if tp.isLambdaSub then tp.hkTypeParams else tp.typeParams
2852
+ userDefinedImplicitNotFoundTypeMessageFor(tp.symbol, typeParams, args)
2853
+ .orElse(recur(tp.info))
2843
2854
case tp : ClassInfo =>
2844
2855
tp.baseClasses.iterator
2845
- .map(userDefinedImplicitNotFoundTypeMessageFor)
2856
+ .map(userDefinedImplicitNotFoundTypeMessageFor(_) )
2846
2857
.find(_.isDefined).flatten
2847
2858
case tp : TypeProxy =>
2848
2859
recur(tp.superType)
0 commit comments