@@ -80,15 +80,17 @@ object Implicits {
80
80
case mt : MethodType =>
81
81
mt.isImplicitMethod ||
82
82
mt.paramInfos.lengthCompare(1 ) != 0 ||
83
- ! ctx.test(implicit ctx => argType relaxed_<:< mt.paramInfos.head)
83
+ ! ctx.test(implicit ctx =>
84
+ argType relaxed_<:< mt.paramInfos.head.widenSingleton)
84
85
case poly : PolyType =>
85
86
// We do not need to call ProtoTypes#constrained on `poly` because
86
87
// `refMatches` is always called with mode TypevarsMissContext enabled.
87
88
poly.resultType match {
88
89
case mt : MethodType =>
89
90
mt.isImplicitMethod ||
90
91
mt.paramInfos.length != 1 ||
91
- ! ctx.test(implicit ctx => argType relaxed_<:< wildApprox(mt.paramInfos.head, null , Set .empty))
92
+ ! ctx.test(implicit ctx =>
93
+ argType relaxed_<:< wildApprox(mt.paramInfos.head.widenSingleton, null , Set .empty))
92
94
case rtp =>
93
95
discardForView(wildApprox(rtp, null , Set .empty), argType)
94
96
}
@@ -132,14 +134,37 @@ object Implicits {
132
134
case _ => false
133
135
}
134
136
137
+ /** Widen singleton arguments of implicit conversions to their underlying type.
138
+ * This is necessary so that they can be found eligible for the argument type.
139
+ * Note that we always take the underlying type of a singleton type as the argument
140
+ * type, so that we get a reasonable implicit cache hit ratio.
141
+ */
142
+ def adjustSingletonArg (tp : Type ): Type = tp match {
143
+ case tp : PolyType =>
144
+ val res = adjustSingletonArg(tp.resType)
145
+ if (res `eq` tp.resType) tp else tp.derivedLambdaType(resType = res)
146
+ case tp : MethodType =>
147
+ tp.paramInfos match {
148
+ case (single : SingletonType ) :: Nil =>
149
+ tp.derivedLambdaType(paramInfos = single.widenSingleton :: Nil )
150
+ case _ =>
151
+ tp
152
+ }
153
+ case _ => tp
154
+ }
155
+
135
156
(ref.symbol isAccessibleFrom ref.prefix) && {
136
157
if (discard) {
137
158
record(" discarded eligible" )
138
159
false
139
160
}
140
161
else {
141
162
val ptNorm = normalize(pt, pt) // `pt` could be implicit function types, check i2749
142
- NoViewsAllowed .isCompatible(normalize(ref, pt), ptNorm)
163
+ val refAdjusted =
164
+ if (pt.isInstanceOf [ViewProto ]) adjustSingletonArg(ref.widenSingleton)
165
+ else ref
166
+ val refNorm = normalize(refAdjusted, pt)
167
+ NoViewsAllowed .isCompatible(refNorm, ptNorm)
143
168
}
144
169
}
145
170
}
0 commit comments