tact-lang / tact

Tact compiler main repository
https://tact-lang.org
MIT License
360 stars 100 forks source link

Tact doesn't catch when the FunC identifier specified in `@name()` doesn't exist #371

Closed novusnota closed 2 months ago

novusnota commented 3 months ago

When specifying a non-existent FunC identifier (neither in stdlib.fc nor in imported FunC code), Tact doesn't catch that and the error leaks to FunC, where compilation errors with a misleading message.

I.e., the following snippet:

@name(iDontExist)
native youDo();

contract Test {
   get fun test() {
       youDo();
   }
}

Produces this FunC (and not Tact's) compilation error:

/test/tact_SimpleCounter.code.fc:23:5: error: undefined function `iDontExist`, defining a global function of unknown type
      iDontExist();
      ^

While the expected behavior would be to tell that the function iDontExist wasn't found in imported FunC sources or something like that.

anton-trunov commented 2 months ago

I'd say that in this case the go-to solution, although admittedly a bit hacky, would be to catch compilation errors from FunC and parse them. (This is brittle but we vendor a FunC compiler, so if we have tests for the FunC errors, we should be fine).

To think of alternative approaches: I don't think FunC has an API for third-party tools like Tact. And re-implementing a FunC parser and a type-checker (scope-checker actually) also don't look like a viable alternative.

novusnota commented 2 months ago

Thing is, we'll still need to support wrapping FunC functions even when we move to non-FunC backend and compile to Fift or straight to BoC's. So making a FunC parser may not be that bad of an idea, although catching compilation errors from FunC seems better.

The latter is especially true if we could influence an API for them — expose the compilation error facilities into funcfiftlib wasm OR to do some C++ addons from Node, binding to FunC's C++ sources. But again, this seems like an over-engineered solution too, although I'd argue that TON's C++ APIs could've been more wrappable, such that there would've been no need for re-implementing stuff in TypeScript, Dart, Go, Python, .NET, etc. — we could've bound to C/C++ directly :)

Anyways, if FunC's error messages keep their format as is, just parsing them will be the easiest of the options we have