From 7ba59b1f8c86bdad79ceed3d21b1fc83bda76d7b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 1 Feb 2014 18:15:14 +0100 Subject: Refactoring implicit discards (1) Moved into refMatches, to avoid normalize on references that are discarded anyway (2) Added another check if the expected type is a value class --- src/dotty/tools/dotc/typer/Implicits.scala | 43 ++++++++++++++++++++++++++-- src/dotty/tools/dotc/typer/Inferencing.scala | 26 +---------------- 2 files changed, 42 insertions(+), 27 deletions(-) (limited to 'src/dotty/tools/dotc/typer') diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index b8908ea34..358f20510 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -43,9 +43,48 @@ object Implicits { /** Return those references in `refs` that are compatible with type `pt`. */ protected def filterMatching(pt: Type)(implicit ctx: Context): List[TermRef] = track("filterMatching") { + def refMatches(ref: TermRef)(implicit ctx: Context) = { - // println(i"refmatches $ref --> ${normalize(ref, pt)}, pt = $pt") - (ref.symbol isAccessibleFrom ref.prefix) && NoViewsAllowed.isCompatible(normalize(ref, pt), pt) + + def discardForView(tpw: Type, argType: Type): Boolean = tpw match { + case tpw: MethodType => + tpw.isImplicit || + tpw.paramTypes.length != 1 || + !(argType <:< tpw.paramTypes.head)(ctx.fresh.withExploreTyperState) + case tpw: PolyType => + discardForView((new WildApprox) apply tpw.resultType, argType) + case tpw: TermRef => + false // can't discard overloaded refs + case tpw => + def isConforms(sym: Symbol) = + sym.exists && sym.owner == defn.ScalaPredefModule.moduleClass && sym.name == tpnme.Conforms + if (isConforms(tpw.typeSymbol)) false // todo: figure out why we need conforms + else { + //if (ctx.typer.isApplicable(tp, argType :: Nil, resultType)) + // println(i"??? $tp is applicable to $this / typeSymbol = ${tpw.typeSymbol}") + true + } + } + + def discardForValueType(tpw: Type): Boolean = tpw match { + case mt: MethodType => !mt.isImplicit + case mt: PolyType => discardForValueType(tpw.resultType) + case _ => false + } + + def discard = pt match { + case pt: ViewProto => discardForView(ref.widen, pt.argType) + case _: ValueType => !defn.isFunctionType(pt) && discardForValueType(ref.widen) + case _ => false + } + + (ref.symbol isAccessibleFrom ref.prefix) && { + if (discard) { + record("discarded eligible") + false + } + else NoViewsAllowed.isCompatible(normalize(ref, pt), pt) + } } if (refs.isEmpty) refs diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 3dff1c728..5ba644b9c 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -209,31 +209,7 @@ object Inferencing { // case _ => false // } def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean = /*ctx.conditionalTraceIndented(lookingForInfo, i"?.info isMatchedBy $tp ${tp.getClass}")*/ { - def discard(tp: Type): Boolean = tp.widen match { - case tpw: MethodType => - tpw.isImplicit || - tpw.paramTypes.length != 1 || - !(argType <:< tpw.paramTypes.head)(ctx.fresh.withExploreTyperState) - case tpw: PolyType => - discard((new WildApprox) apply tpw.resultType) - case tpw: TermRef => - false // can't discard overloaded refs - case tpw => - def isConforms(sym: Symbol) = - sym.exists && sym.owner == defn.ScalaPredefModule.moduleClass && sym.name == tpnme.Conforms - if (isConforms(tpw.typeSymbol)) false // todo: figure out why we need conforms - else { - //if (ctx.typer.isApplicable(tp, argType :: Nil, resultType)) - // println(i"??? $tp is applicable to $this / typeSymbol = ${tpw.typeSymbol}") - true - } - } - - if (discard(tp)) { - Stats.record("discarded eligible") - false - } - else ctx.typer.isApplicable(tp, argType :: Nil, resultType) + ctx.typer.isApplicable(tp, argType :: Nil, resultType) } def derivedViewProto(argType: Type, resultType: Type)(implicit ctx: Context) = -- cgit v1.2.3