mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #14304 from ethereum/relax-restrictions-on-immutable-initialization-outside-functions-and-modifiers
Relax restrictions on immutable initialization (outside of functions and modifiers)
This commit is contained in:
+1
-1
@@ -150,7 +150,7 @@ Modifiers
|
||||
- ``view`` for functions: Disallows modification of state.
|
||||
- ``payable`` for functions: Allows them to receive Ether together with a call.
|
||||
- ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot.
|
||||
- ``immutable`` for state variables: Allows exactly one assignment at construction time and is constant afterwards. Is stored in code.
|
||||
- ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code.
|
||||
- ``anonymous`` for events: Does not store event signature as topic.
|
||||
- ``indexed`` for event parameters: Stores the parameter as topic.
|
||||
- ``virtual`` for functions and modifiers: Allows the function's or modifier's
|
||||
|
||||
@@ -30,19 +30,23 @@ Not all types for constants and immutables are implemented at this time. The onl
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.4;
|
||||
pragma solidity ^0.8.21;
|
||||
|
||||
uint constant X = 32**22 + 8;
|
||||
|
||||
contract C {
|
||||
string constant TEXT = "abc";
|
||||
bytes32 constant MY_HASH = keccak256("abc");
|
||||
uint immutable decimals;
|
||||
uint immutable decimals = 18;
|
||||
uint immutable maxBalance;
|
||||
address immutable owner = msg.sender;
|
||||
|
||||
constructor(uint decimals_, address ref) {
|
||||
decimals = decimals_;
|
||||
if (decimals_ != 0)
|
||||
// Immutables are only immutable when deployed.
|
||||
// At construction time they can be assigned to any number of times.
|
||||
decimals = decimals_;
|
||||
|
||||
// Assignments to immutables can even access the environment.
|
||||
maxBalance = ref.balance;
|
||||
}
|
||||
@@ -74,10 +78,29 @@ Immutable
|
||||
=========
|
||||
|
||||
Variables declared as ``immutable`` are a bit less restricted than those
|
||||
declared as ``constant``: Immutable variables can be assigned an arbitrary
|
||||
value in the constructor of the contract or at the point of their declaration.
|
||||
They can be assigned only once and can, from that point on, be read even during
|
||||
construction time.
|
||||
declared as ``constant``: Immutable variables can be assigned a
|
||||
value at construction time.
|
||||
The value can be changed at any time before deployment and then it becomes permanent.
|
||||
|
||||
One additional restriction is that immutables can only be assigned to inside expressions for which
|
||||
there is no possibility of being executed after creation.
|
||||
This excludes all modifier definitions and functions other than constructors.
|
||||
|
||||
There are no restrictions on reading immutable variables.
|
||||
The read is even allowed to happen before the variable is written to for the first time because variables in
|
||||
Solidity always have a well-defined initial value.
|
||||
For this reason it is also allowed to never explicitly assign a value to an immutable.
|
||||
|
||||
.. warning::
|
||||
When accessing immutables at construction time, please keep the :ref:`initialization order
|
||||
<state-variable-initialization-order>` in mind.
|
||||
Even if you provide an explicit initializer, some expressions may end up being evaluated before
|
||||
that initializer, especially when they are at a different level in inheritance hierarchy.
|
||||
|
||||
.. note::
|
||||
Before Solidity 0.8.21 initialization of immutable variables was more restrictive.
|
||||
Such variables had to be initialized exactly once at construction time and could not be read
|
||||
before then.
|
||||
|
||||
The contract creation code generated by the compiler will modify the
|
||||
contract's runtime code before it is returned by replacing all references
|
||||
@@ -86,14 +109,3 @@ you are comparing the
|
||||
runtime code generated by the compiler with the one actually stored in the
|
||||
blockchain. The compiler outputs where these immutables are located in the deployed bytecode
|
||||
in the ``immutableReferences`` field of the :ref:`compiler JSON standard output <compiler-api>`.
|
||||
|
||||
.. note::
|
||||
Immutables that are assigned at their declaration are only considered
|
||||
initialized once the constructor of the contract is executing.
|
||||
This means you cannot initialize immutables inline with a value
|
||||
that depends on another immutable. You can do this, however,
|
||||
inside the constructor of the contract.
|
||||
|
||||
This is a safeguard against different interpretations about the order
|
||||
of state variable initialization and constructor execution, especially
|
||||
with regards to inheritance.
|
||||
|
||||
@@ -30,6 +30,8 @@ Semantic Only Changes
|
||||
This section lists the changes that are semantic-only, thus potentially
|
||||
hiding new and different behavior in existing code.
|
||||
|
||||
.. _state-variable-initialization-order:
|
||||
|
||||
- The order of state variable initialization has changed in case of inheritance.
|
||||
|
||||
The order used to be:
|
||||
|
||||
Reference in New Issue
Block a user