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

dependently-typed constructors do not correctly propagate type information to type members #5700

Closed
scabug opened this issue Apr 23, 2012 · 4 comments

Comments

@scabug
Copy link

scabug commented Apr 23, 2012

It appears that dependent types do not correctly propagate through constructors:

trait Foo { type FA }
class Bar(val foo: Foo) {
  type FA = foo.FA
}

object Test {
  def main(argv: Array[String]) {
    val barLong: Bar { type FA = Long } = new Bar(new Foo { type FA = Long })
  }
}

This always tries to derive the "raw" type for Bar:

[nuttycom@yggdrasil dependent_case_class]$ ~/bin/scala-2.10.0-M2/bin/scalac -Xexperimental Test.scala 
Test.scala:8: error: type mismatch;
 found   : Bar
 required: Bar{type FA = Long}
    val barLong: Bar { type FA = Long } = new Bar(new Foo { type FA = Long })

Variants don't appear to work either:

[nuttycom@yggdrasil dependent_case_class]$ cat Test.scala 
trait Foo { type FA }
class Bar(val foo: Foo) {
  type FA = foo.FA
}

object Test {
  def main(argv: Array[String]) {
    val barLong: Bar { type FA = Long } = new Bar(new Foo { type FA = Long }) {
      override type FA = Long
    }
  }
}

// vim: set ts=4 sw=4 et:
[nuttycom@yggdrasil dependent_case_class]$ ~/bin/scala-2.10.0-M2/bin/scalac -Xexperimental Test.scala 
Test.scala:9: error: overriding type FA in class Bar, which equals this.foo.FA;
 type FA has incompatible type
      override type FA = Long
                    ^
one error found
@scabug
Copy link
Author

scabug commented Apr 23, 2012

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

@scabug
Copy link
Author

scabug commented Dec 24, 2012

@paulp said:
I don't think this is a bug. Class Bar exposes "val foo: Foo". The extra type information does not cross that boundary. If it were "val foo: Any", you wouldn't be surprised when you passed in a String and still couldn't use it as a String. This is the same.

Both of these work:

// option 1, provide an avenue for more type information
class Bar[F <: Foo](val foo: F) 

// option 2, subclass and refine the type
def newBar[T <: Foo](x: T) = {
  class Bar1(override val foo: T = x) extends Bar(foo)
  new Bar1(x)
}

@scabug
Copy link
Author

scabug commented Dec 24, 2012

@paulp said:
Closing as not a bug unless someone wants to argue otherwise.

@scabug scabug closed this as completed Dec 24, 2012
@scabug
Copy link
Author

scabug commented Dec 26, 2012

@adriaanm said:
agreed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants