summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-11-07 17:37:54 +0000
committerMartin Odersky <odersky@gmail.com>2005-11-07 17:37:54 +0000
commit0f97e0f90df27d39a75b3142c72ad21d20fbdd2c (patch)
treead0221b94c810182009eb69444db895a951daa25 /sources
parenteba1c026d1f43e935864cb93f99f6c5515d90062 (diff)
downloadscala-0f97e0f90df27d39a75b3142c72ad21d20fbdd2c.tar.gz
scala-0f97e0f90df27d39a75b3142c72ad21d20fbdd2c.tar.bz2
scala-0f97e0f90df27d39a75b3142c72ad21d20fbdd2c.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala7
-rwxr-xr-xsources/scala/tools/nsc/transform/Erasure.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala21
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala73
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala3
5 files changed, 79 insertions, 27 deletions
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index a13b809660..d4df21fd0a 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -1472,10 +1472,9 @@ import Flags._;
tps1.isEmpty && tps2.isEmpty
||
!tps1.isEmpty && !tps2.isEmpty &&
- (if (tparams.head.hasFlag(COVARIANT)) tps1.head <:< tps2.head
- else if (tparams.head.hasFlag(CONTRAVARIANT)) tps2.head <:< tps1.head
- else tps1.head =:= tps2.head) &&
- isSubArgs(tps1.tail, tps2.tail, tparams.tail)
+ (tparams.head.hasFlag(COVARIANT) || (tps2.head <:< tps1.head)) &&
+ (tparams.head.hasFlag(CONTRAVARIANT) || tps1.head <:< tps2.head) &&
+ isSubArgs(tps1.tail, tps2.tail, tparams.tail)
}
sym1 == sym2 && (pre1 <:< pre2) &&
isSubArgs(args1, args2, sym1.typeParams)
diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala
index aa3f874d30..5d02e12e04 100755
--- a/sources/scala/tools/nsc/transform/Erasure.scala
+++ b/sources/scala/tools/nsc/transform/Erasure.scala
@@ -407,7 +407,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val member = opc.overriding;
val other = opc.overridden;
//System.out.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString);//DEBUG
- if (!(member hasFlag DEFERRED)) {
+ if (!atPhase(phase.prev)(member hasFlag DEFERRED)) {
val otpe = erasure(other.tpe);
val bridgeNeeded = atPhase(phase.next) {
!(other.tpe =:= member.tpe) &&
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 718b7655b8..7490fc00c6 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -62,13 +62,13 @@ import scala.tools.util.Position;
private var _undetparams: List[Symbol] = List(); // Undetermined type parameters
var depth: int = 0;
var imports: List[ImportInfo] = List();
- var typeSubstFrom: List[Symbol] = List(); // The set of type parameters in scope.
- var typeSubstTo: List[Type] = List(); // Types to which parameters are mapped.
var reportAmbiguousErrors = false;
var reportGeneralErrors = false;
var checking = false;
+ var savedTypeBounds: List[Pair[Symbol, Type]] = List();
+
def undetparams = _undetparams;
def undetparams_=(ps: List[Symbol]) = {
//System.out.println("undetparams = " + ps);//debug
@@ -88,8 +88,6 @@ import scala.tools.util.Position;
c.variance = this.variance;
c.depth = if (scope == this.scope) this.depth else this.depth + 1;
c.imports = imports;
- c.typeSubstFrom = this.typeSubstFrom;
- c.typeSubstTo = this.typeSubstTo;
c.reportAmbiguousErrors = this.reportAmbiguousErrors;
c.reportGeneralErrors = this.reportGeneralErrors;
c.checking = this.checking;
@@ -155,6 +153,9 @@ import scala.tools.util.Position;
case _ => outer.isLocal()
}
+ def nextEnclosing(p: Context => boolean): Context =
+ if (this == NoContext || p(this)) this else outer.nextEnclosing(p);
+
override def toString(): String = {
if (this == NoContext) "NoContext";
else owner.toString() + " @ " + tree.getClass() + " " + tree.toString() + ", scope = " + scope.hashCode() + " " + scope.toList + "\n:: " + outer.toString()
@@ -193,6 +194,18 @@ import scala.tools.util.Position;
(pre.widen.symbol.isSubClass(sym.owner) && isSubClassOfEnclosing(pre.widen.symbol))))
}
+ def pushTypeBounds(sym: Symbol): unit = {
+ savedTypeBounds = Pair(sym, sym.info) :: savedTypeBounds
+ }
+
+ def restoreTypeBounds: unit = {
+ for (val Pair(sym, info) <- savedTypeBounds) {
+ System.out.println("resetting " + sym + " to " + info);
+ sym.setInfo(info);
+ }
+ savedTypeBounds = List()
+ }
+
private var implicitsCache: List[List[ImplicitInfo]] = null;
private var implicitsRun: CompilerRun = NoRun;
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index 173e43cb36..e010c600b5 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -77,6 +77,29 @@ package scala.tools.nsc.typechecker;
List.map2(bounds, targs)((bound, targ) => bound containsType targ) forall (x => x)
}
+ object freeTypeParams extends TypeTraverser {
+ private var result: List[Symbol] = _;
+ private def includeIfAbstract(sym: Symbol): unit = {
+ if (sym.isAbstractType && !result.contains(sym)) result = sym :: result;
+ }
+ override def traverse(tp: Type): TypeTraverser = {
+ tp match {
+ case TypeRef(NoPrefix, sym, _) =>
+ includeIfAbstract(sym)
+ case TypeRef(ThisType(_), sym, _) =>
+ includeIfAbstract(sym)
+ case _ =>
+ }
+ mapOver(tp);
+ this
+ }
+ def collect(tp: Type): List[Symbol] = {
+ result = List();
+ traverse(tp);
+ result
+ }
+ }
+
/** Solve constraint collected in types `tvars'
* @param tvars All type variables to be instantiated.
* @param tparams The type parameters corresponding to `tvars'
@@ -486,27 +509,43 @@ package scala.tools.nsc.typechecker;
" can be instantiated in more than one way to expected type " + pt +
"\n --- because ---\n" + ex.getMessage());
}
-/*
- if (!restpe.subst(undetparams, tvars) <:< pt) {
- map all unbound type params to AnyVal;
- tvars = undetparams map freshVar;
- if (restpe.subst(undetparams, tvars) <:< pt) {
- computeArgs;
- restpe = skipImplicit(tree.tpe.resultType);
- map all unbound type params tparams1 to freshVars tvars1
- val targs1 = solve(tvars1, tparams1, ??, ??);
- checkBounds(tparams1, targs1, "inferred");
- return Pair(tparams, targs) where different
- }
- }
-*/
- if (restpe.subst(undetparams, tvars) <:< pt) {
- computeArgs
- } else {
+ def instError = {
System.out.println("ici " + tree + " " + undetparams + " " + pt);//debug
errorTree(tree, "constructor cannot be instantiated to expected type" +
foundReqMsg(restpe, pt))
}
+ if (restpe.subst(undetparams, tvars) <:< pt) {
+ computeArgs
+ } else if (isFullyDefined(pt)) {
+ System.out.println("infer constr " + tree + ":" + restpe + ", pt = " + pt);//debug
+ val ptparams = freeTypeParams.collect(pt);
+ System.out.println("free type params = " + ptparams);//debug
+ val ptWithWildcards = pt.subst(ptparams, ptparams map (ptparam => WildcardType));
+ tvars = undetparams map freshVar;
+ if (restpe.subst(undetparams, tvars) <:< ptWithWildcards) {
+ computeArgs;
+ restpe = skipImplicit(tree.tpe.resultType);
+ System.out.println("new tree = " + tree + ":" + restpe);//debug
+ val ptvars = ptparams map freshVar;
+ if (restpe <:< pt.subst(ptparams, ptvars)) {
+ for (val tvar <- ptvars) {
+ val tparam = tvar.origin.symbol;
+ val Pair(loBounds, hiBounds) =
+ if (tvar.constr.inst != NoType && isFullyDefined(tvar.constr.inst))
+ Pair(List(tvar.constr.inst), List(tvar.constr.inst))
+ else
+ Pair(tvar.constr.lobounds, tvar.constr.hibounds);
+ if (!loBounds.isEmpty || !hiBounds.isEmpty) {
+ context.nextEnclosing(.tree.isInstanceOf[CaseDef]).pushTypeBounds(tparam);
+ tparam setInfo TypeBounds(
+ lub(tparam.info.bounds.lo :: loBounds),
+ glb(tparam.info.bounds.hi :: hiBounds));
+ System.out.println("new bounds of " + tparam + " = " + tparam.info);//debug
+ }
+ }
+ } else { System.out.println("no instance: "); instError }
+ } else { System.out.println("not a subtype " + restpe.subst(undetparams, tvars) + " of " + ptWithWildcards); instError }
+ } else { System.out.println("not fuly defined: " + pt); instError }
}
/* -- Overload Resolution ----------------------------------------------------------- */
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 6a29c53241..8cddbef7fb 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -722,12 +722,13 @@ import collection.mutable.HashMap;
val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree
else typed(cdef.guard, BooleanClass.tpe);
val body1: Tree = typed(cdef.body, pt);
+ context.restoreTypeBounds;
copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
def typedCases(tree: Tree, cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] = {
List.mapConserve(cases)(cdef =>
- newTyper(context.makeNewScope(tree, context.owner)).typedCase(cdef, pattp, pt))
+ newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt))
}
def typedFunction(fun: Function, mode: int, pt: Type): Tree = {