summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-10-01 14:26:56 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-10-01 14:26:56 +0000
commitfe264943efccc2534a65ce0b49ed16a51e597aed (patch)
treea30ac4abd80845b04e13f7a61bcdffec18ead7b1 /src
parent082a427ff9572e002bb1fc5c71e129e857f0aa81 (diff)
downloadscala-fe264943efccc2534a65ce0b49ed16a51e597aed.tar.gz
scala-fe264943efccc2534a65ce0b49ed16a51e597aed.tar.bz2
scala-fe264943efccc2534a65ce0b49ed16a51e597aed.zip
fixed #2101
there were some issues with heap pressure that made the compile take incredibly long, these were solved by increasing the max allowed heap
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 8bf9708c0c..0ebd2018fb 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -4005,10 +4005,29 @@ A type's typeSymbol should never be inspected directly.
(res1 <:< res2) &&
tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType])
case (PolyType(tparams1, res1), PolyType(tparams2, res2)) =>
- (tparams1.length == tparams2.length &&
- List.forall2(tparams1, tparams2)
- ((p1, p2) => p2.info.substSym(tparams2, tparams1) <:< p1.info) &&
- res1 <:< res2.substSym(tparams2, tparams1))
+ tparams1.length == tparams2.length && {
+ if(tparams1.isEmpty) res1 <:< res2 // fast-path: monomorphic nullary method type
+ else if(tparams1.head.owner.isMethod) { // fast-path: polymorphic method type -- type params cannot be captured
+ List.forall2(tparams1, tparams2)((p1, p2) =>
+ p2.info.substSym(tparams2, tparams1) <:< p1.info) &&
+ res1 <:< res2.substSym(tparams2, tparams1)
+ } else { // normalized higher-kinded type
+ //@M for an example of why we need to generate fresh symbols, see neg/tcpoly_ticket2101.scala
+ val tpsFresh = cloneSymbols(tparams1) // @M cloneSymbols(tparams2) should be equivalent -- TODO: check
+
+ (List.forall2(tparams1, tparams2)((p1, p2) =>
+ p2.info.substSym(tparams2, tpsFresh) <:< p1.info.substSym(tparams1, tpsFresh)) &&
+ res1.substSym(tparams1, tpsFresh) <:< res2.substSym(tparams2, tpsFresh))
+
+ //@M the forall in the previous test could be optimised to the following,
+ // but not worth the extra complexity since it only shaves 1s from quick.comp
+ // (List.forall2(tpsFresh/*optimisation*/, tparams2)((p1, p2) =>
+ // p2.info.substSym(tparams2, tpsFresh) <:< p1.info /*optimisation, == (p1 from tparams1).info.substSym(tparams1, tpsFresh)*/) &&
+ // this optimisation holds because inlining cloneSymbols in `val tpsFresh = cloneSymbols(tparams1)` gives:
+ // val tpsFresh = tparams1 map (_.cloneSymbol)
+ // for (tpFresh <- tpsFresh) tpFresh.setInfo(tpFresh.info.substSym(tparams1, tpsFresh))
+ }
+ }
case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) =>
lo2 <:< lo1 && hi1 <:< hi2
case (AnnotatedType(_,_,_), _) =>