Skip to content

Mishandled captured parameters in secondary class constructors. #9536

Open
@scabug

Description

There are some conditions where parameter captured by secondary constructors generate ambiguous bytecode. Such as in the following example where the default constructor receives an Int parameter and the secondary captures an Int.

object Bar extends App {
  val 
  def foo(x: Int) = {		
    class Foo(i: Int) {
      def this() = this(x)
    }
    new Foo
  }
  println(foo(6))
}

Will generate the following bytecode where the two constructors have the same signature.

public class Bar$Foo$1 {
  public Bar$Foo$1(int);
    descriptor: (I)V
    Code:
       0: aload_0
       1: invokespecial #15                 // Method java/lang/Object."<init>":()V
       4: return

  public Bar$Foo$1(int);
    descriptor: (I)V
    Code:
       0: aload_0
       1: iload_1
       2: invokespecial #21                 // Method "<init>":(I)V
       5: return
}

The problem does not show itself at compilation time, it only fails at runtime with:

[info] Running Bar 
[error] (run-main-b) java.lang.ClassFormatError: Duplicate method name&signature in class file Bar$Foo$1
java.lang.ClassFormatError: Duplicate method name&signature in class file Bar$Foo$1
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at Bar$.foo(A.scala:7)
	at Bar$.delayedEndpoint$App$1(Bar.scala:10)
	at Bar$delayedInit$body.apply(Bar.scala:1)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.Bar$$anonfun$main$1.apply(App.scala:76)
	at scala.Bar$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:381)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at Bar$.main(Bar.scala:1)
	at Bar.main(Bar.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
	at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
[error] Total time: 1 s, completed Oct 26, 2015 4:42:21 PM

The compiler should handle these cases in a different way or should disallow them by failing the compilation.

Metadata

Assignees

No one assigned

    Labels

    bytecodefixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions