metals icon indicating copy to clipboard operation
metals copied to clipboard

Wrong details for `sliding` method

Open tgodzik opened this issue 2 years ago • 2 comments

Describe the bug

This shows up in the CompletionDocSuite:

  check(
    "scala1",
    """
      |object A {
      |  List(1).iterator.sliding@@
      |}
    """.stripMargin,
    """|sliding[B >: Int](size: Int, step: Int = 1): Iterator[Int]#GroupedIterator[B]
       |""".stripMargin,
    compat = Map(
      "3" ->
        """|sliding[B >: Int](size: Int, step: Int = 1): $1$.GroupedIterator[B]
           |""".stripMargin
    )
  )

There should ideally be no difference between the main expectation and the Scala 3 one

Expected behavior

Iterator[Int]#GroupedIterator[B] is shown.

Operating system

Linux

Editor/Extension

VS Code

Version of Metals

v0.11.5

Extra context or search terms

completions iterator sliding

tgodzik avatar May 13 '22 15:05 tgodzik

After https://github.com/scalameta/metals/pull/4922, the details are `List[Int]#iterator.GroupedIterator[B]. The objective of this task now changes to inspecting why it was behaving incorrectly in the fist place and why it changed.

kasiaMarek avatar Feb 10 '23 14:02 kasiaMarek

IN THE OLD VERSION:

The problem in created in substituteTypeVars (postProcess phase in Completions). If the head of the path is a select we substitute the type of completion by asSeenFrom select.qualifier.tpe. Where select.qualifier.tpe : TermRef(prefix = NoPrefix, myDesignator = val $1$) because the head of path is an odd select:

preBody = List(
  Block(
    stats = List(
      ValDef(
        name = DerivedName(underlying = , info = NumberedInfo(num = 1)),
        tpt = TypeTree[AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class collection)),trait Iterator),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)))],
        preRhs = Select(
          qualifier = Apply(
            fun = TypeApply(
              fun = Select(qualifier = Ident(name = List), name = apply),
              args = List(
                TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)]
              )
            ),
            args = List(
              Typed(
                expr = SeqLiteral(
                  elems = List(Literal(const = ( = 1))),
                  elemtpt = TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)]
                ),
                tpt = TypeTree[AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class <repeated>),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)))]
              )
            )
          ),
          name = iterator
        )
      )
    ),
    expr = Typed(
      expr = Block(
        stats = List(
          DefDef(
            name = $anonfun,
            paramss = List(
              List(
                ValDef(
                  name = size,
                  tpt = TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)],
                  preRhs = Thicket(trees = List())
                ),
                ValDef(
                  name = step,
                  tpt = TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)],
                  preRhs = Thicket(trees = List())
                )
              )
            ),
            tpt = TypeTree[AppliedType(TypeRef(TermRef(NoPrefix,val $1$),class GroupedIterator),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)))],
            preRhs = Apply(
              fun = TypeApply(
@@           head of path tree         @@
                fun = Select(
                  qualifier = Ident(
                    name = DerivedName(underlying = , info = NumberedInfo(num = 1))
                  ),
                  name = sliding
                ),
                args = List(
                  TypeTree[TypeVar(TypeParamRef(B) -> TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))]
                )
              ),
              args = List(Ident(name = size), Ident(name = step))
            )
          )
        ),
        expr = Closure(
          env = List(),
          meth = Ident(name = $anonfun),
          tpt = Thicket(trees = List())
        )
      ),
      tpt = TypeTree[AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),trait Function2),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int), TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int), AppliedType(TypeRef(AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class collection)),trait Iterator),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))),class GroupedIterator),List(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)))))]
    )
  )
)

IN THE NEW VERSION (with CURSOR):

select.qualifier.tpe:

TermRef(
  prefix = AppliedType(
    tycon = TypeRef(
      prefix = ThisType(tref = TypeRef(prefix = NoPrefix, myDesignator = module class immutable)),
      myDesignator = class List
    ),
    args = List(
      TypeRef(
        prefix = ThisType(tref = TypeRef(prefix = NoPrefix, myDesignator = module class scala)),
        myDesignator = class Int
      )
    )
  ),
  myDesignator = method iterator
)

In the new version the qualifier in select is more what we'd expect.

preBody = List(
@@  head of path  @@
  Select(
    qualifier = Select(
      qualifier = Apply(
        fun = TypeApply(
          fun = Select(qualifier = Ident(name = List), name = apply),
          args = List(
            TypeTree[TypeVar(TypeParamRef(A) -> TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))]
          )
        ),
        args = List(
          Typed(
            expr = SeqLiteral(
              elems = List(Literal(const = ( = 1))),
              elemtpt = TypeTree[TypeVar(TypeParamRef(A) -> TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))]
            ),
            tpt = TypeTree[AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class <repeated>),List(TypeVar(TypeParamRef(A) -> TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int))))]
          )
        )
      ),
      name = iterator
    ),
    name = slidingCURSOR
  )
)

I don't really understand why those trees look the way they do and how to handle such cases.

kasiaMarek avatar Mar 13 '23 13:03 kasiaMarek