Solidity v0.7.1 adds functions at file-level and fixes several small bugs.
Notable New Features
Functions At File-Level
Functions can now be defined at file-level. Such functions are called "free functions" (as opposed to functions bound to a specific contract).
Free functions are always internal functions and are meant to replace internal library functions and their very special behaviour.
A free function behaves like an internal function of the contract that called it. The main difference is that a free function cannot directly access state variables and internal functions of contracts. Free functions can call other contracts, emit events and send Ether, and in this case, msg.sender will be the contract that called the free function.
A contract's storage can only be accessed from a free function if a storage pointer is passed to the function (see the example below) or if inline assembly is used. The state mutability is checked, which means that pure free functions cannot access storage or send Ether.
The code of a free function is only included into the contracts that use it.
/// @dev returns the smaller of the two values. function min(uint x, uint y) pure returns (uint) { return x < y ? x : y; } /// @dev returns the sum of the elements of the storage array function sum(uint[] storage items) view returns (uint s) { for (uint i = 0; i < items.length; i++) s += items[i]; }
If free functions are imported from another file, it is recommended to use the import statement that generates a new object, so that the file's scope is not polluted needlessly:
helper.sol:
function f() returns (uint) { /* ... */ }
main.sol:
import "helper.sol" as Helper; contract C { function g() public returns (uint) { return Helper.f(); } }
The ability to use using A for B for free functions is planned for future releases.
Full Changelog
Language Features:
- Allow function definitions outside of contracts, behaving much like internal library functions.
- Code generator: Implemented copying structs from calldata to storage.
Compiler Features:
- SMTChecker: Add underflow and overflow as verification conditions in the CHC engine.
- SMTChecker: Support bitwise or, xor and not operators.
- SMTChecker: Support conditional operator.
- Standard JSON Interface: Do not run EVM bytecode code generation, if only Yul IR or EWasm output is requested.
- Yul Optimizer: LoopInvariantCodeMotion can move reading operations outside for-loops as long as the affected area is not modified inside the loop.
- Yul: Report error when using non-string literals for datasize(), dataoffset(), linkersymbol(), loadimmutable(), setimmutable().
Bugfixes:
- AST: Remove null member values also when the compiler is used in standard-json-mode.
- General: Allow type(Contract).name for abstract contracts and interfaces.
- Immutables: Disallow assigning immutables more than once during their declaration.
- Immutables: Properly treat complex assignment and increment/decrement as both reading and writing and thus disallow it everywhere for immutable variables.
- Optimizer: Keep side-effects of x in byte(a, shr(b, x)) even if the constants a and b would make the expression zero unconditionally. This optimizer rule is very hard if not impossible to trigger in a way that it can result in invalid code, though.
- References Resolver: Fix internal bug when using constructor for library.
- Scanner: Fix bug where whitespace would be allowed within the -> token (e.g. function f() - > x {} becomes invalid in inline assembly and Yul).
- SMTChecker: Fix internal error in BMC function inlining.
- SMTChecker: Fix internal error on array implicit conversion.
- SMTChecker: Fix internal error on fixed bytes index access.
- SMTChecker: Fix internal error on lvalue unary operators with tuples.
- SMTChecker: Fix soundness of array pop.
- Type Checker: Disallow using for directive inside interfaces.
- Type Checker: Disallow signed literals as exponent in exponentiation operator.
- Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions.
- Yul Optimizer: Ensure that Yul keywords are not mistakenly used by the NameDispenser and VarNameCleaners. The bug would manifest as uncompilable code.
- Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.
A big thank you to all contributors who helped make this release possible!
Download the new version of Solidity here.