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 check failed with an error message "found : w.F; required: w.F" #9878

Closed
scabug opened this issue Aug 2, 2016 · 7 comments
Closed

Type check failed with an error message "found : w.F; required: w.F" #9878

scabug opened this issue Aug 2, 2016 · 7 comments

Comments

@scabug
Copy link

scabug commented Aug 2, 2016

Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait A {
  type Self >: this.type <: A
}

case class W(f: A) { outer =>
  type F = f.Self
  def selfF: F = f: f.Self
  type Self = W {
    type F = outer.F
  }

  def error(w: Self) = {
    val wF: w.F = w.selfF
  }
}

// Exiting paste mode, now interpreting.

<console>:23: error: type mismatch;
 found   : w.F
    (which expands to)  w.f.Self
 required: w.F
    (which expands to)  W.this.f.Self
           val wF: w.F = w.selfF
                           ^
@scabug
Copy link
Author

scabug commented Aug 2, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9878?orig=1
Reporter: @Atry
Affected Versions: 2.11.8

@scabug
Copy link
Author

scabug commented Aug 2, 2016

@SethTisue said:
would you agree this illustrates the same issue, but with less code?

class W[T <: AnyRef](val f: T) {
  type F = f.type
  type SelfW = W[T] { type F = W.this.F }
  def error(w: SelfW) = w.f: w.F
}

S.scala:4: error: type mismatch;
 found   : w.f.type (with underlying type T)
 required: w.F
    (which expands to)  W.this.f.type
  def error(w: SelfW) = w.f: w.F
                          ^
one error found

@scabug
Copy link
Author

scabug commented Aug 3, 2016

@Atry said:
Your example is similar, but less ridiculous.

@scabug
Copy link
Author

scabug commented Aug 21, 2016

@SethTisue said:
Well, I think my example isn't a bug, actually – the compiler has no guarantee that the two instances of W share the same f.

Your example is so complicated, I don't know what it is. I think it's unlikely it will get attention unless you can simplify it.

@scabug
Copy link
Author

scabug commented Aug 21, 2016

@SethTisue said:
Hmm, now I'm wondering.... are you actually saying your original code should compile, or are you just reporting that the error message is confusing?

The error message is confusing, I'll give you that. But I very much doubt that your code is correct. I think you may have an incorrect idea of what it means to "override" a type in a type alias. Scala will let you write e.g.:

trait A { type T = Int ; def f: T = 3 }
type U = A { type T = String }

but that doesn't mean that in U, you have somehow changed the type of f. The type of f is still Int.

By the same token, in your code you write:

type Self = W { type F = outer.F }

but that doesn't mean that if I have a value w of type Self, def w.selfF is constrained to be outer.F!

@scabug
Copy link
Author

scabug commented Aug 23, 2016

@Atry said (edited on Aug 23, 2016 6:17:30 AM UTC):
The type T in your example is a concrete type, while the type Self and F in my original example are abstract types.

Scalac does change the type in expression def f: T so long as T is an abstract type. For example:

Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.

scala> trait A { type T; def f: T }
defined trait A

scala> type U = A { type T = String }
defined type alias U

scala> new A { type T = String; def f = "f" }
res0: A{type T = String} = $anon$1@68f7aae2

scala> res0: U
res1: U = $anon$1@68f7aae2

scala> res1.f.substring(0, 1) // res1.f is a String 
res2: String = f

@scabug
Copy link
Author

scabug commented Aug 23, 2016

@SethTisue said:
{quote}the type Self and F in my original example are abstract types{quote}

It seems to me that Self is abstract but F is not — F is a type alias. See SLS 4.3.

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

1 participant