Skip to content
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

Using Enumeration values to match will compile even when match is not exhaustive #4333

Closed
scabug opened this issue Mar 11, 2011 · 7 comments
Closed

Comments

@scabug
Copy link

scabug commented Mar 11, 2011

I think this following snippet should not compile (because the match does not contain an exhaustive set of cases):

scala> object Enum extends Enumeration { val A, B, C = Value }
defined module Enum

scala> def foo(v : Enum.Value) = v match {
     | case Enum.B => println("B")
     | }
foo: (v: Enum.Value)Unit

It compiles and produces a MatchError at runtime:

scala> foo(Enum.A)
scala.MatchError: A
	at .foo(<console>:6)
	at .<init>(<console>:8)
	at .<clinit>(<console>)
	at RequestResult$$.<init>(<console>:9)
	at RequestResult$$.<clinit>(<console>)
	at RequestResult$$scala_repl_result(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at scala.tools.nsc.Interpreter$$Request$$$$anonfun$$loadAndRun$$1$$$$anonfun$$apply$$18.apply(Interpreter.scala:981)
	at scala.tools.nsc.Interpreter$$Request$$$$anonfun$$loadAndRun$$1$$$$anonfun$$apply$$18.apply(Interpreter.scala:981)
	at scala.util.control.Exception$$Catch.apply(Exception.scala:79)
	at scal...

Using scala 2.8.1.

@scabug
Copy link
Author

scabug commented Mar 11, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4333?orig=1
Reporter: @oxbowlakes
See #5211

@scabug
Copy link
Author

scabug commented Mar 11, 2011

@retronym said:
"If the selector of a pattern match is an instance of a sealed class (�5.2), the compilation of pattern matching can emit warnings which diagnose that a given set of
patterns is not exhaustive, i.e. that there is a possibility of a MatchError being raised at run-time."

That doesn't apply for Enumeration.

@scabug
Copy link
Author

scabug commented Mar 11, 2011

@oxbowlakes said:
Can this be upped to an enhancement request? I think that:

a) it breaks the principle of least surprise
b) it is something that can quite clearly be checked at compile-time

@scabug
Copy link
Author

scabug commented Mar 11, 2011

@retronym said:
For better or for worse, scala.Enumeration is provided by the library, not the language. As such, it isn't afforded special treatment by the pattern matcher.

Perhaps this could provided by an IDE inspection. But I doubt you'll convince anyone that it could or should go in the pattern matcher, circa 2011.

@scabug
Copy link
Author

scabug commented Mar 11, 2011

@acruise said:
I agree that special-casing Enumeration in the compiler is unlikely to happen, but it's interesting to think about how this kind of thing could be done in a general way.

CODE SKETCH, DO NOT COMPILE

case class sealed(value: Seq[_ <: Enumeration#Value] extends Annotation

object Foo extends Enumeration {
  @sealed(List(Foo1,Foo2)) // Probably doable, but smelly repetition
  @sealed(values)          // Too bad values is a def, not a stable identifier
  case class FooValue(i: Int, s: String, d: Double) extends Value(i, s)

  type Foo = FooValue

  val Foo1 = Foo(1,"One",1.0)
  val Foo2 = Foo(2,"Two",2.0)
}

@scabug
Copy link
Author

scabug commented Mar 11, 2011

@acruise said:
Replying to [comment:4 acruise]:

case class sealed(value: Seq[_ <: Enumeration#Value] extends Annotation

I guess that should be Seq[Any] or Seq[_] to avoid special-casing enumerations in the compiler. :)

@scabug
Copy link
Author

scabug commented Mar 12, 2011

@retronym said:
Well, you can't pass arbitrary objects to annotations, they must be Contant Expressions (like literals, arrays, other annotations, or final vals, in an object, without type annotation, with a constant expression as the RHS.

You can pass type parameters though.

https://gist.github.com/867149

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant