Skip to content

Commit

Permalink
fix: check map types for deepEquals method
Browse files Browse the repository at this point in the history
Fixes #1261
  • Loading branch information
i582 committed Feb 5, 2025
1 parent 13fee13 commit 776607c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/abi/map.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { CompilerContext } from "../context/context";
import { SrcInfo } from "../grammar";
import { TypeRef } from "../types/types";
import { printTypeRef, TypeRef } from "../types/types";
import { WriterContext } from "../generator/Writer";
import { ops } from "../generator/writers/ops";
import { writeExpression } from "../generator/writers/writeExpression";
import { throwCompilationError } from "../error/errors";
import { getType } from "../types/resolveDescriptors";
import { AbiFunction } from "./AbiFunction";
import { AstExpression } from "../ast/ast";
import { isAssignable } from "../types/subtyping";

// Helper functions to avoid redundancy
function checkArgumentsLength(
Expand Down Expand Up @@ -492,6 +493,13 @@ export const MapFunctions: ReadonlyMap<string, AbiFunction> = new Map([
checkMapType(self, ref);
checkMapType(other, ref);

if (!isAssignable(self, other)) {
throwCompilationError(
`Type mismatch: "${printTypeRef(self)}" is not assignable to "${printTypeRef(other)}"`,
ref,
);
}

return { kind: "ref", name: "Bool", optional: false };
},
generate(
Expand Down
18 changes: 18 additions & 0 deletions src/types/__snapshots__/resolveStatements.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,24 @@ exports[`resolveStatements should fail statements for init-vars-analysis-with-if
"
`;

exports[`resolveStatements should fail statements for map-deepEquals-type-mismatch 1`] = `
"<unknown>:12:16: Type mismatch: "map<Int, Int>" is not assignable to "map<Address, Int>"
11 | let m2: map<Address, Int> = emptyMap();
> 12 | return m1.deepEquals(m2);
^~~~~~~~~~~~~~~~~
13 | }
"
`;

exports[`resolveStatements should fail statements for map-deepEquals-type-mismatch-2 1`] = `
"<unknown>:12:16: Type mismatch: "map<Address, Int>" is not assignable to "map<Int, Address>"
11 | let m2: map<Int, Address> = emptyMap();
> 12 | return m1.deepEquals(m2);
^~~~~~~~~~~~~~~~~
13 | }
"
`;

exports[`resolveStatements should fail statements for return-analysis-catch-if 1`] = `
"<unknown>:4:1: Function does not always return a result. Adding 'return' statement(s) should fix the issue.
3 |
Expand Down
14 changes: 14 additions & 0 deletions src/types/stmts-failed/map-deepEquals-type-mismatch-2.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
primitive Bool;
primitive Int;
primitive Address;

trait BaseTrait {}

contract Test {
get fun foo(): Bool {
let m1: map<Address, Int> = emptyMap();
m1.set(address(""), 0);
let m2: map<Int, Address> = emptyMap();
return m1.deepEquals(m2);
}
}
14 changes: 14 additions & 0 deletions src/types/stmts-failed/map-deepEquals-type-mismatch.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
primitive Bool;
primitive Int;
primitive Address;

trait BaseTrait {}

contract Test {
get fun foo(): Bool {
let m1: map<Int, Int> = emptyMap();
m1.set(42, 0);
let m2: map<Address, Int> = emptyMap();
return m1.deepEquals(m2);
}
}

0 comments on commit 776607c

Please sign in to comment.