aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Implicits.scala
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/typer/Implicits.scala
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/typer/Implicits.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala43
1 files changed, 41 insertions, 2 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