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

ClassFormatError when overriding a val in a trait refinement #1093

Closed
scabug opened this issue Jul 7, 2008 · 5 comments
Closed

ClassFormatError when overriding a val in a trait refinement #1093

scabug opened this issue Jul 7, 2008 · 5 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jul 7, 2008

trait  Foo {
  val a: Option[String] = None
  def withA(anA:String):Foo = new Foo {
    override val a = Some(anA)
  }
}

class Bar extends Foo

(new Bar()).withA("quux")

The code above compiles fine, but throws this exception when we run it:

java.lang.ClassFormatError: Duplicate method name&signature in class file Main$$$$anon$$2$$Foo$$$$anon$$1
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
	at java.net.URLClassLoader.access$$000(URLClassLoader.java:56)
	at java.net.URLClassLoader$$1.run(URLClassLoader.java:195)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at Main$$$$anon$$2$$Foo$$class.withA((virtual file):7)
	at Main$$$$anon$$2$$Bar.withA((virtual file):12)
	at Main$$$$anon$$2.<init>((virtual file):14)
	at Main$$.main((virtual file):4)
	at Main.main((virtual file))

The generated class Test$$Foo$$$$anon$$1 looks very sucpicious when printed after cleanup.

final <synthetic> class Test$$Foo$$$$anon$$1 extends java.lang.Object with Test$$Foo {
  final <stable> <accessor> def a(): Option = Test$$Foo$$$$anon$$1.this.a;
  private[this] val a: Option = _;
  final <accessor> def a_=(x$$1: Option): Unit = Test$$Foo$$$$anon$$1.this.a = x$$1.$$asInstanceOf[Some]();
  private[this] val a: Some = _;
  override <stable> <accessor> def a(): Some = Test$$Foo$$$$anon$$1.this.a;
  override <stable> <bridge> def a(): Option = Test$$Foo$$$$anon$$1.this.a();
  ...
}
@scabug
Copy link
Author

scabug commented Jul 7, 2008

Imported From: https://issues.scala-lang.org/browse/SI-1093?orig=1
Reporter: Rafael de F. Ferreira (rafaeldff)

@scabug
Copy link
Author

scabug commented Jul 8, 2008

@dubochet said:
I confirmed this issue with r15501. There is definitely something fishy with the way Scalac creates accessors and/or bridges in that case.

@scabug
Copy link
Author

scabug commented Jul 31, 2008

@odersky said:
I could fix this (in r15656) but the fix breaks binary compatibility of all classes that use traits with fields. I therefore postpone the fix to 2.8.0. But it can be tested already now with -Xexperimental.

Btw, the fix can and should be generalized so as to also allow super calls on trait fields. Should be relatively straightforward given the technique (rename trait val fields in addition to trait val setters).

@scabug
Copy link
Author

scabug commented Jan 14, 2009

@odersky said:
Milestone postponed deleted

@scabug
Copy link
Author

scabug commented Apr 30, 2009

@paulp said:
This is all good in trunk and has been for a while; I opened #1938 to preserve martin's comment.

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