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

Implicit conversion to function type produces incorrect symbol occurrence #1968

Open
ckipp01 opened this issue Nov 8, 2019 · 3 comments
Open

Comments

@ckipp01
Copy link
Member

ckipp01 commented Nov 8, 2019

Describe the bug
I've noticed this issue more lately where if I have for example the following small application...

object WebServer {

  def route = getDirectives {
    path("hello") {
      complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
    }
  }

  private lazy val getDirectives = get

  def main(args: Array[String]) {

    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    // needed for the future flatMap/onComplete in the end
    implicit val executionContext = system.dispatcher

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)

    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine() // let it run until user presses return
    bindingFuture
      .flatMap(_.unbind()) // trigger unbinding from the port
      .onComplete(_ => system.terminate()) // and shutdown when done
  }
}

I would expect that when I "goToDefinition" on get it would bring me to where it is defined. That's what it does in IntelliJ. However, in metals, it seems to bring me to the actual typeDefinition. For example, above it will end up leading me to the implicit def addByNameNullaryApply(directive: Directive0) in akka-land since indeed get is a Directive0. However, I don't want to go to the type definition, but to the position where get is defined.

I have a minimal project that illustrates this issue located here https://github.com/ckipp01/type-def-issue

To Reproduce
Steps to reproduce the behavior:

  1. Clone example issue project
  2. Compile
  3. Attempt to jump to definition on get
  4. 😢

Expected behavior
Would jump to where get is defined.

Installation:

  • Operating system: macOS
  • Editor: Visual Studio Code / Vim
  • Metals version: v0.7.6-SNAPSHOT

Search terms
goToDefinition

@olafurpg
Copy link
Member

olafurpg commented Feb 2, 2020

Thank you for reporting! This looks like a semanticdb-scalac bug.

I played around with setting up a worksheet in the Metals test suite to reproduce,

import scala.meta.interactive.InteractiveSemanticdb
val pc = InteractiveSemanticdb.newCompiler()

val x =
  InteractiveSemanticdb
    .toTextDocument(
      pc,
      """
package a
object a {
  implicit class RichInt(x: Int) {
    def soRich(other: Int) = x + other
  }

  val op = 1
  op soRich 2
}
  """,
      List("-P:semanticdb:synthetics:on", "-P:semanticdb:text:on")
    )

scala.meta.internal.mtags.Semanticdbs
  .printTextDocument(x)

pc.askShutdown()

Screenshot 2020-02-02 at 09 44 34

I see that method from akka-http has an advanced signature

akka-http/src/main/scala/akka/http/scaladsl/server/Directive.scala
150:  implicit def addByNameNullaryApply(directive: Directive0): (=> Route) => Route =

The first step would be to reproduce in a minimized code example with no external dependencies and open an issue in scalameta/scalameta

@olafurpg
Copy link
Member

olafurpg commented Feb 2, 2020

Closing this issue in favor of #1967

@olafurpg olafurpg closed this as completed Feb 2, 2020
@olafurpg olafurpg reopened this Feb 2, 2020
@olafurpg olafurpg transferred this issue from scalameta/metals Feb 2, 2020
@olafurpg olafurpg changed the title Incorrect goToDefinition Implicit conversion to function type produces incorrect symbol occurrence Feb 2, 2020
@olafurpg
Copy link
Member

olafurpg commented Feb 2, 2020

Realized I can transfer the issue.


SemanticDB v4.3.0

object a {
  implicit def addByNameNullaryApply(directive: Int): (=> Int) => Int = ???
  
  def bar(fn: (=> Int) => Int): Int = 42
  val get = 42
  get {
    42
  }}

Produces

-- obtained
++ expected
- get/*_empty_.a.addByNameNullaryApply().*/
+ get/*_empty_.a.get.*/

Reported originally by @ckipp01 in https://github.com/scalameta/metals/issues/1052

A good place to start investigating this issue would be to write a test case in TargetedSuite here

Next, look at all the places where occurrences is updated in TextDocumentOps

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

3 participants