[SI-4365] type parameterization unstable based on file compilation order Created: 19/Mar/11  Updated: 25/Mar/14  Resolved: 26/Apr/13

Status: CLOSED
Project: Scala Programming Language
Component/s: Compiler (Misc)
Affects Version/s: None
Fix Version/s: Scala 2.11.0-M3

Type: Bug Priority: Major
Reporter: Paul Phillips Assignee: Paul Phillips
Resolution: Fixed Votes: 0
Labels: separate-compilation

Issue Links:
relates to SI-8439 poor diagnostic error for using newly... Open
Johannes Rudolph, Paul Phillips


Extracted from SI-4305, where adriaan has some more info.

// 1.scala
trait Derived[+SA, +This <: Derived[SA, This]] extends Base[SA, This] {
  trait Reversed extends super.Reversed with super.Transformed[SA]
  protected override def newReversed: super.Transformed[SA] = new Reversed { } 
// 2.scala
trait Base[+A, +This <: Base[A, This]] {
  trait Transformed[+B] {
    override def toString: String = error("")
  trait Reversed extends Transformed[A] {
    private def x: Unit = {x: A => error("") }
  protected def newReversed: Transformed[A] = new Reversed { }

% scalac29 1.scala 2.scala 
error: java.lang.Error: A in trait Base cannot be instantiated from [+A,+This <: Base[A,This]]Base[A,This]
	at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:35)
	at scala.tools.nsc.symtab.Types$$AsSeenFromMap.throwError$$1(Types.scala:3389)
	at scala.tools.nsc.symtab.Types$$AsSeenFromMap.instParam$$1(Types.scala:3392)
	at scala.tools.nsc.symtab.Types$$AsSeenFromMap.toInstance$$1(Types.scala:3403)
% scalac29 2.scala 1.scala

Assigning to myself, but don't infer that I know anything about how to fix it, I'm just diving in front of the bullet.

Comment by Lukas Rytz [ 14/Jul/12 ]

The example in the description works in the meantime. However I can still reproduce it with the following sources


package scala.collection
trait SeqViewLike[+A,
                  +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]]
  extends Seq[A]   with GenSeqViewLike[A, Coll, This]
  trait Transformed[+B] extends super[GenSeqViewLike].Transformed[B]
  private[collection] abstract class AbstractTransformed[+B] extends Seq[B] with Transformed[B] {
    def underlying: Coll = error("")
  trait Reversed extends Transformed[A] with super[GenSeqViewLike].Reversed
  protected def newReversed: Transformed[A] = new AbstractTransformed[A] with Reversed


package scala.collection
trait GenSeqViewLike[+A,
                     +This <: GenSeqView[A, Coll] with GenSeqViewLike[A, Coll, This]]
extends GenSeq[A] {
self =>
  trait Transformed[+B] {
    def length: Int = 0
    def apply(idx: Int): B = error("")
  trait Reversed extends Transformed[A] {
    def iterator: Iterator[A] = createReversedIterator
    private def createReversedIterator: Iterator[A] = {
      self.foreach(_ => ())

i get

build/pack/bin/scalac -sourcepath src/library -d out -cp build/libs/classes/forkjoin:build/locker/classes/library sandbox/1.scala sandbox/2.scala 
error: A in trait GenSeqViewLike cannot be instantiated from [+A, +Coll, +This <: scala.collection.GenSeqView[A,Coll] with scala.collection.GenSeqViewLike[A,Coll,This]]scala.collection.GenSeqViewLike[A,Coll,This]
lucmac:scala luc$ build/pack/bin/scalac -sourcepath src/library -d out -cp build/libs/classes/forkjoin:build/locker/classes/library sandbox/2.scala sandbox/1.scala 
warning: there were 2 deprecation warnings; re-run with -deprecation for details
one warning found
lucmac:scala luc$ 

Comment by Lukas Rytz [ 14/Jul/12 ]

or with the unmodified library sources

lucmac:scala luc$ build/pack/bin/scalac -sourcepath src/library -d out -cp build/libs/classes/forkjoin:build/locker/classes/library src/library/scala/collection/SeqViewLike.scala src/library/scala/collection/GenSeqViewLike.scala
error: A in trait GenTraversableViewLike cannot be instantiated from [+A, +Coll, +This <: scala.collection.GenTraversableView[A,Coll] with scala.collection.GenTraversableViewLike[A,Coll,This]]scala.collection.GenTraversableViewLike[A,Coll,This]

Comment by Paul Phillips [ 14/Jul/12 ]

Minimized a ways, and self-contained. Someday I have to write something to do this sort of minimization on our behalves.

// a_1.scala
trait SVL extends GSVL[Int, CBar] {
  new Reversed { }
// a_2.scala
trait Bar0[+A]
trait Bar1[+This]
class CBar extends Bar0[Int] with Bar1[CBar] { }
trait GSVL[+A, +This <: Bar0[A] with Bar1[This]] {
  // There has to be a method in Foo
  trait Foo { def f = ??? }
  // There has to be a private method with a closure in Reversed,
  // and it has to be a trait.
  trait Reversed extends Foo {
    private def g = { List(1) map (_ + 1) ; ??? }

Comment by Paul Phillips [ 14/Jul/12 ]

Here is a key-appearing excerpt from the diff between the non-crashing version where "def g" is public, and the crashing private version. < is private, > is public.

< [log erasure(->posterasure)] Destructively modifying owner of method g from trait Reversed to implementation class Reversed$class
> [log erasure(->posterasure)] Cloning method g for implementation method in implementation class Reversed$class

Comment by Lukas Rytz [ 14/Jul/12 ]

thanks for minimizing - how did you do that..? i found it very hard.

Comment by Paul Phillips [ 14/Jul/12 ]

Don't worry, so did I. I have no well-defined algorithm, just a reasonable knowledge of what is likely to matter. Shrink, see if it still crashes, ratchet down if so, try something else if not. I usually start by eliminating all possible type parameters, any expendable classes/traits, all the method bodies (replacing them with ???), and then see what's left.

But this one was a real standout in the difficulty department.

Comment by Lukas Rytz [ 16/Jul/12 ]

-Yno-generic-signatures can be used as a workaround since https://github.com/scala/scala/commit/93751072ef9ce684a5a8282bbf619f62736c30f4

Comment by Heejong Lee [ 22/Apr/13 ]

-Yno-generic-signatures didn't help in my case.
I still got a following exception from vanilla library source.

$ qbin/scalac -Yno-generic-signatures -sourcepath src/library -d sandbox -cp build/libs/classes/forkjoin:build/locker/classes/library src/library/scala/collection/SeqViewLike.scala src/library/scala/collection/GenSeqViewLike.scala
error: something is wrong: cannot make sense of type application
unhandled exception while transforming GenSeqViewLike.scala
error: uncaught exception during compilation: FatalError("
     while compiling: src/library/scala/collection/GenSeqViewLike.scala
        during phase: global=erasure, enteringPhase=explicitouter
     library version: version 2.11.0-20130421-223257-66ba223de5
    compiler version: version 2.11.0-20130421-223257-66ba223de5
  reconstructed args: -d sandbox -classpath build/libs/classes/forkjoin:build/locker/classes/library -Yno-generic-signatures -sourcepath src/library
  last tree to typer: TypeTree(trait Seq)
              symbol: trait Seq in package collection (flags: abstract <trait>)
   symbol definition: abstract trait Seq[+A] extends PartialFunction[Int,A] with Iterable[A] with GenSeq[A] with GenericTraversableTemplate[A,Seq] with SeqLike[A,Seq[A]]
                 tpe: Seq
       symbol owners: trait Seq -> package collection
      context owners: anonymous class $anonfun -> method createReversedIterator -> class Reversed$class -> trait GenSeqViewLike -> package collection

Comment by Paul Phillips [ 22/Apr/13 ]

Aha. Here we see the real benefit of rewrites like AsSeenFromMap. It is not the immediate benefit, but the fact that this time I was fairly easily able to diagnose and apparently fix this issue. Pull request or howl of angst to follow before long.

Comment by Paul Phillips [ 22/Apr/13 ]


Comment by Adriaan Moors [ 26/Apr/13 ]

The PR is somewhere between a fix and a workaround. Closing though I'd rather see a deeper fix that allows us to go back to comparing by symbol.

Generated at Wed Dec 12 22:42:51 CET 2018 using JIRA 7.9.1#79001-sha1:60970b42586a2ec2760ed6cfe825b26961e62b9e.