scalameta / metals-feature-requests

Issue tracker for Metals feature requests
37 stars 4 forks source link

Add missing implicit parameter #105

Open kubukoz opened 4 years ago

kubukoz commented 4 years ago

Is your feature request related to a problem? Please describe. When working in a codebase with lots of implicits, e.g. using the tagless final technique, you find yourself adding implicit parameters or context bounds quite often when trying to use an interface you haven't used before.

Currently, when you make a call to such an interface, Metals will happily help you with an import on completion / in the quick fix, but you'll only have the type, not the value. The type needs to be added manually to the implicit parameter list (if there is one in the surrounding definitions) or the context bounds (if the missing implicit contains any of the type parameters of the surrounding definitions).

Describe the solution you'd like A quick fix available on positions with missing implicits.

Let's have an example:

trait Execution

trait Alg[F[_]] {
  def pure[A](x: A)(implicit e: Execution): F[A]
}

object Alg {
  def apply[F[_]](implicit F: Alg[F]): Alg[F] = F
}

trait Monoid[A] { def empty: A }

object Monoid {
  def empty[A](implicit A: Monoid[A]): A = A.empty
}

class Example[F[_]] {

  def instance[A]: F[A] =
    ???
}

This complies fine. Let's replace the placeholder with some references to some implicits:

-    ???
+    Alg[F].pure(Monoid.empty[A])

Now we get errors in two positions: at Alg[F] (missing implicit) and empty[A] (missing implicit):

image

If we add the necessary constraints, we'll also get an error due to the missing implicit Execution.

Some of the ways an inspection could help:

Ideally, the specifics on where to insert the parameter would be some sort of context menu separate from the short list of quick fixes (much like creating new Scala files in vscode), so that it's not polluted with too many options at once. Ideally, with a preview, but I underestand that might be much harder to implement.

Describe alternatives you've considered Manually adding required parameters to the desired location.

Additional context Some implicits might be harder to define as context bounds, for example MonadError[*[_], Throwable] (using kind-projector syntax). For these, we could start by only adding them as normal implicit parameters.

Search terms: Context bounds, type class constraints, effect polymorphic, cats-effect

tgodzik commented 4 years ago

Thanks for reporting! I agree that it would be useful indeed, but not sure how difficult it will be. If anyone wants to take a shot at this, we can try to help out.