Skip to content

Commit

Permalink
fix: disallow trait field initializers (#831)
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-trunov authored Sep 15, 2024
1 parent b6c65a4 commit 15a055d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `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)
- Contract method calls in return statements: PR [#829](https://github.com/tact-lang/tact/pull/829)
- Disallow initializers for trait storage fields: PR [#831](https://github.com/tact-lang/tact/pull/831)

## [1.4.4] - 2024-08-18

Expand Down
10 changes: 10 additions & 0 deletions src/types/__snapshots__/resolveDescriptors.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,16 @@ Line 7, col 1:
"
`;
exports[`resolveDescriptors should fail descriptors for trait-field-initialized 1`] = `
"<unknown>:2:14: Trait field cannot have an initializer
Line 2, col 14:
1 | trait T {
> 2 | a: Int = 42; // error
^~
3 |
"
`;
exports[`resolveDescriptors should fail descriptors for wf-type-const 1`] = `
"<unknown>:4:19: Invalid map type. Check https://docs.tact-lang.org/book/maps#allowed-types
Line 4, col 19:
Expand Down
48 changes: 29 additions & 19 deletions src/types/resolveDescriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,65 +538,75 @@ export function resolveDescriptors(ctx: CompilerContext) {

// Trait
if (a.kind === "trait") {
for (const f of a.declarations) {
if (f.kind === "field_decl") {
for (const traitDecl of a.declarations) {
if (traitDecl.kind === "field_decl") {
if (
types
.get(idText(a.name))!
.fields.find((v) => eqNames(v.name, f.name))
.fields.find((v) => eqNames(v.name, traitDecl.name))
) {
throwCompilationError(
`Field ${idTextErr(f.name)} already exists`,
f.loc,
`Field ${idTextErr(traitDecl.name)} already exists`,
traitDecl.loc,
);
}
if (f.as) {
if (traitDecl.as) {
throwCompilationError(
`Trait field cannot have serialization specifier`,
f.loc,
traitDecl.loc,
);
}
if (traitDecl.initializer) {
throwCompilationError(
`Trait field cannot have an initializer`,
traitDecl.initializer.loc,
);
}
types
.get(idText(a.name))!
.fields.push(
buildFieldDescription(
f,
traitDecl,
types.get(idText(a.name))!.fields.length,
),
);
} else if (
f.kind === "constant_def" ||
f.kind === "constant_decl"
traitDecl.kind === "constant_def" ||
traitDecl.kind === "constant_decl"
) {
if (
types
.get(idText(a.name))!
.fields.find((v) => eqNames(v.name, f.name))
.fields.find((v) => eqNames(v.name, traitDecl.name))
) {
throwCompilationError(
`Field ${idTextErr(f.name)} already exists`,
f.loc,
`Field ${idTextErr(traitDecl.name)} already exists`,
traitDecl.loc,
);
}
if (
types
.get(idText(a.name))!
.constants.find((v) => eqNames(v.name, f.name))
.constants.find((v) =>
eqNames(v.name, traitDecl.name),
)
) {
throwCompilationError(
`Constant ${idTextErr(f.name)} already exists`,
f.loc,
`Constant ${idTextErr(traitDecl.name)} already exists`,
traitDecl.loc,
);
}
if (f.attributes.find((v) => v.type === "override")) {
if (
traitDecl.attributes.find((v) => v.type === "override")
) {
throwCompilationError(
`Trait constant cannot be overridden`,
f.loc,
traitDecl.loc,
);
}
types
.get(idText(a.name))!
.constants.push(buildConstantDescription(f));
.constants.push(buildConstantDescription(traitDecl));
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/types/test-failed/trait-field-initialized.tact
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
trait T {
a: Int = 42; // error

get fun getA(): Int {
return self.a;
}
}

contract Test with T {
a: Int = 19;
}

0 comments on commit 15a055d

Please sign in to comment.