-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Typing varargs in pattern position #4790
Comments
The reason it work with |
The restriction is basically because we're afraid that some class might implement
But it seems too conservative here for two reasons:
class Test {
def foo(as: immutable.Seq[Int]) = {
val _ :: bs = as
val cs: collection.Seq[Int] = bs
}
} Double-checking scenario 2 is safe is the harder part, but extending diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
index 66adb9194..13786309d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -20,6 +20,7 @@ import config.Printers.{typr, constr}
import annotation.tailrec
import reporting._
import collection.mutable
+import transform.SymUtils._
import config.Config
import scala.annotation.internal.sharable
@@ -191,8 +192,10 @@ object Inferencing {
* TODO: Update so that GADT symbols can be variant, and we special case final class types in patterns
*/
def constrainPatternType(tp: Type, pt: Type)(implicit ctx: Context): Boolean = {
+ def refinementIsInvariantCls(cls: Symbol): Boolean =
+ cls.is(Final) || cls.is(Case) || cls.is(Sealed) && cls.children.forall(refinementIsInvariantCls) // checking .forall(childCls => childCls.is(Final) || childCls.is(Final)) is a tempting mistake, but I think we need recursion here to handle multiple levels.
def refinementIsInvariant(tp: Type): Boolean = tp match {
- case tp: ClassInfo => tp.cls.is(Final) || tp.cls.is(Case)
+ case tp: ClassInfo => refinementIsInvariantCls(tp.cls)
case tp: TypeProxy => refinementIsInvariant(tp.underlying)
case tp: AndType => refinementIsInvariant(tp.tp1) && refinementIsInvariant(tp.tp2)
case tp: OrType => refinementIsInvariant(tp.tp1) && refinementIsInvariant(tp.tp2) (Tested in this case). |
Must also check if those closed hierarchies prevent refinement.
Must also check if those closed hierarchies prevent refinement.
I probably won't be able to work on this in the near future. |
But it does compile with
-language:Scala2
...The text was updated successfully, but these errors were encountered: