Skip to content

Commit

Permalink
Improve failure message of enum fromOrdinal/valueOf (scala#19182)
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Dec 15, 2023
2 parents 08572ee + 2dcd64a commit 1f7aa24
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 5 deletions.
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ object DesugarEnums {

val valuesOfBody: Tree =
val defaultCase =
val msg = Apply(Select(Literal(Constant("enum case not found: ")), nme.PLUS), Ident(nme.nameDollar))
val msg = Apply(Select(Literal(Constant(s"enum ${enumClass.fullName} has no case with name: ")), nme.PLUS), Ident(nme.nameDollar))
CaseDef(Ident(nme.WILDCARD), EmptyTree,
Throw(New(TypeTree(defn.IllegalArgumentExceptionType), List(msg :: Nil))))
val stringCases = enumValues.map(enumValue =>
Expand All @@ -148,7 +148,8 @@ object DesugarEnums {
def valueCtor: List[Tree] = if constraints.requiresCreator then enumValueCreator :: Nil else Nil
def fromOrdinal: Tree =
def throwArg(ordinal: Tree) =
Throw(New(TypeTree(defn.NoSuchElementExceptionType), List(Select(ordinal, nme.toString_) :: Nil)))
val msg = Apply(Select(Literal(Constant(s"enum ${enumClass.fullName} has no case with ordinal: ")), nme.PLUS), Select(ordinal, nme.toString_))
Throw(New(TypeTree(defn.NoSuchElementExceptionType), List(msg :: Nil)))
if !constraints.cached then
fromOrdinalMeth(throwArg)
else
Expand Down
2 changes: 1 addition & 1 deletion tests/run/enum-java.check
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ MONDAY : 0
TUESDAY : 1
SATURDAY : 2
By-name value: MONDAY
Correctly failed to retrieve illegal name, message: enum case not found: stuff
Correctly failed to retrieve illegal name, message: enum A has no case with name: stuff

Collections Test
Retrieving Monday: workday
Expand Down
2 changes: 1 addition & 1 deletion tests/run/enum-values.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ enum ClassOnly: // this should still generate the `ordinal` and `fromOrdinal` co
catch
case e: java.lang.reflect.InvocationTargetException => // TODO: maybe reflect.Selectable should catch this?
assert(e.getCause.isInstanceOf[java.util.NoSuchElementException]
&& e.getCause.getMessage == ordinal.toString)
&& e.getCause.getMessage == s"enum ${companion.getClass.getName.stripSuffix("$")} has no case with ordinal: $ordinal")

fetchFromOrdinal(companion = Color, compare = Red, Green, Blue)
fetchFromOrdinal(companion = Suits, compare = Clubs, Spades, Diamonds, Hearts)
Expand Down
2 changes: 1 addition & 1 deletion tests/run/enums-java-compat.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ TUESDAY : 1
SATURDAY : 2
Stuff : 3
By-name value: MONDAY
Correctly failed to retrieve illegal name, message: enum case not found: stuff
Correctly failed to retrieve illegal name, message: enum A has no case with name: stuff
4 changes: 4 additions & 0 deletions tests/run/i19178.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Failure(java.util.NoSuchElementException: enum Foo has no case with ordinal: 3)
Failure(java.lang.IllegalArgumentException: enum Foo has no case with name: Bar)
Failure(java.util.NoSuchElementException: enum bar.Bar has no case with ordinal: 4)
Failure(java.lang.IllegalArgumentException: enum bar.Bar has no case with name: Baz)
14 changes: 14 additions & 0 deletions tests/run/i19178.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
enum Foo:
case A

package bar {
enum Bar:
case B
}

@main def Test =
import scala.util.Try
println(Try(Foo.fromOrdinal(3)))
println(Try(Foo.valueOf("Bar")))
println(Try(bar.Bar.fromOrdinal(4)))
println(Try(bar.Bar.valueOf("Baz")))

0 comments on commit 1f7aa24

Please sign in to comment.