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

override Unit returning method in a parameterized class doesn't override #4749

Closed
scabug opened this issue Jul 1, 2011 · 6 comments
Closed
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jul 1, 2011

I have an entry point wrapper that looks something like the trait listed below that is intended to expose a main for a java entry point if type T = Unit or an arbitrary return type T if the module is embedded:

trait RunWrapper[T] {
  def run(args : Array[String]) : T;
  def main(args : Array[String]) : T = {
    try { run(args) } finally { }
  }
}

// Entry point for java
object A extends RunWrapper[Unit] {
  def run(args : Array[String]) { println("the end") }
}

Unfortunately, I get this bytecode from the compiler (the same for both 2.8.1 and 2.9.0.1):

$ javap A
Compiled from "test.scala"
public final class A extends java.lang.Object{
public static final java.lang.Object main(java.lang.String[]);
public static final void run(java.lang.String[]);
}

Why do I get a return type of java.lang.Object, in this case, for main()? How do I get void in this scenario so that java will allow my to use A as an entry point?

However, if I define the following:

object B extends RunWrapper[Unit] {
def run(args : Array[String]) { println("the end") }
override def main(args : Array[String]) { try { run(args) } finally { } }
}

I get this:

$ javap B
Compiled from "test.scala"
public final class B extends java.lang.Object{
    public static final void main(java.lang.String[]);
    public static final void run(java.lang.String[]);
    public static final java.lang.Object main(java.lang.String[]);
}

So it seems override didn't override anything and the compiler doesn't complain or warn about this. Is this a boxing issue?

@scabug
Copy link
Author

scabug commented Jul 1, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4749?orig=1
Reporter: s wade (swadenator)
Affected Versions: 2.8.1, 2.9.0

@scabug
Copy link
Author

scabug commented Jul 1, 2011

@paulp said:
OK, let's see here:

The return type of Object in RunWrapper is correct. This is how generics work.

Unless we special case main, you will have to write a method which is specifically Unit, you can't use a generic implementation because the jvm requires the exact signature.

When I first saw the example I thought there was a bug, but now if there is one I don't know what it is, other than that we should spot a method which looks like it's trying to be an entry point and warn that it is not in fact an entry point.

@scabug
Copy link
Author

scabug commented Jul 1, 2011

s wade (swadenator) said:
I'm guessing that object B is the bug. Shouldn't the override yield a warning or an error instead of quietly creating a main method with a void return type in addition to the base class's main?

@scabug
Copy link
Author

scabug commented Jul 1, 2011

@paulp said:
No, that is also how generics work.

@scabug
Copy link
Author

scabug commented Jul 1, 2011

s wade (swadenator) said:
got it. Thanks for the explanation.

@scabug
Copy link
Author

scabug commented Jan 10, 2012

@paulp said:
Better error messages in 2064372659 .

@scabug scabug closed this as completed Jan 10, 2012
@scabug scabug added this to the 2.10.0 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants