@@ -108,7 +108,7 @@ trait SpaceLogic {
108108 def decompose (tp : Type ): List [Typ ]
109109
110110 /** Whether the extractor covers the given type */
111- def covers (unapp : TermRef , scrutineeTp : Type ): Boolean
111+ def covers (unapp : TermRef , scrutineeTp : Type , argLen : Int ): Boolean
112112
113113 /** Display space in string format */
114114 def show (sp : Space ): String
@@ -186,7 +186,7 @@ trait SpaceLogic {
186186 isSubType(tp1, tp2)
187187 case (Typ (tp1, _), Prod (tp2, fun, ss)) =>
188188 isSubType(tp1, tp2)
189- && covers(fun, tp1)
189+ && covers(fun, tp1, ss.length )
190190 && isSubspace(Prod (tp2, fun, signature(fun, tp2, ss.length).map(Typ (_, false ))), b)
191191 case (Prod (_, fun1, ss1), Prod (_, fun2, ss2)) =>
192192 isSameUnapply(fun1, fun2) && ss1.zip(ss2).forall((isSubspace _).tupled)
@@ -240,7 +240,7 @@ trait SpaceLogic {
240240 else a
241241 case (Typ (tp1, _), Prod (tp2, fun, ss)) =>
242242 // rationale: every instance of `tp1` is covered by `tp2(_)`
243- if isSubType(tp1, tp2) && covers(fun, tp1) then
243+ if isSubType(tp1, tp2) && covers(fun, tp1, ss.length ) then
244244 minus(Prod (tp1, fun, signature(fun, tp1, ss.length).map(Typ (_, false ))), b)
245245 else if canDecompose(tp1) then
246246 tryDecompose1(tp1)
@@ -262,6 +262,7 @@ trait SpaceLogic {
262262 a
263263 case (Prod (tp1, fun1, ss1), Prod (tp2, fun2, ss2)) =>
264264 if (! isSameUnapply(fun1, fun2)) return a
265+ if (fun1.symbol.name == nme.unapply && ss1.length != ss2.length) return a
265266
266267 val range = (0 until ss1.size).toList
267268 val cache = Array .fill[Space ](ss2.length)(null )
@@ -288,13 +289,13 @@ object SpaceEngine {
288289 /** Is the unapply or unapplySeq irrefutable?
289290 * @param unapp The unapply function reference
290291 */
291- def isIrrefutable (unapp : TermRef )(using Context ): Boolean = {
292+ def isIrrefutable (unapp : TermRef , argLen : Int )(using Context ): Boolean = {
292293 val unappResult = unapp.widen.finalResultType
293294 unappResult.isRef(defn.SomeClass )
294295 || unappResult <:< ConstantType (Constant (true )) // only for unapply
295296 || (unapp.symbol.is(Synthetic ) && unapp.symbol.owner.linkedClass.is(Case )) // scala2 compatibility
296297 || unapplySeqTypeElemTp(unappResult).exists // only for unapplySeq
297- || productArity (unappResult) > 0
298+ || isProductMatch (unappResult, argLen)
298299 || {
299300 val isEmptyTp = extractorMemberType(unappResult, nme.isEmpty, NoSourcePosition )
300301 isEmptyTp <:< ConstantType (Constant (false ))
@@ -304,10 +305,10 @@ object SpaceEngine {
304305 /** Is the unapply or unapplySeq irrefutable?
305306 * @param unapp The unapply function tree
306307 */
307- def isIrrefutable (unapp : tpd.Tree )(using Context ): Boolean = {
308+ def isIrrefutable (unapp : tpd.Tree , argLen : Int )(using Context ): Boolean = {
308309 val fun1 = tpd.funPart(unapp)
309310 val funRef = fun1.tpe.asInstanceOf [TermRef ]
310- isIrrefutable(funRef)
311+ isIrrefutable(funRef, argLen )
311312 }
312313}
313314
@@ -606,8 +607,8 @@ class SpaceEngine(using Context) extends SpaceLogic {
606607 }
607608
608609 /** Whether the extractor covers the given type */
609- def covers (unapp : TermRef , scrutineeTp : Type ): Boolean =
610- SpaceEngine .isIrrefutable(unapp) || unapp.symbol == defn.TypeTest_unapply && {
610+ def covers (unapp : TermRef , scrutineeTp : Type , argLen : Int ): Boolean =
611+ SpaceEngine .isIrrefutable(unapp, argLen ) || unapp.symbol == defn.TypeTest_unapply && {
611612 val AppliedType (_, _ :: tp :: Nil ) = unapp.prefix.widen.dealias
612613 scrutineeTp <:< tp
613614 }
0 commit comments