SI-6541 valid wildcard existentials for case-module-unapply#4017
SI-6541 valid wildcard existentials for case-module-unapply#4017lrytz merged 2 commits intoscala:2.11.xfrom
Conversation
|
Review by @retronym |
There was a problem hiding this comment.
This ain't hygenic.
case class C2(b: Tuple1[_ <: String])
object C2 {
class String
}test/files/run/t6541.scala:28: error: type mismatch;
found : (_$1(in method apply),) where type _$1(in method apply) <: C2.String
required: Tuple1[_ <: String]
case class C2(b: Tuple1[_ <: String])
^
There was a problem hiding this comment.
Last time I tried to fix this, I ended up with a custom type completer for unapply to add enough laziness to the mix so we could peek at the info of the case class to derive the type of the unapply method.
There was a problem hiding this comment.
You are right about hygiene. But note that the error message talks about apply (not unapply), so this failure is not introduced by my change. Arguably, the failure is according to the spec: http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#case-classes.
We should do the same for the parameter types of apply and the return type of unapply: both hygienic, or both not.
We should also include copy in the discussion – it's not systematic that it works differently. The problem with copy is that we have a stronger argument for making it hygienic: otherwise we can get a failure even without an explicit shadowing type declaration:
class A {
class C
case class B(x: C) extends A { def copy(x: C = this.x) = ... }
}The class parameter type is A.this.C. If copy was non-hygienic, the parameter type of copy would be B.this.C (since B extends A), so it would not compile.
There was a problem hiding this comment.
Right you are. In fact, the type parameters of copy are also prone to shadowing.
case class C2[T <: String]() {
class String
}% scalac-hash v2.11.2 test/files/run/t6541.scala
test/files/run/t6541.scala:28: error: type arguments [T] do not conform to class C2's type parameter bounds [T <: String]
case class C2[T <: String]() {
^
one error found
In this case, we can defer that mess to a new ticket and proceed with this one. Perhaps though it needs to be under -Xsource:2.12 as it changes signatures (albeit in a binary compatible way).
There was a problem hiding this comment.
I logged https://issues.scala-lang.org/browse/SI-8884
Good point about compatibility, I only thought about binary.
I'm not sure if -Xsource:2.12 is the right solution here, maybe better submit the PR against 2.12? Because the generated pickle is different, so in some sense it's binary incompatible. If you turn it on to compile a library, then a client might fail to compile against the new binary.
There was a problem hiding this comment.
I can't see a way that enabling this under -Xsource:2.12 would lead to breakage under separate compilation with different flags. The type of the unapply is computed once and stored in the pickle.
There was a problem hiding this comment.
-
constrParamssreturns duplicated trees
There was a problem hiding this comment.
But needn't call it twice (once to determine the method name, and again here).
|
Not sure what style we should settle on, but we might consider referring to e.g. https://github.com/retronym/scala/compare/review/4017/symful?expand=1 We don't need to change this PR, but let's give it some thought and seek some consistency in how we refer to things from the parser. /cc @densh |
|
As far as I know the reason we have both root qualified and symbol qualified identifiers emitted by the parser due to the fact that symbol-only approach used to cause cyclic references while bootstrapping standard library. Maybe this is not an issue any more but it needs some investigation. |
004060d to
a51c9f3
Compare
aebc456 to
9a76336
Compare
The default value was NoScalaVersion before, because tryToSet (where the default was supposed to be set) is not called at all if the option is not specified. The initial value of Xmigration is set to NoScalaVersion (which it was before, the AnyScalaVersion argument was ignored). AnyScalaVersion would be wrong, it would give a warning in `Map(1 -> "eis").values` if the option was not specified. See tests.
|
The change is now under |
|
Great! One last thing: can you please add a |
Instead of letting the compiler infer the return type of case module unapply methods, provide them explicitly. This is enabled only under -Xsource:2.12, because the change is not source compatible.
|
@retronym turned it into a repl test |
|
LGTM |
SI-6541 valid wildcard existentials for case-module-unapply
Instead of letting the compiler infer the return type of case module
unapply methods, provide them explicitly.