Skip to content

Commit 917f58f

Browse files
committed
Better printing of variant types with wildcard arguments.
We used to approximate these by their bounds, but this is confusing. See comment in printbounds.scala.
1 parent a468a86 commit 917f58f

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ class TypeApplications(val self: Type) extends AnyVal {
293293
/** If this is an encoding of a (partially) applied type, return its arguments,
294294
* otherwise return Nil.
295295
* Existential types in arguments are returned as TypeBounds instances.
296+
* @param interpolate See argInfo
296297
*/
297-
final def argInfos(implicit ctx: Context): List[Type] = {
298+
final def argInfos(interpolate: Boolean)(implicit ctx: Context): List[Type] = {
298299
var tparams: List[TypeSymbol] = null
299300
def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar match {
300301
case tp @ RefinedType(tycon, name) =>
@@ -304,7 +305,7 @@ class TypeApplications(val self: Type) extends AnyVal {
304305
if (tparams == null) tparams = tycon.typeParams
305306
if (buf.size < tparams.length) {
306307
val tparam = tparams(buf.size)
307-
if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam)
308+
if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam, interpolate)
308309
else null
309310
} else null
310311
}
@@ -316,6 +317,8 @@ class TypeApplications(val self: Type) extends AnyVal {
316317
if (buf == null) Nil else buf.toList
317318
}
318319

320+
final def argInfos(implicit ctx: Context): List[Type] = argInfos(interpolate = true)
321+
319322
/** Argument types where existential types in arguments are disallowed */
320323
def argTypes(implicit ctx: Context) = argInfos mapConserve noBounds
321324

@@ -338,16 +341,27 @@ class TypeApplications(val self: Type) extends AnyVal {
338341

339342
/** If this is the image of a type argument to type parameter `tparam`,
340343
* recover the type argument, otherwise NoType.
344+
* @param interpolate If true, replace type bounds as arguments corresponding to
345+
* variant type parameters by their dominating element. I.e. an argument
346+
*
347+
* T <: U
348+
*
349+
* for a covariant type-parameter becomes U, and an argument
350+
*
351+
* T >: L
352+
*
353+
* for a contravariant type-parameter becomes L.
341354
*/
342-
final def argInfo(tparam: Symbol)(implicit ctx: Context): Type = self match {
355+
final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self match {
343356
case TypeBounds(lo, hi) =>
344357
if (lo eq hi) hi
345-
else {
358+
else if (interpolate) {
346359
val v = tparam.variance
347360
if (v > 0 && (lo isRef defn.NothingClass)) hi
348361
else if (v < 0 && (hi isRef defn.AnyClass)) lo
349-
else self // it's wildcard type; return its bounds
362+
else self
350363
}
364+
else self
351365
case _ =>
352366
NoType
353367
}

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
9797
}
9898
tp match {
9999
case tp: RefinedType =>
100-
val args = tp.argInfos
100+
val args = tp.argInfos(interpolate = false)
101101
if (args.nonEmpty) {
102102
val tycon = tp.unrefine
103103
val cls = tycon.typeSymbol

tests/pos/printbounds.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Tree[-T >: Number]
2+
3+
4+
class Test {
5+
6+
val x: Tree[_] = ???
7+
8+
val y = x // With -Xprint:front this should print val x: Tree[_] = x
9+
// used to print Tree[Nothing], which is confusing.
10+
11+
}

0 commit comments

Comments
 (0)