diff --git a/server/src/e2e/tolk/testcases/types/basic.test b/server/src/e2e/tolk/testcases/types/basic.test index 1c67a921..a3f23005 100644 --- a/server/src/e2e/tolk/testcases/types/basic.test +++ b/server/src/e2e/tolk/testcases/types/basic.test @@ -394,3 +394,23 @@ fun main() { } ------------------------------------------------------------------------ ok + +======================================================================== +Cyclic dependency with Cell in struct +======================================================================== +struct SwapStep { + pool: address + minAmountOut: coins + nextStep: Cell? +} + +fun main() { + val foo = SwapStep{}; +//! ^ SwapStep + val step = foo.nextStep! +//! ^ Cell + val loadedStep = foo.nextStep!.load() +//! ^ SwapStep +} +------------------------------------------------------------------------ +ok diff --git a/server/src/languages/tolk/TypeInferer.ts b/server/src/languages/tolk/TypeInferer.ts index f56a9c2f..7190e31d 100644 --- a/server/src/languages/tolk/TypeInferer.ts +++ b/server/src/languages/tolk/TypeInferer.ts @@ -670,11 +670,16 @@ export class TypeInferer { private inferTypeFromResolved(resolved: NamedNode): Ty | null { if (resolved instanceof Struct) { - const baseTy = new StructTy( - resolved.fields().map(it => this.inferType(it.typeNode()) ?? UnknownTy.UNKNOWN), - resolved.name(), - resolved, - ) + const fieldTypes = resolved.fields().map(it => { + try { + return this.inferType(it.typeNode()) ?? UnknownTy.UNKNOWN + } catch { + // cyclic dependency + return UnknownTy.UNKNOWN + } + }) + + const baseTy = new StructTy(fieldTypes, resolved.name(), resolved) const typeParameters = resolved.typeParameters() if (typeParameters.length > 0) {