diff --git a/Changelog.md b/Changelog.md index f2c057e94..676a57f5b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Breaking changes: * Type Checker: Disallow assignments to state variables that contain nested mappings. * ``using A for B`` only affects the contract it is mentioned in and not all derived contracts * Inline Assembly: Disallow `.` in user-defined function and variable names. + * Inline Assembly: Slot and offset of storage pointer variable ``x`` are accessed via ``x.slot`` and ``x.offset`` instead of ``x_slot`` and ``x_offset``. Language Features: * Yul: Disallow EVM instruction `pc()`. diff --git a/docs/070-breaking-changes.rst b/docs/070-breaking-changes.rst index 1c6ba132e..9c2d43e41 100644 --- a/docs/070-breaking-changes.rst +++ b/docs/070-breaking-changes.rst @@ -21,3 +21,4 @@ This section gives detailed instructions on how to update prior code for every b * Repeat the ``using A for B`` statements in all derived contracts if needed. * Remove the ``public`` keyword from every constructor. * Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present). +* Change ``_slot`` and ``_offset`` suffixes in inline assembly to ``.slot`` and ``.offset``, respectively. diff --git a/docs/assembly.rst b/docs/assembly.rst index 713a3f8ef..b54800d46 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -132,14 +132,15 @@ For local storage variables or state variables, a single Yul identifier is not sufficient, since they do not necessarily occupy a single full storage slot. Therefore, their "address" is composed of a slot and a byte-offset inside that slot. To retrieve the slot pointed to by the variable ``x``, you -use ``x_slot``, and to retrieve the byte-offset you use ``x_offset``. +use ``x.slot``, and to retrieve the byte-offset you use ``x.offset``. +Using ``x`` itself will result in an error. Local Solidity variables are available for assignments, for example: .. code:: // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.4.16 <0.8.0; + pragma solidity >0.6.99 <0.8.0; contract C { uint b; @@ -147,7 +148,7 @@ Local Solidity variables are available for assignments, for example: assembly { // We ignore the storage slot offset, we know it is zero // in this special case. - r := mul(x, sload(b_slot)) + r := mul(x, sload(b.slot)) } } } @@ -164,20 +165,21 @@ Local Solidity variables are available for assignments, for example: ``assembly { signextend(, x) }`` -Since Solidity 0.6.0 the name of a inline assembly variable may not end in ``_offset`` or ``_slot`` -and it may not shadow any declaration visible in the scope of the inline assembly block -(including variable, contract and function declarations). Similarly, if the name of a declared -variable contains a dot ``.``, the prefix up to the ``.`` may not conflict with any -declaration visible in the scope of the inline assembly block. +Since Solidity 0.6.0 the name of a inline assembly variable may not +shadow any declaration visible in the scope of the inline assembly block +(including variable, contract and function declarations). +Since Solidity 0.7.0, variables and functions declared inside the +inline assembly block may not contain ``.``, but using ``.`` is +valid to access Solidity variables from outside the inline assembly block. Assignments are possible to assembly-local variables and to function-local variables. Take care that when you assign to variables that point to memory or storage, you will only change the pointer and not the data. -You can assign to the ``_slot`` part of a local storage variable pointer. -For these (structs, arrays or mappings), the ``_offset`` part is always zero. -It is not possible to assign to the ``_slot`` or ``_offset`` part of a state variable, +You can assign to the ``.slot`` part of a local storage variable pointer. +For these (structs, arrays or mappings), the ``.offset`` part is always zero. +It is not possible to assign to the ``.slot`` or ``.offset`` part of a state variable, though.