Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

self should not be assignable in init method #816

Open
1 task done
jeshecdom opened this issue Sep 12, 2024 · 1 comment
Open
1 task done

self should not be assignable in init method #816

jeshecdom opened this issue Sep 12, 2024 · 1 comment
Labels
bug Something isn't working
Milestone

Comments

@jeshecdom
Copy link
Contributor

Are you using the latest released (or pre-released, a.k.a. "next") version?

  • I'm using the latest Tact version

Tact source code

contract Test {
   a: Int;

   init() {
      let contract_copy = self;
      self.a = 5;
      self = contract_copy;    // Does this line "uninitialize" self.a?
   }
}

Relevant Tact/build system log output

This is the generated func code of the init method:

(int) $Test$_contract_init() impure inline_ref {
    var (($self'a)) = (null());
    var ($contract_copy'a) = ($self'a);
    $self'a = 5;
    ($self'a) = ($contract_copy'a);
    return ($self'a);
}

What happened?

Field $self'a will be initialized to null() after $Test$_contract_init executes. Is null() a valid value for an Int?

What did you expect?

Probably an error message explaining that self should not be assigned in the init method.

Steps to reproduce

No response

How do you run Tact?

Tact CLI

Anything else?

No response

@jeshecdom jeshecdom added the bug Something isn't working label Sep 12, 2024
@jeshecdom
Copy link
Contributor Author

Actually, reading the entire contract state using self should not be allowed in the init function because someone could write something like this:

contract Test {
   a: Int;

   init() {
      let contract_copy = self;
      self.a = 5;
      self.a = contract_copy.a;
   }
}

which has the same effect. Note we are not assigning the variable self this time: we are just reading it.

Reading variable self in init does not make sense, because init is supposed to initialize the contract. Therefore, self by itself does not have any meaning until init finishes execution!

However, it is OK to read specific fields inside init, like self.a, as long as those fields have been initialized. For example, the compiler correctly rejects this:

contract Test {
   a: Int;

   init() {
      let a_copy = self.a;
      self.a = 5;
      self.a = a_copy;
   }
}

because self.a has not been initialized.

@anton-trunov anton-trunov added this to the v1.6.0 milestone Sep 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants