-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Search for type tests when matching abstract applied type #13453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
4987f48
to
6e238b6
Compare
What's the issue with isInstanceOf on a match type? And if there is an issue, shouldn't normalized be called at the point where we generate the isInstanceOf instead? |
6e238b6
to
8d29145
Compare
Investigating further it was not the {
def $anonfun(s: Any): Option[(s : Any) & Matcher[String]] =
if s.isInstanceOf[Matcher[String]] then
Some.apply[s.type & Matcher[String]](
s.asInstanceOf[s.type & Matcher[String]]
)
else None
closure($anonfun:scala.reflect.TypeTest[Any, Matcher[String]])
} but if we write it explicitly we infer {
def $anonfun(s: Any): Option[(s : Any) & String] =
{
if s.isInstanceOf[Matcher[String]] then
Some.apply[s.type & Matcher[String]](
s.asInstanceOf[s.type & Matcher[String]]
)
else None
}
closure($anonfun)
} I will investigate further |
As far as I can see it is only the synthesized version of the type test that needs this explicit normalization of the type. |
By the way, is there any reason to limit ourselves to abstract types? One could imagine wanting to write a TypeTest instance for a concrete class with abstract type parameters: import scala.reflect.Typeable
class Box[A](val a: A)(using val ta: Typeable[A])
object Box:
given [A]: Typeable[Box[A]] with
def unapply(x: Any) = x match
case box: Box[_] =>
if box.ta.unapply(box.a).isDefined then
Some(box.asInstanceOf[x.type & Box[A]])
else
None
case _ =>
None
def func[A](box: Box[A]) = box match {
case _: Box[String] => println("String")
case _: Box[Int] => println("Int")
} (this came up on gitter today: https://gitter.im/scala/scala?at=613a4ccf4c7be06b79abec3e) |
(probably not something we want to change in this PR but worth discussing later) |
That is a limitation that I would like to remove at some point. The only noticeable thing is that some pattern matches that had unchecked warnings might become checked, which will change the semantics of some existing programs. Unless we do not provide any interesting implementations of |
Are you still investigating or is this PR waiting on me? |
Waiting for you. The investigation concluded with #13453 (comment). Sorry to not have been clear. |
@@ -50,7 +50,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): | |||
(formal, span) => formal.argInfos match { | |||
case arg1 :: arg2 :: Nil if !defn.isBottomClass(arg2.typeSymbol) => | |||
val tp1 = fullyDefinedType(arg1, "TypeTest argument", span) | |||
val tp2 = fullyDefinedType(arg2, "TypeTest argument", span) | |||
val tp2 = fullyDefinedType(arg2, "TypeTest argument", span).normalized |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks a bit suspicious. By default I would say that we need a really good reason to manually trigger type normalized. In principle all newly created types should already go thought nurmalization just after creation, and if fullyDefinedType creates non normalized types it might mean that there is a better spot in the code to do the normalization (deeper in the stack trace).
Note that we another place in the code where we do a fullyDefinedType
call followed by a .normalized
(which is equality suspicious):
My intition tells me that there is a way to both fix this issue and remove that .normalized
in Synthesizer
, and that this way would a better solution that the change done in this PR...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it seems to be a general limitation. We should probably open a separate issue for this improvement.
8d29145
to
6ff902b
Compare
Rebased |
TypeTest
closure signature.Fixes #13433