Skip to content

Problem extending java.lang.Enum #7174

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

Closed
ekrich opened this issue Sep 5, 2019 · 10 comments · Fixed by #9487
Closed

Problem extending java.lang.Enum #7174

ekrich opened this issue Sep 5, 2019 · 10 comments · Fixed by #9487
Assignees
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala area:enums itype:bug

Comments

@ekrich
Copy link
Contributor

ekrich commented Sep 5, 2019

minimized code

import java.{lang => jl}

final class ConfigSyntax private (name: String, ordinal: Int)
    extends jl.Enum[ConfigSyntax](name, ordinal)

object ConfigSyntax {

  final val JSON = new ConfigSyntax("JSON", 0)
  final val CONF = new ConfigSyntax("CONF", 1)
  final val PROPERTIES = new ConfigSyntax("PROPERTIES", 2)

  private[this] final val _values: Array[ConfigSyntax] =
    Array(JSON, CONF, PROPERTIES)

  def values: Array[ConfigSyntax] = _values.clone()

  def valueOf(name: String): ConfigSyntax =
    _values.find(_.name == name).getOrElse {
      throw new IllegalArgumentException("No enum const ConfigSyntax." + name)
    }
}

problem

Currently the compiler requires an alias or fully specified class name for java.lang.Enum and errors when compiling.

too many arguments for constructor Enum: (): Enum[ConfigSyntax]

expectation

Should compile and not require a fully specified class name.

@OlivierBlanvillain OlivierBlanvillain added the area:desugar Desugaring happens after parsing but before typing, see desugar.scala label Sep 6, 2019
@ekrich
Copy link
Contributor Author

ekrich commented Sep 7, 2019

Edit: this was removed as it is not applicable to the problem.

@ekrich
Copy link
Contributor Author

ekrich commented Sep 10, 2019

I also confirmed that the following code works fine just in Dotty, not Scala 2.

import java.{lang => jl}

enum FromMapMode extends jl.Enum[FromMapMode]{
  case KEYS_ARE_PATHS, KEYS_ARE_KEYS
}

@bishabosha
Copy link
Member

I’m sceptical if the name + ordinal constructor should be exposed in Scala as it’s not visible in Java either

@ekrich
Copy link
Contributor Author

ekrich commented Oct 8, 2019

@bishabosha But this is code existing in the Scala wild as there are no such restrictions from Scala.
Also, this is needed to be compatible with Java enum for interoperability.

@ekrich
Copy link
Contributor Author

ekrich commented Oct 8, 2019

A longer term solution is to provide duplicate enums for Scala 3 but this means editing in 2 places if needed. This is the approach I took here. ekrich/sconfig@4aecf41

@bishabosha
Copy link
Member

@bishabosha But this is code existing in the Scala wild as there are no such restrictions from Scala.
Also, this is needed to be compatible with Java enum for interoperability.

Well I would just say for migration you would be required to use the built-in enum which would synthesise a super call to jl.Enum with the identifier of the constant, and later should be have semantically correct valueOf, values etc. without needing the scala library.

@bishabosha
Copy link
Member

So the current plan is to prevent user-written classes that extend java.lang.Enum like the example, and migrate to the enum construct, once java compatible enums are complete - So I believe that this is out of scope to fix this in the meantime.

@ekrich
Copy link
Contributor Author

ekrich commented Nov 6, 2019

Well, I know we are trying to make Scala safer but since there was no good solution for enums in Scala 2, and this was a way to make Java compatible enums; close anyway. In reality, some projects are going to need to support older Scala versions concurrently with newer versions for quite some time until they can be dropped and having to rewrite all the enums in a project and hack the build file etc. is far from optimal. Did you look at the commit link above to see the amount of work needed to support Dotty enums for that project?

I think this should be supported and could be dropped in the future so this is my objection to closing this issue. Most Scala 2 code should work with some changes or rewrites otherwise the migration to Scala 3 won't be very pleasant. Of course, this project could be the only one that needs this capability so only the future will tell.

@smarter
Copy link
Member

smarter commented Nov 6, 2019

If needs be, we can preserve the previous behavior under -language:Scala2 or only enable it under -strict.

@bishabosha
Copy link
Member

Its definitely important now to enable the constructor as enums can't be written under 3.0-migration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala area:enums itype:bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants