From 42dc44dd5235cbe30bc52dcaa360bdccb50b87cd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 7 Oct 2006 16:08:21 +0000 Subject: more changes towards wildcards --- src/compiler/scala/tools/nsc/symtab/Types.scala | 27 ++++++++++++++-------- .../scala/tools/nsc/typechecker/RefChecks.scala | 6 ++--- .../scala/tools/nsc/typechecker/Typers.scala | 1 + 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 56f332689d..00a3c5bfb9 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -278,6 +278,11 @@ trait Types requires SymbolTable { else isSameType(this, that)) ); + /** Does this type contain that type? This is true if the two types are the same wrt <:<, + * or this type is a TypeBounds which contains that type + */ + def containsType(that: Type) = this <:< that && that <:< this + /** Does this type implement symbol sym with same or stronger type? */ def specializes(sym: Symbol): boolean = @@ -546,7 +551,7 @@ trait Types requires SymbolTable { } case class BoundedWildcardType(override val bounds: TypeBounds) extends Type { - override def toString(): String = "_" + bounds + override def toString(): String = "? " + bounds.boundsString } /** An object representing a non-existing type */ @@ -645,7 +650,7 @@ trait Types requires SymbolTable { override val isTrivial: boolean = lo.isTrivial && hi.isTrivial def supertype: Type = hi override def bounds: TypeBounds = this - def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi; + override def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi // override def isNullable: boolean = AllRefClass.tpe <:< lo; override def toString = "_ "+boundsString def boundsString = ">: "+lo+" <: "+ hi @@ -1102,7 +1107,7 @@ trait Types requires SymbolTable { /** A creator of type approximations, depending on variance */ def typeApproximation(variance: int, lo: Type, hi: Type, pre: Type, sym: Symbol) = variance match { - case 0 => BoundedWildcardType(TypeBounds(lo, hi)) + case 0 => TypeBounds(lo, hi) case 1 => hi case -1 => lo case NOAPPROX => throw new MalformedType(pre, sym.name.toString) @@ -1843,14 +1848,14 @@ trait Types requires SymbolTable { case Pair(TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) => //System.out.println("isSubType " + tp1 + " " + tp2);//DEBUG def isSubArgs(tps1: List[Type], tps2: List[Type], - tparams: List[Symbol]): boolean = ( - tps1.isEmpty && tps2.isEmpty - || + tparams: List[Symbol]): boolean = + tps1.isEmpty && tps2.isEmpty || !tps1.isEmpty && !tps2.isEmpty && - (tparams.head.isCovariant || (tps2.head <:< tps1.head)) && - (tparams.head.isContravariant || (tps1.head <:< tps2.head)) && + (if (tparams.head.isCovariant) tps1.head <:< tps2.head + else if (tparams.head.isContravariant) tps2.head <:< tps1.head + else tps2.head containsType tps1.head) && isSubArgs(tps1.tail, tps2.tail, tparams.tail) - ); + (sym1 == sym2 && (phase.erasedTypes || pre1 <:< pre2) && isSubArgs(args1, args2, sym1.typeParams) @@ -1880,6 +1885,10 @@ trait Types requires SymbolTable { res1 <:< res2.substSym(tparams2, tparams1)) case Pair(TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) => lo2 <:< lo1 && hi1 <:< hi2 + case Pair(TypeBounds(lo1, hi1), _) => + lo1 <:< tp2 && hi1 <:< tp2 + case Pair(_, TypeBounds(lo2, hi2)) => + lo2.symbol == AllClass && tp1 <:< hi2 case Pair(BoundedWildcardType(bounds), _) => bounds.lo <:< tp2 case Pair(_, BoundedWildcardType(bounds)) => diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 51872a5ab1..b2815eeddd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -92,9 +92,9 @@ abstract class RefChecks extends InfoTransform { sym1.toString() + (if (sym1.owner == clazz) "" else (sym1.locationString + - (if (sym1.isAliasType) ", which equals " + self.memberInfo(sym1) - else if (sym1.isAbstractType) " with bounds " + self.memberInfo(sym1) - else if (sym1.isTerm) " of type " + self.memberInfo(sym1) + (if (sym1.isAliasType) ", which equals "+self.memberInfo(sym1) + else if (sym1.isAbstractType) " with bounds "+self.memberInfo(sym1).bounds.boundsString + else if (sym1.isTerm) " of type "+self.memberInfo(sym1) else ""))) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d8c35441b2..f26970e453 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5,6 +5,7 @@ // $Id$ //todo: rewrite or disllow new T where T is a mixin (currently: not a member of T) +//todo: use inherited type info also for vars and values package scala.tools.nsc.typechecker import scala.collection.mutable.{HashMap, ListBuffer} -- cgit v1.2.3