diff --git a/CHANGELOG.md b/CHANGELOG.md index 558dfb5a6..4b27b351b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `log2` and `log` math functions in `@stdlib/math`: PR [#166](https://github.com/tact-lang/tact/pull/166) - Reserve mode constants in `@stdlib/reserve`, namely `ReserveExact`, `ReserveAllExcept`, `ReserveAtMost`, `ReserveAddOriginalBalance`, `ReserveInvertSign`, `ReserveBounceIfActionFail`: PR [#173](https://github.com/tact-lang/tact/pull/173) - JSON Schema for `tact.config.json`: PR [#194](https://github.com/tact-lang/tact/pull/194) +- Display an error for integer overflow at compile-time: PR [#200](https://github.com/tact-lang/tact/pull/200) +- Non-modifying `StringBuilder`'s `concat` method for chained string concatenations: PR [#217](https://github.com/tact-lang/tact/pull/217) ### Changed - Update the `dump` function to handle addresses: PR [#175](https://github.com/tact-lang/tact/pull/175) diff --git a/grammar/configSchema.json b/grammar/configSchema.json index 5b6f35226..5016c7b00 100644 --- a/grammar/configSchema.json +++ b/grammar/configSchema.json @@ -19,11 +19,11 @@ }, "path": { "type": "string", - "description": "Path to the project's Tact file. You can only specify one Tact file per project." + "description": "Path to the project's Tact file. You can only specify one Tact file per project.\n\nIn Blueprint projects, `path` is superseded by the field `target` in `wrappers/ProjectName.compile.ts`." }, "output": { "type": "string", - "description": "Path to the directory where all generated files will be placed." + "description": "Path to the directory where all generated files will be placed.\n\nIn Blueprint projects, `output` is unused and all generated files are always placed in `build/ProjectName/`." }, "options": { "type": "object", diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index 88c126178..470dd6c41 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -2996,6 +2996,21 @@ return ((builders), ());", "name": "__tact_string_builder_append", "signature": "((tuple), ()) __tact_string_builder_append(tuple builders, slice sc)", }, + { + "code": { + "code": "builders~__tact_string_builder_append(sc); +return builders;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_string_builder_append", + }, + "flags": Set {}, + "name": "__tact_string_builder_append_not_mut", + "signature": "(tuple) __tact_string_builder_append_not_mut(tuple builders, slice sc)", + }, { "code": { "code": "var b = begin_cell(); @@ -6978,6 +6993,21 @@ return ((builders), ());", "name": "__tact_string_builder_append", "signature": "((tuple), ()) __tact_string_builder_append(tuple builders, slice sc)", }, + { + "code": { + "code": "builders~__tact_string_builder_append(sc); +return builders;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_string_builder_append", + }, + "flags": Set {}, + "name": "__tact_string_builder_append_not_mut", + "signature": "(tuple) __tact_string_builder_append_not_mut(tuple builders, slice sc)", + }, { "code": { "code": "var b = begin_cell(); @@ -10960,6 +10990,21 @@ return ((builders), ());", "name": "__tact_string_builder_append", "signature": "((tuple), ()) __tact_string_builder_append(tuple builders, slice sc)", }, + { + "code": { + "code": "builders~__tact_string_builder_append(sc); +return builders;", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_string_builder_append", + }, + "flags": Set {}, + "name": "__tact_string_builder_append_not_mut", + "signature": "(tuple) __tact_string_builder_append_not_mut(tuple builders, slice sc)", + }, { "code": { "code": "var b = begin_cell(); diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index cef64a740..e41c29b48 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -1227,6 +1227,17 @@ export function writeStdlib(ctx: WriterContext) { }); }); + ctx.fun(`__tact_string_builder_append_not_mut`, () => { + ctx.signature(`(tuple) __tact_string_builder_append_not_mut(tuple builders, slice sc)`); + ctx.context('stdlib'); + ctx.body(() => { + ctx.write(` + builders~${ctx.used('__tact_string_builder_append')}(sc); + return builders; + `); + }); + }); + ctx.fun(`__tact_int_to_string`, () => { ctx.signature(`slice __tact_int_to_string(int src)`); ctx.context('stdlib'); diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index 7a89c2659..8feb81eb5 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -228,27 +228,29 @@ files['std/text.tact'] = 'KF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9zdGFydF90YWlsX3N0cmluZykKbmF0aXZlIGJlZ2luVGFpbFN0cmluZygpOiBTdHJpbmdCdWlsZGVyOwoKQG5hbWUoX190YWN0' + 'X3N0cmluZ19idWlsZGVyX3N0YXJ0KQpuYXRpdmUgYmVnaW5TdHJpbmdGcm9tQnVpbGRlcihiOiBCdWlsZGVyKTogU3RyaW5nQnVpbGRlcjsKCkBuYW1lKF9fdGFjdF9z' + 'dHJpbmdfYnVpbGRlcl9hcHBlbmQpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgYXBwZW5kKHNlbGY6IFN0cmluZ0J1aWxkZXIsIHM6IFN0cmluZyk7CgpAbmFtZShfX3Rh' + - 'Y3Rfc3RyaW5nX2J1aWxkZXJfZW5kKQpleHRlbmRzIG5hdGl2ZSB0b0NlbGwoc2VsZjogU3RyaW5nQnVpbGRlcik6IENlbGw7CgpAbmFtZShfX3RhY3Rfc3RyaW5nX2J1' + - 'aWxkZXJfZW5kX3NsaWNlKQpleHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBTdHJpbmdCdWlsZGVyKTogU3RyaW5nOwoKQG5hbWUoX190YWN0X3N0cmluZ19idWls' + - 'ZGVyX2VuZF9zbGljZSkKZXh0ZW5kcyBuYXRpdmUgdG9TbGljZShzZWxmOiBTdHJpbmdCdWlsZGVyKTogU2xpY2U7CgovLwovLyBTdHJpbmcgY29udmVyc2lvbgovLwoK' + - 'QG5hbWUoX190YWN0X2ludF90b19zdHJpbmcpCmV4dGVuZHMgbmF0aXZlIHRvU3RyaW5nKHNlbGY6IEludCk6IFN0cmluZzsKCkBuYW1lKF9fdGFjdF9mbG9hdF90b19z' + - 'dHJpbmcpCmV4dGVuZHMgbmF0aXZlIHRvRmxvYXRTdHJpbmcoc2VsZjogSW50LCBkaWdpdHM6IEludCk6IFN0cmluZzsKCmlubGluZSBleHRlbmRzIGZ1biB0b0NvaW5z' + - 'U3RyaW5nKHNlbGY6IEludCk6IFN0cmluZyB7CiAgICByZXR1cm4gc2VsZi50b0Zsb2F0U3RyaW5nKDkpOwp9CgpleHRlbmRzIGZ1biBhc0NvbW1lbnQoc2VsZjogU3Ry' + - 'aW5nKTogQ2VsbCB7CiAgICBsZXQgYjogU3RyaW5nQnVpbGRlciA9IGJlZ2luQ29tbWVudCgpOwogICAgYi5hcHBlbmQoc2VsZik7CiAgICByZXR1cm4gYi50b0NlbGwo' + - 'KTsKfQoKQG5hbWUoX190YWN0X3N0cl90b19zbGljZSkKZXh0ZW5kcyBuYXRpdmUgYXNTbGljZShzZWxmOiBTdHJpbmcpOiBTbGljZTsKCkBuYW1lKF9fdGFjdF9zbGlj' + - 'ZV90b19zdHIpCmV4dGVuZHMgbmF0aXZlIGFzU3RyaW5nKHNlbGY6IFNsaWNlKTogU3RyaW5nOwoKaW5saW5lIGV4dGVuZHMgZnVuIGZyb21CYXNlNjQoc2VsZjogU3Ry' + - 'aW5nKTogU2xpY2UgewogICAgcmV0dXJuIHNlbGYuYXNTbGljZSgpLmZyb21CYXNlNjQoKTsKfQoKZXh0ZW5kcyBmdW4gZnJvbUJhc2U2NChzZWxmOiBTbGljZSk6IFNs' + - 'aWNlIHsKICAgIGxldCBzaXplOiBJbnQgPSBzZWxmLmJpdHMoKSAvIDg7CiAgICBsZXQgcmVzdWx0OiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7CgogICAgcmVwZWF0IChz' + - 'aXplKSB7CiAgICAgICAgbGV0IGNvZGU6IEludCA9IHNlbGYubG9hZFVpbnQoOCk7CiAgICAgICAgaWYgKGNvZGUgPj0gNjUgJiYgY29kZSA8PSA5MCkgeyAvLyBBLVoK' + - 'ICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gNjUsIDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA+PSA5NyAmJiBjb2RlIDw9IDEy' + - 'MikgeyAvLyBhLXoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlIC0gKDk3IC0gMjYpLCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUg' + - 'Pj0gNDggJiYgY29kZSA8PSA1NykgeyAvLyAwLTkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludChjb2RlICsgKDUyIC0gNDgpLCA2KTsKICAgICAg' + - 'ICB9IGVsc2UgaWYgKGNvZGUgPT0gNDUgfHwgY29kZSA9PSA0MykgeyAvLyAtIG9yICsKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnN0b3JlVWludCg2MiwgNik7' + - 'CiAgICAgICAgfSBlbHNlIGlmIChjb2RlID09IDk1IHx8IGNvZGUgPT0gNDcpIHsgLy8gXyBvciAvCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQo' + - 'NjMsIDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA2MSkgeyAvLyA9CiAgICAgICAgICAgIC8vIFNraXAKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0' + - 'aHJvdygxMzQpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBQYWRkaW5nCiAgICBsZXQgdG90YWw6IEludCA9IHJlc3VsdC5iaXRzKCk7CiAgICBsZXQgcGFkZGluZzog' + - 'SW50ID0gdG90YWwgJSA4OwogICAgaWYgKHBhZGRpbmcgIT0gMCkgewogICAgICAgIGxldCBzOiBTbGljZSA9IHJlc3VsdC5hc1NsaWNlKCk7CiAgICAgICAgcmV0dXJu' + - 'IHMubG9hZEJpdHModG90YWwgLSBwYWRkaW5nKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC5hc1NsaWNlKCk7CiAgICB9Cn0='; + 'Y3Rfc3RyaW5nX2J1aWxkZXJfYXBwZW5kX25vdF9tdXQpCmV4dGVuZHMgbmF0aXZlIGNvbmNhdChzZWxmOiBTdHJpbmdCdWlsZGVyLCBzOiBTdHJpbmcpOiBTdHJpbmdC' + + 'dWlsZGVyOwoKQG5hbWUoX190YWN0X3N0cmluZ19idWlsZGVyX2VuZCkKZXh0ZW5kcyBuYXRpdmUgdG9DZWxsKHNlbGY6IFN0cmluZ0J1aWxkZXIpOiBDZWxsOwoKQG5h' + + 'bWUoX190YWN0X3N0cmluZ19idWlsZGVyX2VuZF9zbGljZSkKZXh0ZW5kcyBuYXRpdmUgdG9TdHJpbmcoc2VsZjogU3RyaW5nQnVpbGRlcik6IFN0cmluZzsKCkBuYW1l' + + 'KF9fdGFjdF9zdHJpbmdfYnVpbGRlcl9lbmRfc2xpY2UpCmV4dGVuZHMgbmF0aXZlIHRvU2xpY2Uoc2VsZjogU3RyaW5nQnVpbGRlcik6IFNsaWNlOwoKLy8KLy8gU3Ry' + + 'aW5nIGNvbnZlcnNpb24KLy8KCkBuYW1lKF9fdGFjdF9pbnRfdG9fc3RyaW5nKQpleHRlbmRzIG5hdGl2ZSB0b1N0cmluZyhzZWxmOiBJbnQpOiBTdHJpbmc7CgpAbmFt' + + 'ZShfX3RhY3RfZmxvYXRfdG9fc3RyaW5nKQpleHRlbmRzIG5hdGl2ZSB0b0Zsb2F0U3RyaW5nKHNlbGY6IEludCwgZGlnaXRzOiBJbnQpOiBTdHJpbmc7CgppbmxpbmUg' + + 'ZXh0ZW5kcyBmdW4gdG9Db2luc1N0cmluZyhzZWxmOiBJbnQpOiBTdHJpbmcgewogICAgcmV0dXJuIHNlbGYudG9GbG9hdFN0cmluZyg5KTsKfQoKZXh0ZW5kcyBmdW4g' + + 'YXNDb21tZW50KHNlbGY6IFN0cmluZyk6IENlbGwgewogICAgbGV0IGI6IFN0cmluZ0J1aWxkZXIgPSBiZWdpbkNvbW1lbnQoKTsKICAgIGIuYXBwZW5kKHNlbGYpOwog' + + 'ICAgcmV0dXJuIGIudG9DZWxsKCk7Cn0KCkBuYW1lKF9fdGFjdF9zdHJfdG9fc2xpY2UpCmV4dGVuZHMgbmF0aXZlIGFzU2xpY2Uoc2VsZjogU3RyaW5nKTogU2xpY2U7' + + 'CgpAbmFtZShfX3RhY3Rfc2xpY2VfdG9fc3RyKQpleHRlbmRzIG5hdGl2ZSBhc1N0cmluZyhzZWxmOiBTbGljZSk6IFN0cmluZzsKCmlubGluZSBleHRlbmRzIGZ1biBm' + + 'cm9tQmFzZTY0KHNlbGY6IFN0cmluZyk6IFNsaWNlIHsKICAgIHJldHVybiBzZWxmLmFzU2xpY2UoKS5mcm9tQmFzZTY0KCk7Cn0KCmV4dGVuZHMgZnVuIGZyb21CYXNl' + + 'NjQoc2VsZjogU2xpY2UpOiBTbGljZSB7CiAgICBsZXQgc2l6ZTogSW50ID0gc2VsZi5iaXRzKCkgLyA4OwogICAgbGV0IHJlc3VsdDogQnVpbGRlciA9IGJlZ2luQ2Vs' + + 'bCgpOwoKICAgIHJlcGVhdCAoc2l6ZSkgewogICAgICAgIGxldCBjb2RlOiBJbnQgPSBzZWxmLmxvYWRVaW50KDgpOwogICAgICAgIGlmIChjb2RlID49IDY1ICYmIGNv' + + 'ZGUgPD0gOTApIHsgLy8gQS1aCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQoY29kZSAtIDY1LCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUg' + + 'Pj0gOTcgJiYgY29kZSA8PSAxMjIpIHsgLy8gYS16CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQoY29kZSAtICg5NyAtIDI2KSwgNik7CiAgICAg' + + 'ICAgfSBlbHNlIGlmIChjb2RlID49IDQ4ICYmIGNvZGUgPD0gNTcpIHsgLy8gMC05CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdG9yZVVpbnQoY29kZSArICg1' + + 'MiAtIDQ4KSwgNik7CiAgICAgICAgfSBlbHNlIGlmIChjb2RlID09IDQ1IHx8IGNvZGUgPT0gNDMpIHsgLy8gLSBvciArCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3Vs' + + 'dC5zdG9yZVVpbnQoNjIsIDYpOwogICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA5NSB8fCBjb2RlID09IDQ3KSB7IC8vIF8gb3IgLwogICAgICAgICAgICByZXN1bHQg' + + 'PSByZXN1bHQuc3RvcmVVaW50KDYzLCA2KTsKICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT0gNjEpIHsgLy8gPQogICAgICAgICAgICAvLyBTa2lwCiAgICAgICAgfSBl' + + 'bHNlIHsKICAgICAgICAgICAgdGhyb3coMTM0KTsKICAgICAgICB9CiAgICB9CgogICAgLy8gUGFkZGluZwogICAgbGV0IHRvdGFsOiBJbnQgPSByZXN1bHQuYml0cygp' + + 'OwogICAgbGV0IHBhZGRpbmc6IEludCA9IHRvdGFsICUgODsKICAgIGlmIChwYWRkaW5nICE9IDApIHsKICAgICAgICBsZXQgczogU2xpY2UgPSByZXN1bHQuYXNTbGlj' + + 'ZSgpOwogICAgICAgIHJldHVybiBzLmxvYWRCaXRzKHRvdGFsIC0gcGFkZGluZyk7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiByZXN1bHQuYXNTbGljZSgpOwog' + + 'ICAgfQp9'; files['stdlib_ex.fc'] = 'Zm9yYWxsIFggLT4gdHVwbGUgX190YWN0X3NldCh0dXBsZSB4LCBYIHYsIGludCBpKSBhc20gIlNFVElOREVYVkFSUSI7CigpIF9fdGFjdF9ub3AoKSBhc20gIk5PUCI7' + 'CnNsaWNlIF9fdGFjdF9zdHJfdG9fc2xpY2Uoc2xpY2UgcykgYXNtICJOT1AiOwpzbGljZSBfX3RhY3Rfc2xpY2VfdG9fc3RyKHNsaWNlIHMpIGFzbSAiTk9QIjsKc2xp' + diff --git a/src/test/feature-strings.spec.ts b/src/test/feature-strings.spec.ts index e312e474f..dd49ff047 100644 --- a/src/test/feature-strings.spec.ts +++ b/src/test/feature-strings.spec.ts @@ -22,6 +22,7 @@ describe('feature-strings', () => { const l = 'привет мир 👀 привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀'; expect(await contract.getConstantStringUnicodeLong()).toBe(l); expect((await contract.getDynamicStringCell()).equals(beginCell().storeStringTail('Hello!').endCell())).toBe(true); + expect((await contract.getDynamicStringCell2()).equals(beginCell().storeStringTail('Hello, World!').endCell())).toBe(true); expect((await contract.getDynamicCommentCell()).equals(beginCell().storeUint(0, 32).storeStringTail('Something something world!').endCell())).toBe(true); const l2 = 'Hello!привет мир 👀 привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀привет мир 👀'; expect((await contract.getDynamicCommentCellLarge()).equals(beginCell().storeStringTail(l2).endCell())).toBe(true); diff --git a/src/test/features/strings.tact b/src/test/features/strings.tact index de50366d3..bf32e8280 100644 --- a/src/test/features/strings.tact +++ b/src/test/features/strings.tact @@ -26,6 +26,12 @@ contract StringsTester { return b.toCell(); } + get fun dynamicStringCell2(): Cell { + let b: StringBuilder = beginString(); + b = b.concat("Hello,").concat(" ").concat("World!"); + return b.toCell(); + } + get fun dynamicCommentCell(): Cell { let b: StringBuilder = beginComment(); b.append("Something something world!"); diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap index a2b389670..390c1f3bf 100644 --- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap +++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap @@ -248,6 +248,16 @@ Line 15, col 3: " `; +exports[`resolveDescriptors should fail descriptors for case-25 1`] = ` +":8:21: Cannot evaluate constant expression due to integer overflow +Line 8, col 21: + 7 | +> 8 | const a: Int = 1 + (1 >> -1073741824); + ^~~~~~~~~~~~~~~~ + 9 | +" +`; + exports[`resolveDescriptors should resolve descriptors for case-0 1`] = ` { "BaseTrait": { diff --git a/src/types/resolveConstantValue.ts b/src/types/resolveConstantValue.ts index 5482c0799..19d0bca2a 100644 --- a/src/types/resolveConstantValue.ts +++ b/src/types/resolveConstantValue.ts @@ -5,7 +5,7 @@ import { ASTExpression, throwError } from "../grammar/ast"; import { printTypeRef, TypeRef } from "./types"; import { sha256_sync } from "@ton/crypto"; -function reduceInt(ast: ASTExpression): bigint { +function reduceIntImpl(ast: ASTExpression): bigint { if (ast.kind === 'number') { return ast.value; } else if (ast.kind === 'op_binary') { @@ -59,6 +59,18 @@ function reduceInt(ast: ASTExpression): bigint { throwError('Cannot reduce expression to a constant integer', ast.ref); } +function reduceInt(ast: ASTExpression): bigint { + try { + return reduceIntImpl(ast) + } catch (error) { + if (error instanceof RangeError) { + throwError('Cannot evaluate constant expression due to integer overflow', ast.ref); + } else { + throw error; + } + } +} + function reduceBool(ast: ASTExpression): boolean { if (ast.kind === 'boolean') { return ast.value; diff --git a/src/types/test-failed/case-25.tact b/src/types/test-failed/case-25.tact new file mode 100644 index 000000000..c9dd18dc4 --- /dev/null +++ b/src/types/test-failed/case-25.tact @@ -0,0 +1,8 @@ +primitive Int; +primitive Bool; + +trait BaseTrait { + +} + +const a: Int = 1 + (1 >> -1073741824); diff --git a/stdlib/std/text.tact b/stdlib/std/text.tact index acaba4477..abc73cfa8 100644 --- a/stdlib/std/text.tact +++ b/stdlib/std/text.tact @@ -17,6 +17,9 @@ native beginStringFromBuilder(b: Builder): StringBuilder; @name(__tact_string_builder_append) extends mutates native append(self: StringBuilder, s: String); +@name(__tact_string_builder_append_not_mut) +extends native concat(self: StringBuilder, s: String): StringBuilder; + @name(__tact_string_builder_end) extends native toCell(self: StringBuilder): Cell;