@@ -43,9 +43,48 @@ object Implicits {
4343
4444 /** Return those references in `refs` that are compatible with type `pt`. */
4545 protected def filterMatching (pt : Type )(implicit ctx : Context ): List [TermRef ] = track(" filterMatching" ) {
46+
4647 def refMatches (ref : TermRef )(implicit ctx : Context ) = {
47- // println(i"refmatches $ref --> ${normalize(ref, pt)}, pt = $pt")
48- (ref.symbol isAccessibleFrom ref.prefix) && NoViewsAllowed .isCompatible(normalize(ref, pt), pt)
48+
49+ def discardForView (tpw : Type , argType : Type ): Boolean = tpw match {
50+ case tpw : MethodType =>
51+ tpw.isImplicit ||
52+ tpw.paramTypes.length != 1 ||
53+ ! (argType <:< tpw.paramTypes.head)(ctx.fresh.withExploreTyperState)
54+ case tpw : PolyType =>
55+ discardForView((new WildApprox ) apply tpw.resultType, argType)
56+ case tpw : TermRef =>
57+ false // can't discard overloaded refs
58+ case tpw =>
59+ def isConforms (sym : Symbol ) =
60+ sym.exists && sym.owner == defn.ScalaPredefModule .moduleClass && sym.name == tpnme.Conforms
61+ if (isConforms(tpw.typeSymbol)) false // todo: figure out why we need conforms
62+ else {
63+ // if (ctx.typer.isApplicable(tp, argType :: Nil, resultType))
64+ // println(i"??? $tp is applicable to $this / typeSymbol = ${tpw.typeSymbol}")
65+ true
66+ }
67+ }
68+
69+ def discardForValueType (tpw : Type ): Boolean = tpw match {
70+ case mt : MethodType => ! mt.isImplicit
71+ case mt : PolyType => discardForValueType(tpw.resultType)
72+ case _ => false
73+ }
74+
75+ def discard = pt match {
76+ case pt : ViewProto => discardForView(ref.widen, pt.argType)
77+ case _ : ValueType => ! defn.isFunctionType(pt) && discardForValueType(ref.widen)
78+ case _ => false
79+ }
80+
81+ (ref.symbol isAccessibleFrom ref.prefix) && {
82+ if (discard) {
83+ record(" discarded eligible" )
84+ false
85+ }
86+ else NoViewsAllowed .isCompatible(normalize(ref, pt), pt)
87+ }
4988 }
5089
5190 if (refs.isEmpty) refs
0 commit comments