@@ -222,72 +222,6 @@ object Inferencing {
222
222
case _ => NoType
223
223
}
224
224
225
- /** Interpolate those undetermined type variables in the widened type of this tree
226
- * which are introduced by type application contained in the tree.
227
- * If such a variable appears covariantly in type `tp` or does not appear at all,
228
- * approximate it by its lower bound. Otherwise, if it appears contravariantly
229
- * in type `tp` approximate it by its upper bound.
230
- * @param ownedBy if it is different from NoSymbol, all type variables owned by
231
- * `ownedBy` qualify, independent of position.
232
- * Without that second condition, it can be that certain variables escape
233
- * interpolation, for instance when their tree was eta-lifted, so
234
- * the typechecked tree is no longer the tree in which the variable
235
- * was declared. A concrete example of this phenomenon can be
236
- * observed when compiling core.TypeOps#asSeenFrom.
237
- */
238
- def interpolateUndetVars (tree : Tree , ownedBy : Symbol )(implicit ctx : Context ): Unit = {
239
- val constraint = ctx.typerState.constraint
240
- val qualifies = (tvar : TypeVar ) =>
241
- (tree contains tvar.bindingTree) || ownedBy.exists && tvar.owner == ownedBy
242
- def interpolate () = Stats .track(" interpolateUndetVars" ) {
243
- val tp = tree.tpe.widen
244
- constr.println(s " interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s " ${tvar.show}@ ${tvar.bindingTree.pos}" )}" )
245
- constr.println(s " qualifying undet vars: ${constraint.uninstVars filter qualifies map (tvar => s " $tvar / ${tvar.show}" )}, constraint: ${constraint.show}" )
246
-
247
- val vs = variances(tp, qualifies)
248
- val hasUnreportedErrors = ctx.typerState.reporter match {
249
- case r : StoreReporter if r.hasErrors => true
250
- case _ => false
251
- }
252
- // Avoid interpolating variables if typerstate has unreported errors.
253
- // Reason: The errors might reflect unsatisfiable constraints. In that
254
- // case interpolating without taking account the constraints risks producing
255
- // nonsensical types that then in turn produce incomprehensible errors.
256
- // An example is in neg/i1240.scala. Without the condition in the next code line
257
- // we get for
258
- //
259
- // val y: List[List[String]] = List(List(1))
260
- //
261
- // i1430.scala:5: error: type mismatch:
262
- // found : Int(1)
263
- // required: Nothing
264
- // val y: List[List[String]] = List(List(1))
265
- // ^
266
- // With the condition, we get the much more sensical:
267
- //
268
- // i1430.scala:5: error: type mismatch:
269
- // found : Int(1)
270
- // required: String
271
- // val y: List[List[String]] = List(List(1))
272
- if (! hasUnreportedErrors)
273
- vs foreachBinding { (tvar, v) =>
274
- if (v != 0 && ctx.typerState.constraint.contains(tvar)) {
275
- // previous interpolations could have already instantiated `tvar`
276
- // through unification, that's why we have to check again whether `tvar`
277
- // is contained in the current constraint.
278
- typr.println(s " interpolate ${if (v == 1 ) " co" else " contra" }variant ${tvar.show} in ${tp.show}" )
279
- tvar.instantiate(fromBelow = v == 1 )
280
- }
281
- }
282
- for (tvar <- constraint.uninstVars)
283
- if (! (vs contains tvar) && qualifies(tvar)) {
284
- typr.println(s " instantiating non-occurring ${tvar.show} in ${tp.show} / $tp" )
285
- tvar.instantiate(fromBelow = true )
286
- }
287
- }
288
- if (constraint.uninstVars exists qualifies) interpolate()
289
- }
290
-
291
225
/** Instantiate undetermined type variables to that type `tp` is
292
226
* maximized and return None. If this is not possible, because a non-variant
293
227
* typevar is not uniquely determined, return that typevar in a Some.
@@ -375,6 +309,93 @@ object Inferencing {
375
309
}
376
310
}
377
311
312
+ trait Inferencing { this : Typer =>
313
+ import Inferencing ._
314
+ import tpd ._
315
+
316
+ /** Interpolate those undetermined type variables in the widened type of this tree
317
+ * which are introduced by type application contained in the tree.
318
+ * If such a variable appears covariantly in type `tp` or does not appear at all,
319
+ * approximate it by its lower bound. Otherwise, if it appears contravariantly
320
+ * in type `tp` approximate it by its upper bound.
321
+ * @param ownedBy if it is different from NoSymbol, all type variables owned by
322
+ * `ownedBy` qualify, independent of position.
323
+ * Without that second condition, it can be that certain variables escape
324
+ * interpolation, for instance when their tree was eta-lifted, so
325
+ * the typechecked tree is no longer the tree in which the variable
326
+ * was declared. A concrete example of this phenomenon can be
327
+ * observed when compiling core.TypeOps#asSeenFrom.
328
+ */
329
+ def interpolateUndetVars (tree : Tree , ownedBy : Symbol , pt : Type )(implicit ctx : Context ): Unit = {
330
+ val constraint = ctx.typerState.constraint
331
+ val qualifies = (tvar : TypeVar ) =>
332
+ (tree contains tvar.bindingTree) || ownedBy.exists && tvar.owner == ownedBy
333
+ def interpolate () = Stats .track(" interpolateUndetVars" ) {
334
+ val tp = tree.tpe.widen
335
+ constr.println(s " interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s " ${tvar.show}@ ${tvar.bindingTree.pos}" )}" )
336
+ constr.println(s " qualifying undet vars: ${constraint.uninstVars filter qualifies map (tvar => s " $tvar / ${tvar.show}" )}, constraint: ${constraint.show}" )
337
+
338
+ val vs = variances(tp, qualifies)
339
+ val hasUnreportedErrors = ctx.typerState.reporter match {
340
+ case r : StoreReporter if r.hasErrors => true
341
+ case _ => false
342
+ }
343
+
344
+ var isConstrained = false
345
+ def ensureConstrained () =
346
+ if (! isConstrained) {
347
+ isConstrained = true
348
+ tree match {
349
+ case tree : Apply => // already constrained
350
+ case _ => tree.tpe match {
351
+ case _ : MethodOrPoly => // already constrained
352
+ case tp => constrainResult(tp, pt)
353
+ }
354
+ }
355
+ }
356
+
357
+ // Avoid interpolating variables if typerstate has unreported errors.
358
+ // Reason: The errors might reflect unsatisfiable constraints. In that
359
+ // case interpolating without taking account the constraints risks producing
360
+ // nonsensical types that then in turn produce incomprehensible errors.
361
+ // An example is in neg/i1240.scala. Without the condition in the next code line
362
+ // we get for
363
+ //
364
+ // val y: List[List[String]] = List(List(1))
365
+ //
366
+ // i1430.scala:5: error: type mismatch:
367
+ // found : Int(1)
368
+ // required: Nothing
369
+ // val y: List[List[String]] = List(List(1))
370
+ // ^
371
+ // With the condition, we get the much more sensical:
372
+ //
373
+ // i1430.scala:5: error: type mismatch:
374
+ // found : Int(1)
375
+ // required: String
376
+ // val y: List[List[String]] = List(List(1))
377
+ if (! hasUnreportedErrors)
378
+ vs foreachBinding { (tvar, v) =>
379
+ if (v != 0 && ctx.typerState.constraint.contains(tvar)) {
380
+ // previous interpolations could have already instantiated `tvar`
381
+ // through unification, that's why we have to check again whether `tvar`
382
+ // is contained in the current constraint.
383
+ typr.println(s " interpolate ${if (v == 1 ) " co" else " contra" }variant ${tvar.show} in ${tp.show}" )
384
+ ensureConstrained()
385
+ tvar.instantiate(fromBelow = v == 1 )
386
+ }
387
+ }
388
+ for (tvar <- constraint.uninstVars)
389
+ if (! (vs contains tvar) && qualifies(tvar)) {
390
+ typr.println(s " instantiating non-occurring ${tvar.show} in ${tp.show} / $tp" )
391
+ ensureConstrained()
392
+ tvar.instantiate(fromBelow = true )
393
+ }
394
+ }
395
+ if (constraint.uninstVars exists qualifies) interpolate()
396
+ }
397
+ }
398
+
378
399
/** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */
379
400
@ sharable object ForceDegree {
380
401
class Value (val appliesTo : TypeVar => Boolean , val minimizeAll : Boolean )
0 commit comments