-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Simplify handling of union types #2330
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
Risk of confusing with Types.SingletonType is too high.
The idea is that or-types should never be inferred, so we widen them - when instantiating type variables - when computing the type of valdef or defdefs from the rhs. This is already done in harmonizeUnion. However, harmonizeUnion had the restrictions that it joined or-types only in Scala2 mode. This restriction is now dropped.
- `ctx.harmonizeUnion(tp)` now becomes `tp.widenUnion`. - Same order of operations in local type inference of Namer and type variable instantiation. First, simplify, then widen, then widenUnion.
@@ -167,6 +167,7 @@ class tests extends CompilerTest { | |||
@Test def rewrites = compileFile(posScala2Dir, "rewrites", "-rewrite" :: scala2mode) | |||
|
|||
@Test def pos_t8146a = compileFile(posSpecialDir, "t8146a")(allowDeepSubtypes) | |||
@Test def pos_jon = compileFile(posSpecialDir, "jon")(allowDeepSubtypes) |
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.
Isn't it surprising that this requires deep subtypes?
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.
I did not look too deeply. But SeqFactory has a funky recursive type
SeqFactory[CC[X] <: Seq[X] with GenericTraversableTemplate[X, CC]] extends GenSeqFactory[CC] with TraversableFactory[CC]
so it's not so implausible.
val xs3 = mutable.ListBuffer(Right("foo"), Left(0), Right("bar")) From the collection strawman to be inferred without unions. If so, it'd be good to add it as a testcase.
sealed trait NegTestState
case class CompFailed() extends NegTestState
case class CompSucceeded() extends NegTestState
object Test {
val failureStates /* : List[CompSucceeded | CompFailed.type] */ = List(true, false) map {
case true => CompSucceeded()
case false => CompFailed // BUG: should be CompFailed()
}
failureStates.exists({
case CompFailed() => // error: CompFailed is neither subtype
true // nor supertype of selector type
case _ =>
false
})
} |
Just updated my example in the previous comment so that it actually compiles with scalac but not with dotty, it was incorrect before. |
* re-lubbing it while allowing type parameters to be constrained further. | ||
* Any remaining union types are replaced by their joins. | ||
* | ||
* For instance, if `A` is an unconstrained type variable, then |
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.
Incorrect indentation around here.
@@ -830,23 +830,23 @@ object Types { | |||
* def o: Outer | |||
* <o.x.type>.widen = o.C | |||
*/ | |||
@tailrec final def widen(implicit ctx: Context): Type = widenSingleton match { |
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.
Why was the tailrec annotation removed?
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.
It was noise. I was against adding it, but it got merged before I could comment.
As I wrote then: Add a @tailrec only if it is important that the method is in fact tail-recursive. Either it is super-performance critical or can potentially recurse deeply. Do not add @tailrec just because the method happens to be tail recursive.
@smarter I don't think it's systematic to treat Any or AnyRef differently here. There is code out there that uses Any types pervasively (Spark comes to mind, as do some of our Lisp interpreters). It would be surprising if type inference started to fail. |
It also compiles with dotty now 😄 |
Except that its type will change with the ProductN removal which needs to get in first. In any case we should get to a point where dotty and the collection strawman are always tested together. |
On the other hand it might motivate people to avoid using |
scalac even has a |
Yes, I think a warning is the right way to deal with this. We can implement that later. |
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.
LGTM
FWIW, timely discussion on the kind of issues I mentioned above: https://www.reddit.com/r/programming/comments/690fpx/when_the_scala_compiler_doesnt_help/ |
Yes, I guess we should implement this "warn on infer Any" flag ;-)
…On Wed, May 3, 2017 at 10:02 PM, Guillaume Martres ***@***.*** > wrote:
FWIW, timely discussion on the kind of issues I mentioned above:
https://www.reddit.com/r/programming/comments/690fpx/
when_the_scala_compiler_doesnt_help/
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#2330 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAwlVlAqeG-N-5qFu1-flDB_DcolJJdLks5r2N1YgaJpZM4NMifh>
.
{"api_version":"1.0","publisher":{"api_key":"
05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":
{"external_key":"github/lampepfl/dotty","title":"
lampepfl/dotty","subtitle":"GitHub repository","main_image_url":"
https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-
11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://
cloud.githubusercontent.com/assets/143418/15842166/
7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in
GitHub","url":"https://github.com/lampepfl/dotty"}},"
***@***.*** in #2330:
FWIW, timely discussion on the kind of issues I mentioned above:
https://www.reddit.com/r/programming/comments/690fpx/
when_the_scala_compiler_doesnt_help/"}],"action":{"name":"View Pull
Request","url":"#2330 (comment)
299019267"}}}
--
Prof. Martin Odersky
LAMP/IC, EPFL
|
This is an attempt at simplifying the way we handle type unions. The central idea is that type unions should be treated analogous to singleton types: We should eliminate them in inferred types unless
they are explicitly given.
We already do a lot of that in many different contexts and by different means because type unions
have turned out to have problematic interactions with type inference. The aim of this PR is to simplify and generalize what we already do.