Skip to content

Commit 5f50490

Browse files
authored
fix: simplify infer type for apply (#23434)
fixes: scalameta/metals#7538 fixes: scalameta/metals#7564 fixes: scalameta/metals#7567 ~I made the change, so infer type would reuse signature help.~ Actually there was a way simpler way to do this.
2 parents 675a43b + 44366a0 commit 5f50490

File tree

4 files changed

+106
-35
lines changed

4 files changed

+106
-35
lines changed

presentation-compiler/src/main/dotty/tools/pc/InferExpectedType.scala

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ class InferExpectedType(
5050
val indexedCtx = IndexedContext(pos)(using locatedCtx)
5151
val printer =
5252
ShortenedTypePrinter(search, IncludeDefaultParam.ResolveLater)(using indexedCtx)
53-
InterCompletionType.inferType(path)(using newctx).map{
53+
InferCompletionType.inferType(path)(using newctx).map{
5454
tpe => printer.tpe(tpe)
5555
}
5656
case None => None
5757

58-
object InterCompletionType:
58+
object InferCompletionType:
5959
def inferType(path: List[Tree])(using Context): Option[Type] =
6060
path match
6161
case (lit: Literal) :: Select(Literal(_), _) :: Apply(Select(Literal(_), _), List(s: Select)) :: rest if s.symbol == defn.Predef_undefined => inferType(rest, lit.span)
@@ -94,37 +94,7 @@ object InterCompletionType:
9494
else Some(UnapplyArgs(fun.tpe.finalResultType, fun, pats, NoSourcePosition).argTypes(ind))
9595
// f(@@)
9696
case ApplyExtractor(app) =>
97-
val argsAndParams = ApplyArgsExtractor.getArgsAndParams(None, app, span).headOption
98-
argsAndParams.flatMap:
99-
case (args, params) =>
100-
val idx = args.indexWhere(_.span.contains(span))
101-
val param =
102-
if idx >= 0 && params.length > idx then Some(params(idx).info)
103-
else None
104-
param match
105-
// def f[T](a: T): T = ???
106-
// f[Int](@@)
107-
// val _: Int = f(@@)
108-
case Some(t : TypeRef) if t.symbol.is(Flags.TypeParam) =>
109-
for
110-
(typeParams, args) <-
111-
app match
112-
case Apply(TypeApply(fun, args), _) =>
113-
val typeParams = fun.symbol.paramSymss.headOption.filter(_.forall(_.isTypeParam))
114-
typeParams.map((_, args.map(_.tpe)))
115-
// val f: (j: "a") => Int
116-
// f(@@)
117-
case Apply(Select(v, StdNames.nme.apply), _) =>
118-
v.symbol.info match
119-
case AppliedType(des, args) =>
120-
Some((des.typeSymbol.typeParams, args))
121-
case _ => None
122-
case _ => None
123-
ind = typeParams.indexOf(t.symbol)
124-
tpe <- args.get(ind)
125-
if !tpe.isErroneous
126-
yield tpe
127-
case Some(tpe) => Some(tpe)
128-
case _ => None
97+
val idx = app.args.indexWhere(_.span.contains(span))
98+
app.fun.tpe.widenTermRefExpr.paramInfoss.flatten.get(idx)
12999
case _ => None
130100

presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ class Completions(
520520
config.isCompletionSnippetsEnabled()
521521
)
522522
(args, false)
523-
val singletonCompletions = InterCompletionType.inferType(path).map(
523+
val singletonCompletions = InferCompletionType.inferType(path).map(
524524
SingletonCompletions.contribute(path, _, completionPos)
525525
).getOrElse(Nil)
526526
(singletonCompletions ++ advanced, exclusive)

presentation-compiler/test/dotty/tools/pc/tests/InferExpectedTypeSuite.scala

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ class InferExpectedTypeSuite extends BasePCSuite:
4747
|""".stripMargin
4848
)
4949

50+
@Test def `basic-params` =
51+
check(
52+
"""|def paint(c: Int, f: String, d: List[String]) = ???
53+
|val _ = paint(1, "aa", @@)
54+
|""".stripMargin,
55+
"""|List[String]
56+
|""".stripMargin
57+
)
58+
59+
@Test def `basic-type-param` =
60+
check(
61+
"""|def paint[T](c: T) = ???
62+
|val _ = paint[Int](@@)
63+
|""".stripMargin,
64+
"""|Int
65+
|""".stripMargin
66+
)
67+
5068
@Test def `type-ascription` =
5169
check(
5270
"""|def doo = (@@ : Double)
@@ -335,3 +353,60 @@ class InferExpectedTypeSuite extends BasePCSuite:
335353
"""|String
336354
|""".stripMargin
337355
)
356+
357+
@Test def using =
358+
check(
359+
"""|def go(using Ordering[Int])(x: Int, y: Int): Int =
360+
| Ordering[Int].compare(x, y)
361+
|
362+
|def test =
363+
| go(???, @@)
364+
|""".stripMargin,
365+
"""|Int
366+
|""".stripMargin
367+
)
368+
369+
@Test def `apply-dynamic` =
370+
check(
371+
"""|object TypedHoleApplyDynamic {
372+
| val obj: reflect.Selectable {
373+
| def method(x: Int): Unit
374+
| } = new reflect.Selectable {
375+
| def method(x: Int): Unit = ()
376+
| }
377+
|
378+
| obj.method(@@)
379+
|}
380+
|""".stripMargin,
381+
"Int"
382+
)
383+
384+
@Test def `apply-dynamic-2` =
385+
check(
386+
"""|object TypedHoleApplyDynamic {
387+
| val obj: reflect.Selectable {
388+
| def method[T](x: Int, y: T): Unit
389+
| } = new reflect.Selectable {
390+
| def method[T](x: Int, y: T): Unit = ()
391+
| }
392+
|
393+
| obj.method[String](1, @@)
394+
|}
395+
|""".stripMargin,
396+
"String"
397+
)
398+
399+
@Test def `apply-dynamic-3` =
400+
check(
401+
"""|object TypedHoleApplyDynamic {
402+
| val obj: reflect.Selectable {
403+
| def method[T](a: Int)(x: Int, y: T): Unit
404+
| } = new reflect.Selectable {
405+
| def method[T](a: Int)(x: Int, y: T): Unit = ()
406+
| }
407+
|
408+
| obj.method[String](1)(1, @@)
409+
|}
410+
|""".stripMargin,
411+
"String"
412+
)

presentation-compiler/test/dotty/tools/pc/tests/completion/SingletonCompletionsSuite.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,30 @@ class SingletonCompletionsSuite extends BaseCompletionSuite {
297297
"""|"foo": "foo"
298298
|""".stripMargin
299299
)
300+
301+
@Test def `type-apply` =
302+
check(
303+
"""|class Consumer[A]:
304+
| def eat(a: A) = ()
305+
|
306+
|def test =
307+
| Consumer[7].eat(@@)
308+
|""".stripMargin,
309+
"7: 7",
310+
topLines = Some(1)
311+
)
312+
313+
@Test def `type-apply-2` =
314+
check(
315+
"""|class Consumer[A]:
316+
| def eat(a: A) = ()
317+
|
318+
|object Consumer7 extends Consumer[7]
319+
|
320+
|def test =
321+
| Consumer7.eat(@@)
322+
|""".stripMargin,
323+
"7: 7",
324+
topLines = Some(1)
325+
)
300326
}

0 commit comments

Comments
 (0)