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

Should report error when invoking method on package visible class via super #4626

Open
scabug opened this issue May 20, 2011 · 6 comments
Open
Labels
Milestone

Comments

@scabug
Copy link

scabug commented May 20, 2011

Suppose we have class "A" implemented in Java in the package "a" defined with the default visibility and implementing public method foo:

// a/A.java}
package a;

class A {
    public void foo() {}
}

And public class "SuperA" in the same package that extends class "a.A" (it doesn't matter if this class is implemented in java or scala):

//a/SuperA.scala
package a

class SuperA extends A

The third class "B" in the package "b" extends "SuperA" and invokes "super.foo()":

// b/B.scala
package b

class B extends a.SuperA {
  super.foo()
}

On an attempt to compile class "b.B" scala compiler crashes throwing the following exception:

$ ./runme.sh 
error: java.lang.Error: Unexpected tree in genLoad: B.super/class scala.reflect.generic.Trees$Super at: source-src/b/B.scala,line-4,offset=40
	at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:35)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:1126)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadQualifier(GenICode.scala:1175)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:738)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genLoadQualifier(GenICode.scala:1175)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:921)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genStat(GenICode.scala:174)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genStat$1.apply(GenICode.scala:143)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$genStat$1.apply(GenICode.scala:143)
	at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:111)
	at scala.collection.immutable.List.foldLeft(List.scala:45)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genStat(GenICode.scala:143)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.scala$tools$nsc$backend$icode$GenICode$ICodePhase$$genLoad(GenICode.scala:1052)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:114)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:69)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:69)
	at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
	at scala.collection.immutable.List.foreach(List.scala:45)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:69)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:136)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:88)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:69)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase$$anonfun$gen$1.apply(GenICode.scala:69)
	at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
	at scala.collection.immutable.List.foreach(List.scala:45)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:69)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:79)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.gen(GenICode.scala:65)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.apply(GenICode.scala:61)
	at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply(Global.scala:326)
	at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply(Global.scala:326)
	at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:47)
	at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:326)
	at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:294)
	at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:294)
	at scala.collection.Iterator$class.foreach(Iterator.scala:652)
	at scala.collection.mutable.ListBuffer$$anon$1.foreach(ListBuffer.scala:311)
	at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:294)
	at scala.tools.nsc.backend.icode.GenICode$ICodePhase.run(GenICode.scala:54)
	at scala.tools.nsc.Global$Run.compileSources(Global.scala:949)
	at scala.tools.nsc.Global$Run.compile(Global.scala:1034)
	at scala.tools.nsc.Main$.process(Main.scala:106)
	at scala.tools.nsc.Main$.main(Main.scala:123)
	at scala.tools.nsc.Main.main(Main.scala)

To reproduce this issue unpack attached archive and execute runme.sh script with scala 2.9.0

@scabug
Copy link
Author

scabug commented May 20, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4626?orig=1
Reporter: Alexei Krainiouk (akrainiouk)
Affected Versions: 2.9.0
Attachments:

@scabug
Copy link
Author

scabug commented Jul 5, 2011

@paulp said (edited on Jul 5, 2011 5:24:23 AM UTC):
Well this is an interesting one. We're missing an entire category of superaccessor. Watch what java does with these classes:

// A.java
package a;

class A {
  public void foo1() { }
  public void foo2() { }
  public void foo3() { }
}
// A2.java
package a;

public class A2 extends A { }

Now look at A2. It gets accessor methods for every method in A even though it can access them just fine since it's in the same package. But its subclasses won't be able to, and thanks to separate compilation it has to assume the worst and put in forwarders for everything. Nice.

public class a.A2 extends a.A{
public a.A2();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method a/A."<init>":()V
   4:	return

public void foo3();
  Code:
   0:	aload_0
   1:	invokespecial	#2; //Method a/A.foo3:()V
   4:	return

public void foo2();
  Code:
   0:	aload_0
   1:	invokespecial	#3; //Method a/A.foo2:()V
   4:	return

public void foo1();
  Code:
   0:	aload_0
   1:	invokespecial	#4; //Method a/A.foo1:()V
   4:	return

}

Of course if you make A public, A2 gets nothing.

@scabug
Copy link
Author

scabug commented Jul 5, 2011

@paulp said:
Looks like "implementation restriction" will be our man.

@scabug
Copy link
Author

scabug commented May 4, 2012

@paulp said:
See also duplicate #5650, where there is a related issue mentioned in comments.

@scabug
Copy link
Author

scabug commented Mar 15, 2013

@adriaanm said:
Un-assigning to foster work stealing, as announced in https://groups.google.com/forum/?fromgroups=#!topic/scala-internals/o8WG4plpNkw

@som-snytt
Copy link

Not a crasher, but surprisingly:

$ ~/scala-2.11.12/bin/scalac b/B.scala 
b/B.scala:5: error: Unable to access method f in class A with a super reference.
  def g = super.f
                ^
one error found

but 2.12 and 2.13 have no problem with it.

@scala scala deleted a comment from scabug Feb 11, 2020
@scala scala deleted a comment from scabug Feb 11, 2020
@scala scala deleted a comment from scabug Feb 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants