summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-04-13 15:46:40 -0700
committerMartin Odersky <odersky@gmail.com>2012-04-13 15:47:08 -0700
commit3324a7215c87c61791f3e4afb49bc63cf9c80f12 (patch)
treed28ec7c6ae615dc32cdb925f486bb0157662f110 /src/compiler
parent7f2624e2ee57d10ff39452164899937dc799e8b1 (diff)
downloadscala-3324a7215c87c61791f3e4afb49bc63cf9c80f12.tar.gz
scala-3324a7215c87c61791f3e4afb49bc63cf9c80f12.tar.bz2
scala-3324a7215c87c61791f3e4afb49bc63cf9c80f12.zip
Fine-tuning of isRepresentableWithWildcards and wildcard printing.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala41
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
2 files changed, 22 insertions, 21 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index c13a33a6fc..b3d425f0c5 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2517,34 +2517,35 @@ trait Types extends api.Types { self: SymbolTable =>
override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying)
- private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
- case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
- ("_"+sym.infoString(sym.info)) :: wildcardArgsString(available - sym, args1)
- case arg :: args1 if !(quantified exists (arg contains _)) =>
- arg.toString :: wildcardArgsString(available, args1)
- case _ =>
- List()
+ private def wildcardArgsString(qset: Set[Symbol], args: List[Type]): List[String] = args map {
+ case TypeRef(_, sym, _) if (qset contains sym) =>
+ "_"+sym.infoString(sym.info)
+ case arg =>
+ arg.toString
}
+
/** An existential can only be printed with wildcards if:
* - the underlying type is a typeref
- * - where there is a 1-to-1 correspondence between underlying's typeargs and quantified
- * - and none of the existential parameters is referenced from anywhere else in the type
- * - and none of the existential parameters are singleton types
- * - @param checkBounds if set returns false for situations like
- * (S, T) forSome { type S; type T <: S }
- * If not set returns true. The reason for this mode is to
- * avoid cyclic reference errors when the method is called
- * early (e.g. from Typers # checkExistentialsFeature)
+ * - every quantified variable appears at most once as a type argument and
+ * nowhere inside a type argument
+ * - no quantified type argument contains a quantified variable in its bound
+ * - the typeref's symbol is not itself quantified
+ * - the prefix is not quanitified
*/
- def isRepresentableWithWildcards(checkBounds: Boolean) = {
+ def isRepresentableWithWildcards = {
val qset = quantified.toSet
underlying match {
- case TypeRef(_, sym, args) =>
- def isQuantified(tpe: Type) = tpe exists (t => quantified contains t.typeSymbol)
+ case TypeRef(pre, sym, args) =>
+ def isQuantified(tpe: Type): Boolean = {
+ (tpe exists (t => qset contains t.typeSymbol)) ||
+ tpe.typeSymbol.isRefinementClass && (tpe.parents exists isQuantified)
+ }
val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol)
wildcardArgs.distinct == wildcardArgs &&
!(otherArgs exists (arg => isQuantified(arg))) &&
- !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds)))
+ !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) &&
+ !(qset contains sym) &&
+ !isQuantified(pre)
case _ => false
}
}
@@ -2555,7 +2556,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (settings.explaintypes.value) "(" + str + ")" else str
}
underlying match {
- case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards(checkBounds = true) =>
+ case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards =>
"" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]")
case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) =>
"(" + underlying + ")" + clauses
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 1425cd4755..9431c6f5e5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -761,7 +761,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def checkExistentialsFeature(pos: Position, tpe: Type, prefix: String) = tpe match {
- case extp: ExistentialType if !extp.isRepresentableWithWildcards(checkBounds = false) =>
+ case extp: ExistentialType if !extp.isRepresentableWithWildcards =>
checkFeature(pos, ExistentialsFeature, prefix+" "+tpe)
case _ =>
}