Skip to content

Commit a5566ac

Browse files
authored
fix(tolk/resolving): fix method resolving for generic structs (#25)
Fixes #18
1 parent d26d0d1 commit a5566ac

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

server/src/e2e/tolk/testcases/resolving/instance-methods.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,23 @@ fun main(): void {
333333
7:4 -> 0:5 resolved
334334
8:9 -> 2:13 resolved
335335
10:4 -> 4:4 resolved
336+
337+
========================================================================
338+
Instance methods for generic
339+
========================================================================
340+
struct First<T> {}
341+
fun First<T>.new(): First<T> {}
342+
343+
struct Second<T> {}
344+
fun Second<T>.new(): Second<T> {}
345+
fun Second<int>.new(): Second<int> {}
346+
347+
fun main() {
348+
val first = First<int>.<caret>new();
349+
val second = Second<int>.<caret>new();
350+
val third = Second<slice>.<caret>new();
351+
}
352+
------------------------------------------------------------------------
353+
8:27 -> 1:13 resolved
354+
9:29 -> 5:16 resolved
355+
10:30 -> 4:14 resolved

server/src/languages/tolk/type-inference.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,13 +1142,23 @@ class InferenceWalker {
11421142
}
11431143

11441144
// step 3: try to match generic receivers, e.g. `Container<T>.copy` / `(T?|slice).copy` but NOT `T.copy`
1145+
const qualifierBaseType = qualifierType.baseType()
11451146
this.processMethods(searchName, method => {
11461147
const receiverTypeNode = method.receiverTypeNode()
11471148
if (!receiverTypeNode) return true
11481149
const receiverType = typeOf(receiverTypeNode, method.file)
11491150

11501151
// Foo<T>, but not T
11511152
if (receiverType?.hasGenerics() && !(receiverType instanceof TypeParameterTy)) {
1153+
const receiverBaseType = receiverType.baseType()
1154+
1155+
if (qualifierBaseType instanceof StructTy && receiverBaseType instanceof StructTy) {
1156+
if (!qualifierBaseType.equals(receiverBaseType)) {
1157+
// different struct names
1158+
return true
1159+
}
1160+
}
1161+
11521162
const subst = GenericSubstitutions.deduce(receiverType, qualifierType)
11531163
const substituted = receiverType.substitute(subst.mapping)
11541164

0 commit comments

Comments
 (0)