-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Union type with object used with generic type infers wrong type even with type ascription #14642
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
Comments
Interestingly even a ++ (b: List[Union]) is typed as |
This looks like the default widening behavior of Scalac. #8231 |
It is, and I'm not a compiler expert, but I think they may rely on the same mechanism. The good thing is that unions are new (exist only in Scala 3) and therefore setting the widening behavior can be more flexible than literal widening. |
l3 seems to work now in 3.2.1 but l2 is still an error: scala> case object A
| case class B()
| case class C()
| type Union = A.type | B | C
| val a: List[A.type] = ???
| val b: List[B] = ???
| val c: List[C] = ???
| val l1: List[Union] = a ++ b // OK
| val l2: List[Union] = a ++ b ++ c // [E007] Found: List[Object], Required: List[Union]
| val l3: List[Union] = (a: List[Union]) ++ b ++ c // [E007] Found: List[Object], Required: List[Union]
| val l4: List[Union] = (a: List[Union]) ++ (b ++ c) // OK
-- [E007] Type Mismatch Error: ------------------------------------------------------------------------------------------------
9 |val l2: List[Union] = a ++ b ++ c // [E007] Found: List[Object], Required: List[Union]
| ^^^^^^^^^^^
| Found: List[Object]
| Required: List[Union]
|
| longer explanation available when compiling with `-explain`
1 error found
|
[skip community_build] closes scala#14642
Compiler version
Scala 3.1.1
Minimized code
Consider this code where the lines with
l2
andl3
fails compilation.Output
Expectation
I am aware that the compiler does not infer union types but instead infers
Matchable
. However, it seems odd thatval l1
compiles whenl2
andl3
don't.The problem might be that
(a ++ b)
is inferred toList[Matchable]
and therefore(a ++ b) ++ c
gets tagged as no-more-specific-than-List[Matchable]
and therefore fails the type ascriptionList[Union]
. It seems(a ++ b)
should be tagged as no-more-specific-than-List[A.type | B]
and therefore(a ++ b) ++ c
should be tagged as no-more-specific-than-List[(A.type | B) | C]
, which either infers toList[Matchable]
with no ascription, or passes theList[Union]
ascription.Adding the extra set of parenthesis for
l4
basically reduces the case to be similar tol1
and things compile.Things (almost) work if A is a class and not an object
It is important to note that the problem is only present if
A
is an object. ChangingA
to be a class changes the behaviour:Now,
l2
still fails compilation but the type ascription inl3
fixes the issue. The problem withl2
looks similar to the problem reported in #11449.The output is:
The text was updated successfully, but these errors were encountered: