From 11bfa25e37d32f4017d5c04b4899b1bdfbd95e06 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 15 Dec 2013 18:28:03 -0800 Subject: SI-7897, SI-6675 improves name-based patmat This emerges from a recent attempt to eliminate pattern matcher related duplication and to bake the scalac-independent logic out of it. I had in mind something a lot cleaner, but it was a whole lot of work to get it here and I can take it no further. Key file to admire is PatternExpander.scala, which should provide a basis for some separation of concerns. The bugs addressed are a CCE involving Tuple1 and an imprecise warning regarding multiple pattern crushing. Editorial: auto-tupling unapply results was a terrible idea which should never have escaped from the crib. It is tantamount to purposely throwing type safety down the toilet in the very place where people need type safety the most. See SI-6111 and SI-6675 for some other comments. --- test/files/neg/t6675b.scala | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/files/neg/t6675b.scala (limited to 'test/files/neg/t6675b.scala') diff --git a/test/files/neg/t6675b.scala b/test/files/neg/t6675b.scala new file mode 100644 index 0000000000..c86c9c3955 --- /dev/null +++ b/test/files/neg/t6675b.scala @@ -0,0 +1,40 @@ +object LeftOrRight { + def unapply[A](value: Either[A, A]): Option[A] = value match { + case scala.Left(x) => Some(x) + case scala.Right(x) => Some(x) + } +} + +object NativelyTwo { + def unapply[A](value: Either[A, A]): Option[(A, A)] = value match { + case scala.Left(x) => Some(x -> x) + case scala.Right(x) => Some(x -> x) + } +} + + +class A { + def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight(a) => a } // warn + def f2 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight((a, b)) => a } // no warn + def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight((a, b, c)) => a } // fail +} + +class B { + def f1[A](x: A) = (Left(x): Either[A, A]) match { case LeftOrRight(a) => a } // no warn + def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight(a) => a } // warn + def f3[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight((a, b)) => a } // no warn + def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight((a, b, c)) => a } // fail +} + +class C { + def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo(a) => a } // warn + def f2 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo((a, b)) => a } // no warn + def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo((a, b, c)) => a } // fail +} + +class D { + def f1[A](x: A) = (Left(x): Either[A, A]) match { case NativelyTwo(a) => a } // warn + def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo(a) => a } // warn + def f3[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo((a, b)) => a } // no warn + def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo((a, b, c)) => a } // fail +} -- cgit v1.2.3