Skip to content

Commit f9e0046

Browse files
committed
feat: clarify error message for bounced types from which accessed a field that does not fit in 224 bytes
1 parent 229ce26 commit f9e0046

5 files changed

+109
-1
lines changed

src/types/__snapshots__/resolveStatements.spec.ts.snap

+31-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Line 10, col 5:
8181
`;
8282

8383
exports[`resolveStatements should fail statements for bounced-type-is-smaller 1`] = `
84-
"<unknown>:23:22: Type bounced<"A"> does not have a field named "c"
84+
"<unknown>:23:22: Maximum size of the bounced message is 224 bytes, but the "c" field cannot fit into it due to the size of previous fields or its own size, so it cannot be accessed. Make the type of the fields before this one smaller, or reduce the type of this field so that it fits into 224 bytes
8585
Line 23, col 22:
8686
22 | let y: Bool = src.b;
8787
> 23 | let z: Int = src.c;
@@ -1238,6 +1238,36 @@ Line 9, col 5:
12381238
"
12391239
`;
12401240

1241+
exports[`resolveStatements should fail statements for usage-of-bounced-field-in-type-that-is-too-big 1`] = `
1242+
"<unknown>:14:29: Maximum size of the bounced message is 224 bytes, but the "amount" field cannot fit into it due to the size of previous fields or its own size, so it cannot be accessed. Make the type of the fields before this one smaller, or reduce the type of this field so that it fits into 224 bytes
1243+
Line 14, col 29:
1244+
13 | self.balance += msg.data; // ok
1245+
> 14 | self.balance += msg.amount;
1246+
^~~~~~
1247+
15 | }
1248+
"
1249+
`;
1250+
1251+
exports[`resolveStatements should fail statements for usage-of-bounced-field-in-type-that-is-too-big-2 1`] = `
1252+
"<unknown>:26:29: Maximum size of the bounced message is 224 bytes, but the "amount" field cannot fit into it due to the size of previous fields or its own size, so it cannot be accessed. Make the type of the fields before this one smaller, or reduce the type of this field so that it fits into 224 bytes
1253+
Line 26, col 29:
1254+
25 |
1255+
> 26 | self.balance += msg.amount;
1256+
^~~~~~
1257+
27 | }
1258+
"
1259+
`;
1260+
1261+
exports[`resolveStatements should fail statements for usage-of-bounced-field-that-is-too-big 1`] = `
1262+
"<unknown>:12:29: Maximum size of the bounced message is 224 bytes, but the "amount" field cannot fit into it because its too big, so it cannot be accessed. Reduce the type of this field so that it fits into 224 bytes
1263+
Line 12, col 29:
1264+
11 | bounced(msg: bounced<Withdraw>){
1265+
> 12 | self.balance += msg.amount;
1266+
^~~~~~
1267+
13 | }
1268+
"
1269+
`;
1270+
12411271
exports[`resolveStatements should fail statements for var-does-not-exist 1`] = `
12421272
"<unknown>:5:9: Unable to resolve id 'nonExistentVariable'
12431273
Line 5, col 9:

src/types/resolveExpression.ts

+20
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,26 @@ function resolveFieldAccess(
450450
}
451451
}
452452

453+
// If it is bounced<T>, check all fields of T
454+
if (src.kind === "ref_bounced") {
455+
const field = srcT.fields.find((v) => eqNames(v.name, exp.field));
456+
457+
// If it has field, it means that this field doesn't fit into bounced message
458+
if (field !== undefined) {
459+
if (srcT.fields.length == 1) {
460+
throwCompilationError(
461+
`Maximum size of the bounced message is 224 bytes, but the ${idTextErr(exp.field)} field cannot fit into it because its too big, so it cannot be accessed. Reduce the type of this field so that it fits into 224 bytes`,
462+
exp.field.loc,
463+
);
464+
}
465+
466+
throwCompilationError(
467+
`Maximum size of the bounced message is 224 bytes, but the ${idTextErr(exp.field)} field cannot fit into it due to the size of previous fields or its own size, so it cannot be accessed. Make the type of the fields before this one smaller, or reduce the type of this field so that it fits into 224 bytes`,
468+
exp.field.loc,
469+
);
470+
}
471+
}
472+
453473
throwCompilationError(
454474
`Type ${typeStr} does not have a field named ${idTextErr(exp.field)}`,
455475
exp.field.loc,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
primitive Int;
2+
trait BaseTrait { }
3+
4+
message Withdraw {
5+
data128: Int as uint128; // 128
6+
data64: Int as uint64; // 192
7+
data16: Int as uint16; // 208
8+
data8: Int as uint8; // 216
9+
data4: Int as uint4; // 220
10+
data4_2: Int as uint4; // 224
11+
12+
amount: Int as uint128;
13+
}
14+
15+
contract Fund {
16+
balance: Int as uint256 = 0;
17+
18+
bounced(msg: bounced<Withdraw>){
19+
self.balance += msg.data128; // ok
20+
self.balance += msg.data64; // ok
21+
self.balance += msg.data16; // ok
22+
self.balance += msg.data8; // ok
23+
self.balance += msg.data4; // ok
24+
self.balance += msg.data4_2; // ok
25+
26+
self.balance += msg.amount;
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
primitive Int;
2+
trait BaseTrait { }
3+
4+
message Withdraw {
5+
data: Int as uint128;
6+
amount: Int as uint128; // exceeds 224 bytes
7+
}
8+
9+
contract Fund {
10+
balance: Int as uint256 = 0;
11+
12+
bounced(msg: bounced<Withdraw>){
13+
self.balance += msg.data; // ok
14+
self.balance += msg.amount;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
primitive Int;
2+
trait BaseTrait { }
3+
4+
message Withdraw {
5+
amount: Int as uint256; // too big
6+
}
7+
8+
contract Fund {
9+
balance: Int as uint256 = 0;
10+
11+
bounced(msg: bounced<Withdraw>){
12+
self.balance += msg.amount;
13+
}
14+
}

0 commit comments

Comments
 (0)