diff --git a/CHANGELOG.md b/CHANGELOG.md index e007c1c5c..c0cc605b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Error messages for unicode code points outside of valid range: PR [#535](https://github.com/tact-lang/tact/pull/535) - Correct regex for unicode code points and escaping of control codes in generated comments: PR [#535](https://github.com/tact-lang/tact/pull/535) - Add `impure` specifier to some stdlib functions that are expected to throw errors: PR [#565](https://github.com/tact-lang/tact/pull/565) +- Defining non-existing native FunC functions now throws an understandable compilation error: PR [#585](https://github.com/tact-lang/tact/pull/585) ## [1.4.0] - 2024-06-21 diff --git a/src/pipeline/build.ts b/src/pipeline/build.ts index 1e5bd8c85..e885eb940 100644 --- a/src/pipeline/build.ts +++ b/src/pipeline/build.ts @@ -180,6 +180,16 @@ export async function build(args: { logger, }); if (!c.ok) { + const match = c.log.match( + /undefined function `([^`]+)`, defining a global function of unknown type/, + ); + if (match) { + const message = `Function '${match[1]}' does not exist in imported FunC sources`; + logger.error(message); + errorMessages.push(new Error(message)); + return { ok: false, error: errorMessages }; + } + logger.error(c.log); ok = false; errorMessages.push(new Error(c.log)); diff --git a/src/test/compilation-failed/contracts/func-function-does-not-exist.tact b/src/test/compilation-failed/contracts/func-function-does-not-exist.tact new file mode 100644 index 000000000..3a70e2d4b --- /dev/null +++ b/src/test/compilation-failed/contracts/func-function-does-not-exist.tact @@ -0,0 +1,8 @@ +@name(iDoNotExist) +native youDo(); + +contract Test { + get fun test() { + youDo(); + } +} \ No newline at end of file diff --git a/src/test/compilation-failed/func-errors.spec.ts b/src/test/compilation-failed/func-errors.spec.ts new file mode 100644 index 000000000..cacceea19 --- /dev/null +++ b/src/test/compilation-failed/func-errors.spec.ts @@ -0,0 +1,14 @@ +import { __DANGER_resetNodeId } from "../../grammar/ast"; +import { itShouldNotCompile } from "./util"; + +describe("func-errors", () => { + beforeEach(() => { + __DANGER_resetNodeId(); + }); + + itShouldNotCompile({ + testName: "func-function-does-not-exist", + errorMessage: + "Function 'iDoNotExist' does not exist in imported FunC sources", + }); +}); diff --git a/src/test/compilation-failed/tact.config.json b/src/test/compilation-failed/tact.config.json index dfc144919..a2109296f 100644 --- a/src/test/compilation-failed/tact.config.json +++ b/src/test/compilation-failed/tact.config.json @@ -131,6 +131,11 @@ "name": "contract-duplicate-receiver-opcode", "path": "./contracts/contract-duplicate-receiver-opcode.tact", "output": "./contracts/output" + }, + { + "name": "func-function-does-not-exist", + "path": "./contracts/func-function-does-not-exist.tact", + "output": "./contracts/output" } ] }