@@ -35,12 +35,21 @@ object ProtoTypes {
3535 def isCompatible (tp : Type , pt : Type )(implicit ctx : Context ): Boolean =
3636 (tp.widenExpr relaxed_<:< pt.widenExpr) || viewExists(tp, pt)
3737
38- /** Test compatibility after normalization in a fresh typerstate. */
39- def normalizedCompatible (tp : Type , pt : Type )(implicit ctx : Context ): Boolean =
40- ctx.test { implicit ctx =>
38+ /** Test compatibility after normalization.
39+ * Do this in a fresh typerstate unless `keepConstraint` is true.
40+ */
41+ def normalizedCompatible (tp : Type , pt : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
42+ def testCompat (implicit ctx : Context ): Boolean = {
4143 val normTp = normalize(tp, pt)
4244 isCompatible(normTp, pt) || pt.isRef(defn.UnitClass ) && normTp.isParameterless
4345 }
46+ if (keepConstraint && false )
47+ tp.widenSingleton match {
48+ case poly : PolyType => normalizedCompatible(tp, pt, keepConstraint = false )
49+ case _ => testCompat
50+ }
51+ else ctx.test(implicit ctx => testCompat)
52+ }
4453
4554 private def disregardProto (pt : Type )(implicit ctx : Context ): Boolean = pt.dealias match {
4655 case _ : OrType => true
@@ -89,7 +98,7 @@ object ProtoTypes {
8998
9099 /** A trait for prototypes that match all types */
91100 trait MatchAlways extends ProtoType {
92- def isMatchedBy (tp1 : Type )(implicit ctx : Context ): Boolean = true
101+ def isMatchedBy (tp1 : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = true
93102 def map (tm : TypeMap )(implicit ctx : Context ): ProtoType = this
94103 def fold [T ](x : T , ta : TypeAccumulator [T ])(implicit ctx : Context ): T = x
95104 override def toString : String = getClass.toString
@@ -131,13 +140,13 @@ object ProtoTypes {
131140 case _ => false
132141 }
133142
134- override def isMatchedBy (tp1 : Type )(implicit ctx : Context ): Boolean = {
143+ override def isMatchedBy (tp1 : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
135144 name == nme.WILDCARD || hasUnknownMembers(tp1) ||
136145 {
137146 val mbr = if (privateOK) tp1.member(name) else tp1.nonPrivateMember(name)
138147 def qualifies (m : SingleDenotation ) =
139148 memberProto.isRef(defn.UnitClass ) ||
140- tp1.isValueType && compat.normalizedCompatible(NamedType (tp1, name, m), memberProto)
149+ tp1.isValueType && compat.normalizedCompatible(NamedType (tp1, name, m), memberProto, keepConstraint )
141150 // Note: can't use `m.info` here because if `m` is a method, `m.info`
142151 // loses knowledge about `m`'s default arguments.
143152 mbr match { // hasAltWith inlined for performance
@@ -234,8 +243,8 @@ object ProtoTypes {
234243 extends UncachedGroundType with ApplyingProto with FunOrPolyProto {
235244 override def resultType (implicit ctx : Context ): Type = resType
236245
237- def isMatchedBy (tp : Type )(implicit ctx : Context ): Boolean =
238- typer.isApplicable(tp, Nil , unforcedTypedArgs, resultType)
246+ def isMatchedBy (tp : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean =
247+ typer.isApplicable(tp, Nil , unforcedTypedArgs, resultType, keepConstraint )
239248
240249 def derivedFunProto (args : List [untpd.Tree ] = this .args, resultType : Type , typer : Typer = this .typer): FunProto =
241250 if ((args eq this .args) && (resultType eq this .resultType) && (typer eq this .typer)) this
@@ -379,7 +388,7 @@ object ProtoTypes {
379388
380389 override def resultType (implicit ctx : Context ): Type = resType
381390
382- def isMatchedBy (tp : Type )(implicit ctx : Context ): Boolean =
391+ def isMatchedBy (tp : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean =
383392 ctx.typer.isApplicable(tp, argType :: Nil , resultType) || {
384393 resType match {
385394 case SelectionProto (name : TermName , mbrType, _, _) =>
@@ -422,7 +431,7 @@ object ProtoTypes {
422431
423432 override def resultType (implicit ctx : Context ): Type = resType
424433
425- override def isMatchedBy (tp : Type )(implicit ctx : Context ): Boolean = {
434+ override def isMatchedBy (tp : Type , keepConstraint : Boolean )(implicit ctx : Context ): Boolean = {
426435 def isInstantiatable (tp : Type ) = tp.widen match {
427436 case tp : PolyType => tp.paramNames.length == targs.length
428437 case _ => false
0 commit comments