Wrong type shown on hover on method with `this.type` as param bound
Describe the bug
Write the following code:
val z: Tuple = ???
def m(x: Tuple) = x.zip(z)
Hover on zip
It shows:

Symbol signature:
inline def zip[This >: Tuple <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2]
Expected behavior
Expected signature:
inline def zip[This >: this.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2]
Source: https://github.com/lampepfl/dotty/blob/main/library/src/scala/Tuple.scala#L51
Operating system
macOS
Editor/Extension
VS Code
Version of Metals
0.11.9
Scala version
3.2.0
Extra context or search terms
This problem also occurs in other methods with this.type as param bounds, eg:
inline def take[This >: Tuple <: Tuple](n: Int): Take[This, n.type]
More minimal example:
object Main {
class T {
def meth@@od[This >: this.type <: T, T2 <: T](t2: T2): T = ???
}
}
Thanks for reporting! I think this is the way it's printed in the compiler actually :thinking: We might need to fix it upstream.
Wait, actually why would we want This >: this.type <: Tuple ?
To make things clear it should be noted that:
- singleton types (like
this.type) are distinct from non-singleton types - so e.g.
val x: Tuple = (1, 2, 3)
summon[x.type =:= Tuple]
won't compile. And we cannot lose this distinction in the IDE
- Metals performs substitutions of types which are already fixed in a given context and this makes sense: e.g.
this.typein
inline def zip[This >: this.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2]
doesn't tell you much without more context. Putting these two facts together I think the signature on hover in this case should be
inline def zip[This >: x.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2]
The question is whether this still should be called Symbol signature as in the actual signature of zip symbol there is Tuple.this in the bounds
I think the bounds are actually printed by the compiler, so this is probably something to fix there.