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

Type incompatibility combining inner classes and abstract overrides #5685

Closed
scabug opened this issue Apr 19, 2012 · 2 comments
Closed

Type incompatibility combining inner classes and abstract overrides #5685

scabug opened this issue Apr 19, 2012 · 2 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Apr 19, 2012

trait X[A] {
  def x: A
}

trait XPrint[A] extends X[A] {
  abstract override def x: A = {
    val a = super.x
    println(a)
    a
  }
}

trait F[A, B] { outer =>
  def apply(xv: X[A]): X[B]
  
  def andThen[C](f: F[B, C]): F[A, C] = new F[A, C] {
    def apply(xv: X[A]): X[C] = f(new XX(xv) with XPrint[B])
  }

  class XX(xv: X[A]) extends X[B] {
    def x = outer(xv).x
  }
}

This fails to compile with the following error:

Test.scala:18: error: type mismatch;
 found   : this.XX with XPrint[B]
 required: X[B]

    def apply(xv: X[A]): X[C] = f(new XX(xv) with XPrint[B])
                                  ^
one error found

I thought a variance issue might be to blame, but changing A to be covariant gives another interesting error:

trait X[+A] {
  def x: A
}

trait XPrint[+A] extends X[A] {
  abstract override def x: A = {
    val a = super.x
    println(a)
    a
  }
}

trait F[-A, +B] { outer =>
  def apply(xv: X[A]): X[B]
  
  def andThen[C](f: F[B, C]): F[A, C] = new F[A, C] {
    def apply(xv: X[A]): X[C] = f(new XX(xv) with XPrint[B])
  }

  class XX(xv: X[A]) extends X[B] {
    def x = outer(xv).x
  }
}

gives the following:

Test.scala:18: error: illegal inheritance;
 anonymous class $anon inherits different type instances of trait X:
X[B] and X[C]
    def apply(xv: X[A]): X[C] = f(new XX(xv) with XPrint[B])
                                      ^
one error found

This is similar to the error I encountered in the original, non-minimized case. In the original case, however, the type parameters were invariant throughout; also, there is a related crasher that I've been unable to reproduce in a minimized case; in the crash, I get the following error, which provides no indication of the original source of the error:

[info] Compiling 2 Scala sources to /home/workspace/kjn-storage/platform/yggdrasil/target/scala-2.9.1/classes...
[error] {file:/home/workspace/kjn-storage/platform/}yggdrasil/compile:compile: scala.tools.nsc.symtab.Types$TypeError: type mismatch;
[error]  found   : com.precog.yggdrasil.Column[Boolean]
[error]  required: com.precog.yggdrasil.Column[A]
[error] Total time: 3 s, completed Apr 19, 2012 10:01:17 PM

In that original error case, the XX class was declared inside of the anonymous F; in the minimized case, moving the XX class inside of the anonymous F eliminates the two errors first noted.

@scabug
Copy link
Author

scabug commented Apr 19, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5685?orig=1
Reporter: Kris Nuttycombe (nuttycom)
Affected Versions: 2.9.0, 2.10.0-M2

@scabug
Copy link
Author

scabug commented May 5, 2012

@paulp said:
Well, it took me a long time to see it. No more letting me do your debugging for you, kris!

  new F[A, C] {
    def apply(xv: X[A]): X[C] = f(new XX(xv) with XPrint[B])
  }

Since you're inside an anonymous F, that new XX is in the F[A, C] being created. You want "new outer.XX(sv)" at which point it compiles as given (with or without variance.)

@scabug scabug closed this as completed May 5, 2012
@scabug scabug added this to the 2.10.0-M3 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