aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-02-01 18:15:14 +0100
committerMartin Odersky <odersky@gmail.com>2014-02-01 18:15:14 +0100
commit7ba59b1f8c86bdad79ceed3d21b1fc83bda76d7b (patch)
tree6129635f5375b296bd6fbe71e55644f8eedf342e /src/dotty/tools/dotc
parentceb4dd9589da30540d2ab812f5ca90298aa4b070 (diff)
downloaddotty-7ba59b1f8c86bdad79ceed3d21b1fc83bda76d7b.tar.gz
dotty-7ba59b1f8c86bdad79ceed3d21b1fc83bda76d7b.tar.bz2
dotty-7ba59b1f8c86bdad79ceed3d21b1fc83bda76d7b.zip
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
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala43
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala26
2 files changed, 42 insertions, 27 deletions
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) =