New `F-unwrapping` example would not work in Scala 3.4+
The example from release notes 0.2.3 and the first test case https://github.com/arainko/ducktape/blob/54d7942a0bc5a4fc310fd7bfdf129d7ff7528155/ducktape/src/test/scala/io/github/arainko/ducktape/fallible/FUnwrappingSuite.scala#L10-L25 would not work in Scala 3.4 and it's changes to better specification and less unsoundness in match types I would fail with the following error:
[error] -- [E191] Type Error: /Users/wmazur/projects/community-build3/repo/ducktape/src/test/scala/io/github/arainko/ducktape/fallible/FUnwrappingSuite.scala:21:37
[error] 21 | val actual = source.fallibleTo[Tuple.InverseMap[source.type, mode.Self]]
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error] | The match type contains an illegal case:
[error] | case mode.Self[x] *: t => x *: Tuple.InverseMap[t, mode.Self]
[error] | The pattern contains a type alias `Self`.
[error] | (this error can be ignored for now with `-source:3.3`)
Hmm, that's disappointing - would it work with import language.betterMatchExtractors? Since Mode#Self is just a typealias I'd expect it to be alright (citation needed 😄 )
I've made a quick check and yes, it works with import scala.language.experimental.betterMatchTypeExtractors the only issue is that it's an experimental feature currently.
Guess, we need to wait till it's stabilized https://github.com/scala/improvement-proposals/pull/84
That's alright then, as long as that gets stabilized in time for the next LTS we're alright, it's just going to need a couple of warnings in the docs.
Thanks for looking out!
So I did some testing and it's pretty weird:
//> using scala 3.5.0
//> using options "-experimental"
trait Test[F[_]] {
final type Self[A] = F[A]
}
object Test {
inline def current(using T: Test[?]): T.type = T
trait Opt extends Test[Option]
trait Either[E] extends Test[[a] =>> scala.Either[E, a]]
}
object testing {
locally {
given Test.Opt()
val tup = (Some(1), Some(2), Some(3))
// compiles just fine with no `scala.language.experimental.betterMatchTypeExtractors`
val d: Tuple.InverseMap[tup.type, Test.current.Self] = ???
}
locally {
import scala.language.experimental.betterMatchTypeExtractors
given Test.Either[String]()
val tup = (Right(1), Right(2), Right(3))
// refuses to compile with or without `scala.language.experimental.betterMatchTypeExtractors`
val d: Tuple.InverseMap[tup.type, Test.current.Self] = ???
}
}
with the output being:
Compiling project (Scala 3.5.0, JVM (21))
[error] ./file.scala:35:12
[error] The match type contains an illegal case:
[error] case given_Either_String.Self[x] *: t => x *: Tuple.InverseMap[t, given_Either_String.Self]
[error] (this error can be ignored for now with `-source:3.3`)
[error] val d: Tuple.InverseMap[tup.type, Test.current.Self] = ???
[error] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
is this expected? I'd expect these two examples to either not compile without betterMatchTypeExtractors at all or compile with betterMatchTypeExtractors