Skip to content

Commit 26fc7ca

Browse files
committed
Workaround symbol not found for HKTypeLambda in upper bounds
and fix type for curried applied type
1 parent 5913b02 commit 26fc7ca

File tree

4 files changed

+57
-8
lines changed

4 files changed

+57
-8
lines changed

compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class TypeOps:
2222
private val refinementSymtab = mutable.Map[(RefinedType, Name), Symbol]()
2323
given typeOps: TypeOps = this
2424

25-
extension [T <: Type](symtab: mutable.Map[(T, Name), Symbol])
25+
extension [T <: LambdaType | RefinedType](symtab: mutable.Map[(T, Name), Symbol])
2626
private def getOrErr(binder: T, name: Name, parent: Symbol)(using Context): Option[Symbol] =
2727
// In case refinement or type param cannot be accessed from traverser and
2828
// no symbols are registered to the symbol table, fall back to Type.member
@@ -33,12 +33,25 @@ class TypeOps:
3333
if sym.exists then
3434
Some(sym)
3535
else
36-
symbolNotFound(binder, name, parent)
37-
None
36+
binder match {
37+
// In case symtab and Type.member failed to find the symbol
38+
// e.g. `class HKClass[F <: [T] =>> [U] =>> (U, T)]`
39+
// and if the binder is HKTypeLambda, fallback to create fake symbol
40+
case lam: HKTypeLambda =>
41+
lam.paramNames.zip(lam.paramInfos).toMap.get(name) match
42+
case Some(info) =>
43+
Some(newSymbol(parent, name, Flags.TypeParam, info))
44+
case None =>
45+
symbolNotFound(binder, name, parent)
46+
None
47+
case _ =>
48+
symbolNotFound(binder, name, parent)
49+
None
50+
}
3851

3952
private def symbolNotFound(binder: Type, name: Name, parent: Symbol)(using ctx: Context): Unit =
4053
report.warning(
41-
s"""Internal error in extracting SemanticDB while compiling ${ctx.compilationUnit.source}: Ignoring ${name} of type ${binder}"""
54+
s"""Internal error in extracting SemanticDB while compiling ${ctx.compilationUnit.source}: Ignoring ${name} of symbol ${parent}, type ${binder}"""
4255
)
4356

4457
extension (tpe: Type)
@@ -319,8 +332,12 @@ class TypeOps:
319332
val sargs = targs.map(_._2)
320333

321334
val applied = loop(tycon) match
322-
case ref: s.TypeRef => ref.copy(typeArguments = sargs)
323-
case _ => s.Type.Empty
335+
case ref @ s.TypeRef(_, _, targs) =>
336+
// For curried applied type `F[T][U]` and tycon is also an `AppliedType`
337+
// Convert it to TypeRef(..., targs = List(T, U))
338+
ref.copy(typeArguments = targs ++ sargs)
339+
case _ =>
340+
s.Type.Empty
324341

325342
if (wildcardSyms.isEmpty) applied
326343
else s.ExistentialType(

tests/semanticdb/expect/Advanced.expect.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ object Test/*<-advanced::Test.*/ {
4242
}
4343
}
4444
}
45+
46+
47+
// Curried Type Application
48+
class HKClass/*<-advanced::HKClass#*/[F/*<-advanced::HKClass#[F]*/ <: [T] =>> [U] =>> (U, T)] {
49+
def foo/*<-advanced::HKClass#foo().*/[T/*<-advanced::HKClass#foo().[T]*/,U/*<-advanced::HKClass#foo().[U]*/](x/*<-advanced::HKClass#foo().(x)*/: F/*->advanced::HKClass#[F]*/[T/*->advanced::HKClass#foo().[T]*/][U/*->advanced::HKClass#foo().[U]*/]): String/*->scala::Predef.String#*/ = x/*->advanced::HKClass#foo().(x)*/.toString/*->scala::Tuple2#toString().*/()
50+
}

tests/semanticdb/expect/Advanced.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ object Test {
4242
}
4343
}
4444
}
45+
46+
47+
// Curried Type Application
48+
class HKClass[F <: [T] =>> [U] =>> (U, T)] {
49+
def foo[T,U](x: F[T][U]): String = x.toString()
50+
}

tests/semanticdb/metac.expect

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,21 @@ Schema => SemanticDB v4
4949
Uri => Advanced.scala
5050
Text => empty
5151
Language => Scala
52-
Symbols => 38 entries
53-
Occurrences => 100 entries
52+
Symbols => 45 entries
53+
Occurrences => 113 entries
5454

5555
Symbols:
5656
advanced/C# => class C [typeparam T ] extends Object { self: C[T] => +3 decls }
5757
advanced/C#[T] => typeparam T
5858
advanced/C#`<init>`(). => primary ctor <init> [typeparam T ](): C[T]
5959
advanced/C#t(). => method t => T
60+
advanced/HKClass# => class HKClass [typeparam F [unknown T: <?>] <: <?>] extends Object { self: HKClass[F] => +3 decls }
61+
advanced/HKClass#[F] => typeparam F [unknown T: <?>] <: <?>
62+
advanced/HKClass#`<init>`(). => primary ctor <init> [typeparam F [unknown T: <?>] <: <?>](): HKClass[F]
63+
advanced/HKClass#foo(). => method foo [typeparam T , typeparam U ](param x: F[T, U]): String
64+
advanced/HKClass#foo().(x) => param x: F[T, U]
65+
advanced/HKClass#foo().[T] => typeparam T
66+
advanced/HKClass#foo().[U] => typeparam U
6067
advanced/Structural# => class Structural extends Object { self: Structural => +5 decls }
6168
advanced/Structural#`<init>`(). => primary ctor <init> (): Structural
6269
advanced/Structural#s1(). => method s1 => Object { abstract val method x Int }
@@ -193,6 +200,19 @@ Occurrences:
193200
[39:12..39:15): e3x <- local17
194201
[39:18..39:20): e3 -> local15
195202
[39:21..39:25): head -> scala/collection/IterableOps#head().
203+
[47:6..47:13): HKClass <- advanced/HKClass#
204+
[47:13..47:13): <- advanced/HKClass#`<init>`().
205+
[47:14..47:15): F <- advanced/HKClass#[F]
206+
[48:6..48:9): foo <- advanced/HKClass#foo().
207+
[48:10..48:11): T <- advanced/HKClass#foo().[T]
208+
[48:12..48:13): U <- advanced/HKClass#foo().[U]
209+
[48:15..48:16): x <- advanced/HKClass#foo().(x)
210+
[48:18..48:19): F -> advanced/HKClass#[F]
211+
[48:20..48:21): T -> advanced/HKClass#foo().[T]
212+
[48:23..48:24): U -> advanced/HKClass#foo().[U]
213+
[48:28..48:34): String -> scala/Predef.String#
214+
[48:37..48:38): x -> advanced/HKClass#foo().(x)
215+
[48:39..48:47): toString -> scala/Tuple2#toString().
196216

197217
expect/Annotations.scala
198218
------------------------

0 commit comments

Comments
 (0)