-
Notifications
You must be signed in to change notification settings - Fork 19
Added -Zexplicit-implicit-type-ascriptions #68
Conversation
This commit reserves the [zZ] and [sS] suffixes for Byte and Short literals, respectively. These work exactly like Long literals, which were already denoted with [lL]. For example, you can say: val zero = 0Z val bytes = List(23Z, 23Z, 0Z, 0Z, 111Z, -54Z, 19Z, 17Z) This commit does not permit literal unsigned bytes, so 255Z and 0xffZ are not legal. The choice of Z may seem strange, but B will not work for hex constants (0x10B would be ambiguous) so Z seemed like a good choice.
This adds a flag called `-Zirrefutable-generator-patterns` which changes desugaring of code like the following: for { (a, b) <- List(1 -> 'a', 2 -> 'b') (c, d) <- List(3 -> 'c', 4 -> 'd') } yield (a + c, b + d) Which previously would turn into something like: List(1 -> 'a', 2 -> 'b').withFilter { case (a, b) => true case _ => false }.flatMap { case (a, b) => List(3 -> 'c', 4 -> 'd').withFilter { case (c, d) => true case _ => false }.map { case (c, d) => (a + c, b + d) } } With this new flag, it only becomes: List(1 -> 'a', 2 -> 'b').flatMap { case (a, b) => List(3 -> 'c', 4 -> 'd').map { case (c, d) => (a + c, b + d) } } Which creates a few benefits: 1. We don't have to do a useless call to withFilter 2. We can use patterns on things without withFilter 3. Things don't silently disappear when patterns are wrong
We assume patterns are exhaustive when desugaring with `-Zirrefutable-generator-patterns` but we should still emit a warning if we think they might not be.
Add support for literal Byte and Short values.
Allow primes at the end of identifiers.
…tterns Conflicts: bincompat-forward.whitelist.conf src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
…atterns Add flag to disable withFilter pattern desugaring
Example usage: trait =!=[C, D] implicit def neq[E, F] : E =!= F = null @annotation.implicitAmbiguous("Could not prove ${J} =!= ${J}") implicit def neqAmbig1[G, H, J] : J =!= J = null implicit def neqAmbig2[I] : I =!= I = null implicitly[Int =!= Int] Which gives the following error: implicit-ambiguous.scala:9: error: Could not prove Int =!= Int implicitly[Int =!= Int] ^ Better than what was previously given: implicit-ambiguous.scala:9: error: ambiguous implicit values: both method neqAmbig1 in object Test of type [G, H, J]=> Main.$anon.Test.=!=[J,J] and method neqAmbig2 in object Test of type [I]=> Main.$anon.Test.=!=[I,I] match expected type Main.$anon.Test.=!=[Int,Int] implicitly[Int =!= Int] ^
This is where our additions to scala-library.jar will go. The current content is the implicitAmbiguous annotation. I seemed to have made the right changes to make the REPL, the test classpath and scala-dist to work. I'm not sure if there's anything else we need but I also inserted references to typelevel where library was also referenced, just in case.
…otation Add an @implicitAmbiguous annotation
With the flag enabled, every implicit val/var/def definition must have an explicit type ascription, otherwise an error is emitted.
Do the type ascription changes to the compiler and stdlib need to be made? They won't have the flag enabled, right? |
Flag's not enabled, so they're not required, no. But they are probably a good thing, and the work's been done, so I've left them in, as the binary compatibility tests all pass. |
Why not enable the flag then? Otherwise this change will not be maintained. |
My minor concern is this could make merging Typesafe scalac a little annoying but probably not. |
Oh, and we'd definitely appreciate the patch with the explicit annotations throughout our code! |
So I just wrote
and obviously I don't want to add an import so I can write This was in a test, BTW, also subject to migration. |
@retronym The patch should ascribe explicit types to all the instances that flagged as errors during compilation of the compiler and standard library, with one exception (which unfortunately I haven't been able to find in ten minutes of trying to find it again): there's a method somewhere which returns an implicit def which returns an instance of a class defined locally to that method. I think this means the implicit will get a structural type inferred, but it was sufficiently horrible that I stopped there... |
@som-snytt I'm not sure I'd want an implicit import for such a specific use case, though I agree it's annoying. Suggestions welcome... |
If you would like to resurrect this issue/PR please rework it as a PR against Lightbend Scala 2.12.x (ie. scala/scala). |
With the flag enabled, every implicit val/var/def definition must have
an explicit type ascription, otherwise an error is emitted.