bug icon indicating copy to clipboard operation
bug copied to clipboard

Error tpe obtained for type alias defined in package object

Open kpodsiad opened this issue 3 years ago • 7 comments

Issue originally raised in Metals - https://github.com/scalameta/metals/issues/4495

Reproduction steps

Scala version: 2.13.8, 2.13.9, probably earlier ones too

Here's repo with reproduction.

a/package.scala

package object a {
  type FancyInt = Int
}

a/Main.scala

package a
object Main extends App {
  def foo(n: FancyInt, k: Int): Unit = {
    n
    k
  }
}

Problem

There are no completions for type alias Screenshot 2022-10-07 at 07 28 13 Screenshot 2022-10-07 at 07 30 32

I initially thought that this is the problem with Metals but @tgodzik created a testcase with reproduction https://github.com/scalameta/metals/compare/main...tgodzik:metals:add-test?expand=1 which shows that this is the compiler issue.

This is what Metals gets from compiler:

CompletionProvider.scala:451 typeMembers: List(
  ScopeMember(
    sym = value n,
    tpe = <error>,
    accessible = true,
    viaImport = <empty>,
    aliasInfo = None
  ),
  ScopeMember(
    sym = value k,
    tpe = TypeRef(pre = ThisType(sym = package scala), sym = class Int, args = List()),
    accessible = true,
    viaImport = <empty>,
    aliasInfo = None
  ),
...

note tpe = <error> for n whereas k has correct tpe.

kpodsiad avatar Oct 10 '22 18:10 kpodsiad

It seems that the issue only happens if we usage the symbol within the same package.

tgodzik avatar Oct 10 '22 19:10 tgodzik

The REPL effect:

scala> :paste -raw
// Entering paste mode (ctrl-D to finish)

package object p { type I = Int }


// Exiting paste mode, now interpreting.


scala> p.I.
I         package

I cut/pasted a pc test.

package object p {
  type I = Int
}
package p {
  object Main extends App {
    def i: I = 42
    def f = i./*!*/
  }
}
reload: Snippet.scala

askTypeCompletion at Snippet.scala(8,14)
================================================================================
[response] askTypeCompletion at (8,14)
retrieved 205 members
[inaccessible] protected def num: Fractional[Double]
[inaccessible] protected def ord: Ordering[Double]
[inaccessible] protected def unifiedPrimitiveEquals(x: Any): Boolean
[inaccessible] protected def unifiedPrimitiveHashcode: Int
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
def !=(x: Byte): Boolean
def !=(x: Char): Boolean
def !=(x: Double): Boolean
def !=(x: Float): Boolean
def !=(x: Int): Boolean
def !=(x: Long): Boolean
def !=(x: Short): Boolean

som-snytt avatar Oct 11 '22 08:10 som-snytt

This only seem to happen when they are located within a separate file and the input to the compiler is an actual compiled classfile.

tgodzik avatar Oct 11 '22 09:10 tgodzik

Thanks, the pc test "just works" when splitting the package object into its own "compilation round" and indeed shows no completions. I'll take a look despite/because not knowing anything about it.

+reload: Snippet.scala
+
+askTypeCompletion at Snippet.scala(5,14)
+================================================================================
+[response] askTypeCompletion at (5,14)
+retrieved 0 members
+
+================================================================================

som-snytt avatar Oct 11 '22 17:10 som-snytt