Skip to content

Commit

Permalink
fix: handle coins for map key and value types correctly (#821)
Browse files Browse the repository at this point in the history
* fix: report error when `coins` annotation is used for map key types
  • Loading branch information
Gusarich authored Sep 15, 2024
1 parent a2863d4 commit 897b480
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Disallow zero binary message opcodes as those are reserved for text messages: PR [#786](https://github.com/tact-lang/tact/pull/786)
- Return-statements in `init()` function do not cause FunC compilation error anymore: PR [#794](https://github.com/tact-lang/tact/pull/794)
- `emptyMap()` in equality comparison expressions does not cause code generation failures: PR [#814](https://github.com/tact-lang/tact/pull/814)
- Maps with `coins` as value type are now correctly handled in structs: PR [#821](https://github.com/tact-lang/tact/pull/821)

## [1.4.4] - 2024-08-18

Expand Down
2 changes: 2 additions & 0 deletions src/bindings/typescript/serializers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,8 @@ const map: Serializer<MapSerializerDescr> = {
src.valueFormat === undefined
) {
value = { kind: "uint", bits: 256 };
} else if (src.valueFormat === "coins") {
value = { kind: "uint", bits: 124 };
}
}
if (src.value === "address") {
Expand Down
19 changes: 19 additions & 0 deletions src/test/e2e-emulated/contracts/structs.tact
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ struct LongAndDeepNestedStruct {
s4: TripleNestedStructOpt?;
}

message(42) Foo {
s: Slice as remaining;
}

struct Dict {
m: map<Int as uint8, Int as coins>;
}

contract StructsTester {
s1: S = S {a: false, b: 21 + 21};
s2: S;
Expand Down Expand Up @@ -272,6 +280,17 @@ contract StructsTester {
// Deploy
receive() { }

receive(msg: Foo) {
let d = Dict.fromSlice(msg.s);
send(SendParameters{
bounce: false,
to: sender(),
value: ton("0.01"),
mode: SendPayGasSeparately,
body: d.toCell()
});
}

get fun structInitializerTest(): Bool {
return self.s1.a == self.s2.a && self.s1.b == self.s2.b &&
self.t1.a == self.t2.a &&
Expand Down
27 changes: 27 additions & 0 deletions src/test/e2e-emulated/structs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,5 +375,32 @@ describe("structs", () => {
.endCell();

expect(await contract.getUintFieldsMessage()).toEqual(mUintFields);

// https://github.com/tact-lang/tact/issues/767

const m = Dictionary.empty(
Dictionary.Keys.Uint(8),
Dictionary.Values.BigVarUint(4),
);
m.set(1, 1n);
m.set(2, 2n);
m.set(3, 3n);
const result = await contract.send(
treasure.getSender(),
{ value: toNano("10") },
{
$$type: "Foo",
s: beginCell().storeDict(m).endCell().asSlice(),
},
);
expect(result.transactions).toHaveTransaction({
on: contract.address,
success: true,
});
expect(result.transactions).toHaveTransaction({
from: contract.address,
to: treasure.address,
body: beginCell().storeDict(m).endCell(),
});
});
});
4 changes: 2 additions & 2 deletions src/types/resolveABITypeRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export function resolveABIType(src: AstFieldDecl): ABITypeRef {
key = "int";
if (src.type.keyStorageType) {
const format = intMapFormats[idText(src.type.keyStorageType)];
if (!format) {
if (!format || format.format === "coins") {
throwCompilationError(
`Unsupported format ${idTextErr(src.type.keyStorageType)} for map key`,
src.loc,
Expand Down Expand Up @@ -421,7 +421,7 @@ export function createABITypeRefFromTypeRef(
key = "int";
if (src.keyAs) {
const format = intMapFormats[src.keyAs];
if (!format) {
if (!format || src.keyAs === "coins") {
throwCompilationError(
`Unsupported format ${src.keyAs} for map key`,
loc,
Expand Down
5 changes: 5 additions & 0 deletions src/types/resolveSignatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ export function resolveSignatures(ctx: CompilerContext) {
`Unsupported map format: ${src.type.format}`,
);
}
if (src.type.keyFormat === "coins") {
throwCompilationError(
`Unsupported format ${src.type.keyFormat} for map key`,
);
}
const key = createTypeFormat(
src.type.key,
src.type.keyFormat ? src.type.keyFormat : null,
Expand Down

0 comments on commit 897b480

Please sign in to comment.