From 1f4f1235920fe87e1b1bdfd042683d9651f1d4f1 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 31 Jan 2012 11:02:43 -0800 Subject: Optimizations. Do cheap tests like x.isImplicit before expensive tests like matchesQuantified. Don't fail to notice that substSym has been called with an empty "from" list and traverse everything anyway. --- src/compiler/scala/reflect/internal/Symbols.scala | 7 +++++-- src/compiler/scala/reflect/internal/Types.scala | 15 +++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 77ed2f6a1b..b3ff2c6329 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1023,8 +1023,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Modifies this symbol's info in place. */ def modifyInfo(f: Type => Type): this.type = setInfo(f(info)) /** Substitute second list of symbols for first in current info. */ - def substInfo(syms0: List[Symbol], syms1: List[Symbol]) = modifyInfo(_.substSym(syms0, syms1)) - def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this) + def substInfo(syms0: List[Symbol], syms1: List[Symbol]): this.type = + if (syms0.isEmpty) this + else modifyInfo(_.substSym(syms0, syms1)) + + def setInfoOwnerAdjusted(info: Type): this.type = setInfo(info atOwner this) /** Set the info and enter this symbol into the owner's scope. */ def setInfoAndEnter(info: Type): this.type = { diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index adf9df185a..04efe04636 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -680,7 +680,7 @@ trait Types extends api.Types { self: SymbolTable => * symbol. */ def substSym(from: List[Symbol], to: List[Symbol]): Type = - if (from eq to) this + if ((from eq to) || from.isEmpty) this else new SubstSymMap(from, to) apply this /** Substitute all occurrences of `ThisType(from)` in this type by `to`. @@ -5381,9 +5381,9 @@ trait Types extends api.Types { self: SymbolTable => val params2 = mt2.params val res2 = mt2.resultType (sameLength(params1, params2) && + mt1.isImplicit == mt2.isImplicit && matchingParams(params1, params2, mt1.isJava, mt2.isJava) && - (res1 <:< res2.substSym(params2, params1)) && - mt1.isImplicit == mt2.isImplicit) + (res1 <:< res2.substSym(params2, params1))) // TODO: if mt1.params.isEmpty, consider NullaryMethodType? case _ => false @@ -5503,9 +5503,9 @@ trait Types extends api.Types { self: SymbolTable => tp2 match { case mt2 @ MethodType(params2, res2) => // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performancewise?) - matchesQuantified(params1, params2, res1, res2) && + mt1.isImplicit == mt2.isImplicit && matchingParams(params1, params2, mt1.isJava, mt2.isJava) && - mt1.isImplicit == mt2.isImplicit + matchesQuantified(params1, params2, res1, res2) case NullaryMethodType(res2) => if (params1.isEmpty) matchesType(res1, res2, alwaysMatchSimple) else matchesType(tp1, res2, alwaysMatchSimple) @@ -5532,7 +5532,10 @@ trait Types extends api.Types { self: SymbolTable => case PolyType(tparams1, res1) => tp2 match { case PolyType(tparams2, res2) => - matchesQuantified(tparams1, tparams2, res1, res2) + if ((tparams1 corresponds tparams2)(_ eq _)) + matchesType(res1, res2, alwaysMatchSimple) + else + matchesQuantified(tparams1, tparams2, res1, res2) case ExistentialType(_, res2) => alwaysMatchSimple && matchesType(tp1, res2, true) case _ => -- cgit v1.2.3