Skip to content

Commit 89b05e0

Browse files
authored
fix(tolk/type-inference): correctly handle cyclic structs (#133)
Fixes #132
1 parent 3a4a6c3 commit 89b05e0

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

server/src/e2e/tolk/testcases/types/basic.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,3 +394,23 @@ fun main() {
394394
}
395395
------------------------------------------------------------------------
396396
ok
397+
398+
========================================================================
399+
Cyclic dependency with Cell in struct
400+
========================================================================
401+
struct SwapStep {
402+
pool: address
403+
minAmountOut: coins
404+
nextStep: Cell<SwapStep>?
405+
}
406+
407+
fun main() {
408+
val foo = SwapStep{};
409+
//! ^ SwapStep
410+
val step = foo.nextStep!
411+
//! ^ Cell<SwapStep>
412+
val loadedStep = foo.nextStep!.load()
413+
//! ^ SwapStep
414+
}
415+
------------------------------------------------------------------------
416+
ok

server/src/languages/tolk/TypeInferer.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -670,11 +670,16 @@ export class TypeInferer {
670670

671671
private inferTypeFromResolved(resolved: NamedNode): Ty | null {
672672
if (resolved instanceof Struct) {
673-
const baseTy = new StructTy(
674-
resolved.fields().map(it => this.inferType(it.typeNode()) ?? UnknownTy.UNKNOWN),
675-
resolved.name(),
676-
resolved,
677-
)
673+
const fieldTypes = resolved.fields().map(it => {
674+
try {
675+
return this.inferType(it.typeNode()) ?? UnknownTy.UNKNOWN
676+
} catch {
677+
// cyclic dependency
678+
return UnknownTy.UNKNOWN
679+
}
680+
})
681+
682+
const baseTy = new StructTy(fieldTypes, resolved.name(), resolved)
678683

679684
const typeParameters = resolved.typeParameters()
680685
if (typeParameters.length > 0) {

0 commit comments

Comments
 (0)