scalameta / metals

Scala language server with rich IDE features 🚀
https://scalameta.org/metals/
Apache License 2.0
2.09k stars 331 forks source link

type information missing in certain cases #5061

Closed andyczerwonka closed 10 months ago

andyczerwonka commented 1 year ago

I have a situation where most of the time, I do get type information when I hover over part of the code. In this one case, I don't see it. You will notice in the attached video, that I am getting types when hovering for everything except the values within the for comprehension.

type-information-error

I'm not sure how to debug this case.

Expected behavior

I would expect to see types show up when I hover over the values in the for comprehension.

Operating system

Linux

Editor/Extension

VS Code

Version of Metals

v0.11.11

Extra context or search terms

No response

tgodzik commented 1 year ago

Thanks for reporting! Any chance you could create a small reproduction? This is usually caused by the compiler not returning the correct information, might require some upstream fixes or workaround in metals.

What is the Scala version you are using? Any specific library? Maybe it also fails on an example project using that library?

andyczerwonka commented 1 year ago

Thanks for reporting! Any chance you could create a small reproduction? This is usually caused by the compiler not returning the correct information, might require some upstream fixes or workaround in metals.

What is the Scala version you are using? Any specific library? Maybe it also fails on an example project using that library?

Yeah, I was trying to reproduce, but I can't seem to. Is seems specific to a project using the Typelevel stack, in this case Cats Effect 3. We also have FS2 in the picture, so fairly heavy use of typeclasses and HKT's.

armanbilge commented 1 year ago

Are you using the better-monadic-for compiler plugin with Scala 2? Maybe that is related.

andyczerwonka commented 1 year ago

Yes we are, and I thought that may be the case too, but I have type information in other places where it is being injected. 🤷🏻

tgodzik commented 1 year ago

I realised that if you turn on semantic highlighting you might actually see where things start to go wrong. It will color everything in that place in one color (it uses the same mechanisms as hover). Not sure, but maybe it could help us out to pinpoint the issue?

andyczerwonka commented 1 year ago

@tgodzik Here it is with semantic highlighting turned on. It's not obvious to me, although color did change significantly.

image

tgodzik commented 1 year ago

Looks like it all starts with scope, which should probably be not shown as a variable. There are issues with that scope so the for comprehensions break as well :thinking:

I wonder if we could create something with a similar structure.

andyczerwonka commented 1 year ago

@tgodzik The scope case class is really simple.

case class RequestScope(
    user: UUID,
    principalId: UUID,
    principalType: String,
    uri: Uri,
    service: Option[String],
    bearerToken: Option[BearerToken] = None
)
tgodzik commented 1 year ago

Did you maybe see any exceptions in .metals/metals.log ? I think I haven't asked about that and we should see something breaking there :thinking:

andyczerwonka commented 1 year ago

I definitely tried that already, no exceptions in the logs.

andyczerwonka commented 1 year ago

I think it's related to the scope.toTypedRequestScope extension method.

  implicit class requestScopeOps(val requestScope: RequestScope) extends AnyVal {
    def toTypedRequestScope: Validated[ServiceError, TypedRequestScope] =
      TypedRequestScope.fromRequestScope(requestScope)
  }
tgodzik commented 1 year ago

I think we might need to report some more data on out side when hover info can't be found.

samspills commented 1 year ago

I think I'm experiencing the same issue with emacs+metals (v0.11.11) when working with DispatcherSpec.scala in cats-effect. Each spec refers to a dispatcher resource that is passed in, and it seems that type info is available in a spec before any reference to disaptcher and unavailable after the reference to dispatcher.

For example: in this test specifically, I get type info for results and gate and then nothing else.

There are no exceptions in metals.log that I can see.

kasiaMarek commented 1 year ago

A small reproduction of the issue:

// file: package.scala
package basepkg //in my case:  scala.meta

package object internal {
  type Intt = Int
}
// file: M.scala
package basepkg.internal //in my case:  scala.meta.internal

object M {
  val thisIsFine : Int = 3
  val hoverError : Intt = 3
}

The type is not resolved in the typed tree properly. Data from the report:

is error: false
symbol: value hoverError
tpe: <notype>

tree:
private[this] val <hoverError: error>: <error> = 3

full tree:
package scala.meta.internal {
  object M extends scala.AnyRef {
    def <init>(): scala.meta.internal.M.type = {
      M.super.<init>();
      ()
    };
    private[this] val thisIsFine: Int = 3;
    <stable> <accessor> def thisIsFine: Int = M.this.thisIsFine;
    private[this] val <hoverError: error>: <error> = 3;
    <stable> <accessor> def <hoverError: error>: <error> = M.this.<hoverError: error>
  }
}
kasiaMarek commented 1 year ago

The issue in the example given by @samspills is this error https://github.com/scala/bug/issues/12663. If there is a type definition in a package object and it is later used in the same package, presentation compiler fails to resolve that type correctly and produces an error. @andyczerwonka, can you confirm that this is also the root of your problem?

kasiaMarek commented 10 months ago

Closing as a duplicate: https://github.com/scalameta/metals/issues/4495. If that's not it @andyczerwonka, please reopen.