@@ -45,7 +45,14 @@ object ProtoTypes {
45
45
}
46
46
if (keepConstraint)
47
47
tp.widenSingleton match {
48
- case poly : PolyType => normalizedCompatible(tp, pt, keepConstraint = false )
48
+ case poly : PolyType =>
49
+ // We can't keep the constraint in this case, since we have to add type parameters
50
+ // to it, but there's no place to associate them with type variables.
51
+ // So we'd get a "inconsistent: no typevars were added to committable constraint"
52
+ // assertion failure in `constrained`. To do better, we'd have to change the
53
+ // constraint handling architecture so that some type parameters are committable
54
+ // and others are not. But that's a whole different ballgame.
55
+ normalizedCompatible(tp, pt, keepConstraint = false )
49
56
case _ => testCompat
50
57
}
51
58
else ctx.test(implicit ctx => testCompat)
@@ -196,8 +203,18 @@ object ProtoTypes {
196
203
def selectionProto (name : Name , tp : Type , typer : Typer )(implicit ctx : Context ): TermType =
197
204
if (name.isConstructorName) WildcardType
198
205
else tp match {
199
- case tp : UnapplyFunProto => new UnapplySelectionProto (name)
200
- case tp => SelectionProto (name, IgnoredProto (tp), typer, privateOK = true )
206
+ case tp : UnapplyFunProto =>
207
+ new UnapplySelectionProto (name)
208
+ case tp =>
209
+ val memberProto =
210
+ if (ctx.mode.is(Mode .SynthesizeExtMethodReceiver )) tp
211
+ else IgnoredProto (tp)
212
+ // Disregard what's known about the member in the selection prototype.
213
+ // This allows implicit conversions to be applied on the member
214
+ // and avoids duplicated computations. Exception: when synthesizing
215
+ // the receiver of an extension method, we do take the type of the first
216
+ // argument into sccount.
217
+ SelectionProto (name, memberProto, typer, privateOK = true )
201
218
}
202
219
203
220
/** A prototype for expressions [] that are in some unspecified selection operation
@@ -246,6 +263,8 @@ object ProtoTypes {
246
263
def isMatchedBy (tp : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
247
264
val args = unforcedTypedArgs
248
265
def isPoly (tree : Tree ) = tree.tpe.widenSingleton.isInstanceOf [PolyType ]
266
+ // See remark in normalizedCompatible for why we can't keep the constraint
267
+ // if one of the arguments has a PolyType.
249
268
typer.isApplicable(tp, Nil , args, resultType, keepConstraint && ! args.exists(isPoly))
250
269
}
251
270
@@ -308,7 +327,7 @@ object ProtoTypes {
308
327
if (state.typedArgs.size == args.length) state.typedArgs
309
328
else {
310
329
val args1 = args.mapconserve(cacheTypedArg(_, typer.typed(_), force))
311
- if (! args1.contains(WildcardType )) state.typedArgs = args1
330
+ if (force || ! args1.contains(WildcardType )) state.typedArgs = args1
312
331
args1
313
332
}
314
333
0 commit comments