summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-10-16 14:43:22 +0000
committerMartin Odersky <odersky@gmail.com>2010-10-16 14:43:22 +0000
commitde2fb8466ebf0fa221e56a1a5db8537676cd7d97 (patch)
tree14f8753649b3996c646beed60a6e080692396467 /src
parent30872339677177693b988f31fae5fe660289b3e2 (diff)
downloadscala-de2fb8466ebf0fa221e56a1a5db8537676cd7d97.tar.gz
scala-de2fb8466ebf0fa221e56a1a5db8537676cd7d97.tar.bz2
scala-de2fb8466ebf0fa221e56a1a5db8537676cd7d97.zip
Closes #3833. Review by extempore.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala63
1 files changed, 39 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index abe9569346..0fe6284e6b 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -4925,7 +4925,7 @@ A type's typeSymbol should never be inspected directly.
else {
val ts0 = tss map (_.head)
val sym = minSym(ts0)
- if (ts0 forall (t => t.typeSymbol == sym))
+ if (ts0 forall (_.typeSymbol == sym))
mergePrefixAndArgs(elimSub(ts0, depth), 1, depth).toList ::: lubList(tss map (_.tail), depth)
else
lubList(tss map (ts => if (ts.head.typeSymbol == sym) ts.tail else ts), depth)
@@ -5009,7 +5009,7 @@ A type's typeSymbol should never be inspected directly.
else abort("trying to do lub/glb of typevar "+tp)
case t => t
}
- val strippedTypes = ts mapConserve (stripType)
+ val strippedTypes = ts mapConserve stripType
(strippedTypes, quantified)
}
@@ -5336,30 +5336,45 @@ A type's typeSymbol should never be inspected directly.
val argss = tps map (_.normalize.typeArgs) // symbol equality (of the tp in tps) was checked using typeSymbol, which normalizes, so should normalize before retrieving arguments
val capturedParams = new ListBuffer[Symbol]
try {
- val args = (sym.typeParams, argss.transpose).zipped map {
- (tparam, as) =>
- if (depth == 0)
- if (tparam.variance == variance) AnyClass.tpe
- else if (tparam.variance == -variance) NothingClass.tpe
- else NoType
- else
- if (tparam.variance == variance) lub(as, decr(depth))
- else if (tparam.variance == -variance) glb(as, decr(depth))
- else {
- val l = lub(as, decr(depth))
- val g = glb(as, decr(depth))
- if (l <:< g) l
- else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we
- // just err on the conservative side, i.e. with a bound that is too high.
- // if(!(tparam.info.bounds contains tparam)){ //@M can't deal with f-bounds, see #2251
- val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l)
- capturedParams += qvar
- qvar.tpe
+ if (sym == ArrayClass && phase.erasedTypes) {
+ // special treatment for lubs of array types after erasure:
+ // if argss contain one value type and some other type, the lub is Object
+ // if argss contain several reference types, the lub is an array over lub of argtypes
+ if (argss exists (_.isEmpty)) {
+ None // something is wrong: an array without a type arg.
+ } else {
+ val args = argss map (_.head)
+ if (args.tail forall (_ =:= args.head)) Some(TypeRef(pre, sym, List(args.head)))
+ else if (args exists (arg => isValueClass(arg.typeSymbol))) Some(ObjectClass.tpe)
+ else Some(TypeRef(pre, sym, List(lub(args))))
+ }
+ } else {
+ val args = (sym.typeParams, argss.transpose).zipped map {
+ (tparam, as) =>
+ if (depth == 0)
+ if (tparam.variance == variance) AnyClass.tpe
+ else if (tparam.variance == -variance) NothingClass.tpe
+ else NoType
+ else
+ if (tparam.variance == variance) lub(as, decr(depth))
+ else if (tparam.variance == -variance) glb(as, decr(depth))
+ else {
+ val l = lub(as, decr(depth))
+ val g = glb(as, decr(depth))
+ if (l <:< g) l
+ else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we
+ // just err on the conservative side, i.e. with a bound that is too high.
+ // if(!(tparam.info.bounds contains tparam)){ //@M can't deal with f-bounds, see #2251
+
+ val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l)
+ capturedParams += qvar
+ qvar.tpe
+ }
}
- }
+ }
+ if (args contains NoType) None
+ else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args)))
}
- if (args contains NoType) None
- else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args)))
} catch {
case ex: MalformedType => None
case ex: IndexOutOfBoundsException => // transpose freaked out because of irregular argss