metals icon indicating copy to clipboard operation
metals copied to clipboard

Type parameters from extension receiver not forwarded to completions in scala 3

Open prolativ opened this issue 2 years ago • 8 comments

Describe the bug

If the signature of a method added by an extension or an implicit conversion refers to a type parameter which should be fixed by the method receiver, the type is not substituted in code completions, e.g. for

extension[T](opt: Option[T])
  def append(x: T): Seq[T] = opt.toSeq :+ x

val x = Some(1).app@@

or

implicit class FooOps[T](opt: Option[T]):
  def append(x: T): Seq[T] = opt.toSeq :+ x

val x = Some(1).app@@

the suggested completion is

append(x: T): Seq[T]

Expected behavior

Type parameters from the extension receiver should be properly propagated, e.g. in the given example the suggested completion should be

append(x: Int): Seq[Int]

Operating system

No response

Editor/Extension

No response

Version of Metals

0.11.7+60-d9677cff-SNAPSHOT

Extra context or search terms

No response

prolativ avatar Jul 22 '22 08:07 prolativ

@prolativ Thanks for reporting!

I think it might be fixed only on compiler side. I already did a similar work with providing a correct type for member completion - https://github.com/scalameta/metals/blob/d9677cff9df3cbd3af977470e3513334abd74b53/mtags/src/main/scala-3/scala/meta/internal/pc/completions/Completions.scala#L482-L502

However, after trying to do the same for extension methods and implicit conversion I realized that it's not possible to do on Metals side. The issue is that returned symbol from interactive.Completion carries the detonation that provides only original symbol type with abstract types.

dos65 avatar Jul 22 '22 09:07 dos65

I think we could do 2 things:

  • copy over the logic from https://github.com/lampepfl/dotty/pull/11187/files or try to reuse it in some way
  • make the interface for completions a bit better (@prolativ already raised na issue): https://github.com/lampepfl/dotty/issues/15730. We can use it for the newer versions of compiler

tgodzik avatar Jul 22 '22 11:07 tgodzik

@tgodzik @prolativ I would choose to not to change interfaces. Actually, the are good enough to use. The issue is that by some reason we are getting a symbol with not-precise denot or info. But it's possible to fix

We can reuse this thing that we have in metals: https://github.com/scalameta/metals/blob/d9677cff9df3cbd3af977470e3513334abd74b53/mtags/src/main/scala-3/scala/meta/internal/mtags/MtagsEnrichments.scala#L132-L146

dos65 avatar Jul 22 '22 12:07 dos65

The point is that in a case like this it's impossible to get the full type signature from a symbol - one needs the entire typed tree of the extension receiver

prolativ avatar Jul 22 '22 12:07 prolativ

@prolativ but it's possible on dotty side. I only meant that it would be nice to change public interfaces

dos65 avatar Jul 22 '22 13:07 dos65

I would choose to not to change interfaces it would be nice to change public interfaces Now I'm quite confused which solution you would prefer 😕

prolativ avatar Jul 22 '22 13:07 prolativ

opps :smile:

I mean do NOT to change

dos65 avatar Jul 22 '22 13:07 dos65

I think it wouldn't be a big problem to add a new endpoint in the compiler without removing the old one as that would be just splitting the logic into two parts and exposing the intermediate results of completions

prolativ avatar Jul 22 '22 13:07 prolativ

This is actually fixed with https://github.com/lampepfl/dotty/pull/18914

rochala avatar Feb 29 '24 13:02 rochala