Presentation compiler autocompletion bug with dependent types

#1

There seems to be an issue with the autocompletion in the presentation compiler. It’s a bit of an edge case, I guess that’s why it wasn’t discovered yet: Autocompletion fails when using dependent types AND omitting the (empty) first parameter block. You can reproduce it in the repl as follows:

object Test1 {
  trait Conv[In] {
    type Out
    def apply(in: In): Out
  }
  object Conv {
    type Aux[In, Out0] = Conv[In] { type Out = Out0 }
    implicit val int2String = new Conv[Int] {
      type Out = String
      override def apply(i: Int) = i.toString
    }
  }

  def withParens[Out]()(implicit conv: Conv.Aux[Int, Out]): Out = "5".asInstanceOf[Out]
  def withoutParens[Out](implicit conv: Conv.Aux[Int, Out]): Out = "5".asInstanceOf[Out]
}

Then type Test1.withParens().<TAB> - it does find autocompletions for String. However, if you try Test1.withoutParens.<TAB> it does not. As a workaround, when saving intermediate result, it works:
val a = Test1.withoutParens; a.<TAB>

Without dependent types, autocompletion works fine in both cases:

object Test2 {
  trait A
  implicit val a: A = ???
  def withParens()(implicit a: A): String = "something"
  def withoutParens(implicit a: A): String = "something"
}

The best solution would be to fix this in the presentation compiler, but I didn’t manage to pin down the problem there. Instead, as a workaround, I patched the repl autocompletion - if it doesn’t find any autocompletions, it interprets the code up until that point and then tries again. Here’s a mini repo that’s using the presentation compiler and the patched autocompletion:


If you use PresentationCompilerCompleter instead of MyPresentationCompilerCompleter in the test, you get the old behaviour (no autocompletion).

Can someone help me fix this in the presentation compiler?
If not, should we bring an improved version of my workaround into the PresentationCompilerCompleter?
Any other ideas?

Cheers
Michael

PS: should this move to https://github.com/scala/bug/issues ?

#2

Thanks for the detailed analysis!

I’ve prototyped a fix for the REPL autocompletion here: https://github.com/retronym/scala/tree/topic/completion-depmet-implicit

It needs a bit more work to see if the fix should really be pushed into typeMembers, rather than having the if/else in completionsAt. A good litmus test would be to try to reproduce the bug in Scala IDE. If that also fails to autocomplete, the root problem is likely in typeMembers, which is finding members of the type of the smallest tree that encloses the search position. There are two trees with the same range position: ApplyImplicitArgs(Select(...), args), andlocatefinds the innerSelect`. Not sure why the dependent types figure into the equation yet.

Probably a good idea to move this over to a bug. If you’d like to dig in to this (adding more tests, checking Scala IDE behaviour), just say so on the ticket. Otherwise I’ll add this to my list :slight_smile:

#3

Thanks for looking into this.

I just moved it to https://github.com/scala/bug/issues/10353
I’m happy to dig in here, please let me know what I can do. Just tested with ScalaIDE and Ensime, both show the same behaviour.