diff options
author | Martin Odersky <odersky@gmail.com> | 2014-11-21 18:28:25 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-11-24 14:57:49 +0100 |
commit | 917f58fe1de3f0237c9133ccda462f8af52124f8 (patch) | |
tree | 3655173fa3fafaeb0fd90de888f940021fa6e0ba /src | |
parent | a468a864dcdb89091985c194737968a979e874fb (diff) | |
download | dotty-917f58fe1de3f0237c9133ccda462f8af52124f8.tar.gz dotty-917f58fe1de3f0237c9133ccda462f8af52124f8.tar.bz2 dotty-917f58fe1de3f0237c9133ccda462f8af52124f8.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 24 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 2 |
2 files changed, 20 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 3beb680d9..d00b018c8 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -293,8 +293,9 @@ class TypeApplications(val self: Type) extends AnyVal { /** If this is an encoding of a (partially) applied type, return its arguments, * otherwise return Nil. * Existential types in arguments are returned as TypeBounds instances. + * @param interpolate See argInfo */ - final def argInfos(implicit ctx: Context): List[Type] = { + final def argInfos(interpolate: Boolean)(implicit ctx: Context): List[Type] = { var tparams: List[TypeSymbol] = null def recur(tp: Type, refineCount: Int): mutable.ListBuffer[Type] = tp.stripTypeVar match { case tp @ RefinedType(tycon, name) => @@ -304,7 +305,7 @@ class TypeApplications(val self: Type) extends AnyVal { if (tparams == null) tparams = tycon.typeParams if (buf.size < tparams.length) { val tparam = tparams(buf.size) - if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam) + if (name == tparam.name) buf += tp.refinedInfo.argInfo(tparam, interpolate) else null } else null } @@ -316,6 +317,8 @@ class TypeApplications(val self: Type) extends AnyVal { if (buf == null) Nil else buf.toList } + final def argInfos(implicit ctx: Context): List[Type] = argInfos(interpolate = true) + /** Argument types where existential types in arguments are disallowed */ def argTypes(implicit ctx: Context) = argInfos mapConserve noBounds @@ -338,16 +341,27 @@ class TypeApplications(val self: Type) extends AnyVal { /** If this is the image of a type argument to type parameter `tparam`, * recover the type argument, otherwise NoType. + * @param interpolate If true, replace type bounds as arguments corresponding to + * variant type parameters by their dominating element. I.e. an argument + * + * T <: U + * + * for a covariant type-parameter becomes U, and an argument + * + * T >: L + * + * for a contravariant type-parameter becomes L. */ - final def argInfo(tparam: Symbol)(implicit ctx: Context): Type = self match { + final def argInfo(tparam: Symbol, interpolate: Boolean = true)(implicit ctx: Context): Type = self match { case TypeBounds(lo, hi) => if (lo eq hi) hi - else { + else if (interpolate) { val v = tparam.variance if (v > 0 && (lo isRef defn.NothingClass)) hi else if (v < 0 && (hi isRef defn.AnyClass)) lo - else self // it's wildcard type; return its bounds + else self } + else self case _ => NoType } diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 12ac03bd0..a5f1c07fd 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -97,7 +97,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } tp match { case tp: RefinedType => - val args = tp.argInfos + val args = tp.argInfos(interpolate = false) if (args.nonEmpty) { val tycon = tp.unrefine val cls = tycon.typeSymbol |