@@ -285,6 +285,21 @@ object SpaceEngine {
285285 isEmptyTp <:< ConstantType (Constant (true ))
286286 }
287287 }
288+
289+ /** Is the unapplySeq irrefutable?
290+ * @param unapp The unapplySeq function reference
291+ */
292+ def isIrrefutableUnapplySeq (unapp : tpd.Tree , patSize : Int )(implicit ctx : Context ): Boolean = {
293+ val unappResult = unapp.tpe.widen.finalResultType
294+ unappResult.isRef(defn.SomeClass ) ||
295+ (unapp.symbol.is(Synthetic ) && unapp.symbol.owner.linkedClass.is(Case )) || // scala2 compatibility
296+ unapplySeqTypeElemTp(unappResult).exists ||
297+ isProductSeqMatch(unappResult, patSize) ||
298+ {
299+ val isEmptyTp = extractorMemberType(unappResult, nme.isEmpty, unapp.sourcePos)
300+ isEmptyTp <:< ConstantType (Constant (true ))
301+ }
302+ }
288303}
289304
290305/** Scala implementation of space logic */
@@ -351,9 +366,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
351366 else {
352367 val (arity, elemTp, resultTp) = unapplySeqInfo(fun.tpe.widen.finalResultType, fun.sourcePos)
353368 if (elemTp.exists)
354- Prod (erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, projectSeq(pats) :: Nil , isIrrefutableUnapply (fun, - 1 ))
369+ Prod (erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, projectSeq(pats) :: Nil , isIrrefutableUnapplySeq (fun, pats.size ))
355370 else
356- Prod (erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.take(arity - 1 ).map(project) :+ projectSeq(pats.drop(arity - 1 )), full = true )
371+ Prod (erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.take(arity - 1 ).map(project) :+ projectSeq(pats.drop(arity - 1 )), isIrrefutableUnapplySeq(fun, pats.size) )
357372 }
358373 else
359374 Prod (erase(pat.tpe.stripAnnots), erase(fun.tpe), fun.symbol, pats.map(project), isIrrefutableUnapply(fun, pats.length))
0 commit comments