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:
Kamil Śliwak
2023-07-17 16:38:57 +02:00
committed by GitHub
56 changed files with 207 additions and 419 deletions
@@ -0,0 +1,15 @@
contract C {
uint8 immutable public a;
uint8 immutable public b = 0x42;
uint public c;
constructor() {
delete a;
delete b;
c = b * 2 + a;
}
}
// ----
// a() -> 0
// b() -> 0
// c() -> 0
@@ -0,0 +1,18 @@
contract C {
int immutable x = 1;
int immutable y = 3;
constructor() {
x--;
--x;
y++;
++y;
--y;
}
function f() public view returns (int, int) {
return (x, y);
}
}
// ----
// f() -> -1, 4
@@ -0,0 +1,27 @@
contract A {
uint immutable x = x + 1;
uint immutable y = x += 2;
constructor(uint) m(x += 16) m(x += 32) {
x += 64;
x += 128;
}
modifier m(uint) {
_;
}
function get() public returns (uint) {
return x;
}
}
contract B is A(A.x += 8) {
constructor(uint) {}
}
contract C is B {
constructor() B(x += 4) {}
}
// ----
// get() -> 0xff
@@ -0,0 +1,11 @@
contract C {
uint immutable u;
bool immutable b;
address immutable a;
function get() public returns (uint, bool, address) {
return (u, b, a);
}
}
// ----
// get() -> 0, false, 0x0
@@ -7,5 +7,3 @@ contract C {
x = 1;
}
}
// ----
// TypeError 2658: (86-93): Construction control flow ends without initializing all immutable state variables.
@@ -5,5 +5,3 @@ contract C {
x = 1;
}
}
// ----
// TypeError 4599: (86-87): Cannot write to immutable here: Immutable variables cannot be initialized inside an if statement.
@@ -4,7 +4,5 @@ contract C {
x = f();
}
function f() public pure returns (uint) { return 3 + x; }
function f() public view returns (uint) { return 3 + x; }
}
// ----
// TypeError 7733: (136-137): Immutable variables cannot be read before they are initialized.
@@ -4,5 +4,3 @@ contract C {
x = 3 + x;
}
}
// ----
// TypeError 7733: (71-72): Immutable variables cannot be read before they are initialized.
@@ -9,4 +9,3 @@ contract C {
function f(uint a) internal pure {}
}
// ----
// TypeError 1581: (59-60): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -10,5 +10,3 @@ contract C {
function f(uint a) internal pure {}
}
// ----
// TypeError 7733: (119-120): Immutable variables cannot be read before they are initialized.
@@ -4,5 +4,3 @@ contract C {
x--;
}
}
// ----
// TypeError 3969: (63-64): Immutable variables must be initialized using an assignment.
@@ -1,8 +0,0 @@
contract C {
uint immutable x;
constructor() {
delete x;
}
}
// ----
// TypeError 3969: (70-71): Immutable variables must be initialized using an assignment.
@@ -1,8 +0,0 @@
contract C {
uint immutable x = 3;
constructor() {
delete x;
}
}
// ----
// TypeError 2718: (74-75): Immutable variables cannot be modified after initialization.
@@ -1,7 +1,5 @@
contract C {
uint immutable x = f();
function f() public pure returns (uint) { return 3 + x; }
function f() public view returns (uint) { return 3 + x; }
}
// ----
// TypeError 7733: (99-100): Immutable variables cannot be read before they are initialized.
@@ -11,4 +11,3 @@ contract C is B(C.f) {
}
// ----
// TypeError 1581: (200-201): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
// TypeError 1574: (109-110): Immutable state variable already initialized.
@@ -7,7 +7,6 @@ abstract contract B {
}
contract C is B(C.f) {
function f() internal returns(uint) { return x + 2; }
function f() internal view returns(uint) { return x + 2; }
}
// ----
// TypeError 7733: (200-201): Immutable variables cannot be read before they are initialized.
@@ -4,5 +4,3 @@ contract C {
x++;
}
}
// ----
// TypeError 3969: (63-64): Immutable variables must be initialized using an assignment.
@@ -1,11 +0,0 @@
contract C {
uint immutable x;
uint immutable y;
constructor() {
++x;
--y;
}
}
// ----
// TypeError 3969: (77-78): Immutable variables must be initialized using an assignment.
// TypeError 3969: (86-87): Immutable variables must be initialized using an assignment.
@@ -2,7 +2,6 @@ contract C {
uint immutable x = 0;
uint y = f();
function f() internal returns(uint) { return x; }
function f() internal pure returns(uint) { return x; }
}
// ----
// TypeError 7733: (107-108): Immutable variables cannot be read before they are initialized.
@@ -10,5 +10,3 @@ contract C is B {
uint immutable y;
constructor() B(y = 3) { }
}
// ----
// TypeError 1581: (148-149): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -9,5 +9,3 @@ contract B {
contract C is B(C.y = 3) {
uint immutable y;
}
// ----
// TypeError 1581: (104-107): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -12,5 +12,3 @@ contract C is B(C.y) {
y = 3;
}
}
// ----
// TypeError 7733: (104-107): Immutable variables cannot be read before they are initialized.
@@ -5,15 +5,14 @@ contract B {
x = xInit();
}
function xInit() internal virtual returns(uint) {
function xInit() internal view virtual returns(uint) {
return 3;
}
}
contract C is B {
function xInit() internal override returns(uint) {
function xInit() internal view override returns(uint) {
return x;
}
}
// ----
// TypeError 7733: (253-254): Immutable variables cannot be read before they are initialized.
@@ -17,5 +17,3 @@ contract C is B {
_; f(x);
}
}
// ----
// TypeError 7733: (245-246): Immutable variables cannot be read before they are initialized.
@@ -7,5 +7,3 @@ contract C is B {
x = 3;
}
}
// ----
// TypeError 7484: (88-89): Cannot write to immutable here: Immutable variables must be initialized in the constructor of the contract they are defined in.
@@ -0,0 +1,6 @@
contract D {
uint immutable t;
modifier m(uint) { _; }
constructor() m(t = 2) {}
}
// ----
@@ -3,5 +3,3 @@ contract D is C {
uint immutable t;
constructor() C(t=2) {}
}
// ----
// TypeError 1581: (92-93): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -0,0 +1,7 @@
contract D {
uint immutable t;
modifier m(uint) { _; }
function f() public m(t = 2) {}
}
// ----
// TypeError 1581: (89-90): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -0,0 +1,11 @@
contract B {
uint immutable x;
}
contract C is B {
function f() public {
B.x = 42;
}
}
// ----
// TypeError 1581: (90-93): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -0,0 +1,13 @@
contract B {
uint immutable x;
function g() public {}
}
contract C is B {
function f() public {
super.x = 42;
}
}
// ----
// TypeError 9582: (118-125): Member "x" not found or not visible after argument-dependent lookup in type(contract super C).
@@ -1,6 +1,4 @@
contract C { constructor(uint) {} }
contract D is C(D.t = 2) {
uint immutable t;
uint immutable t;
}
// ----
// TypeError 1581: (52-55): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -1,7 +0,0 @@
contract D {
uint immutable t;
modifier m(uint) { _; }
constructor() m(t=2) {}
}
// ----
// TypeError 1581: (77-78): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -5,5 +5,3 @@ contract C {
x = 1;
}
}
// ----
// TypeError 6672: (88-89): Cannot write to immutable here: Immutable variables cannot be initialized inside a loop.
@@ -13,7 +13,7 @@ contract B {
return f();
}
function f() internal virtual returns(uint) { return 3; }
function f() internal view virtual returns(uint) { return 3; }
}
contract C is A, B {
@@ -21,9 +21,8 @@ contract C is A, B {
return B.xInit();
}
function f() internal override(A, B) returns(uint) {
function f() internal view override(A, B) returns(uint) {
return x;
}
}
// ----
// TypeError 7733: (489-490): Immutable variables cannot be read before they are initialized.
@@ -13,7 +13,7 @@ contract B {
return f();
}
function f() internal virtual returns(uint) { return 3; }
function f() internal view virtual returns(uint) { return 3; }
}
contract C is A, B {
@@ -21,9 +21,8 @@ contract C is A, B {
return super.xInit();
}
function f() internal override(A, B) returns(uint) {
function f() internal view override(A, B) returns(uint) {
return x;
}
}
// ----
// TypeError 7733: (493-494): Immutable variables cannot be read before they are initialized.
@@ -5,5 +5,3 @@ contract C {
x = 4;
}
}
// ----
// TypeError 1574: (78-79): Immutable state variable already initialized.
@@ -16,5 +16,3 @@ contract C is B {
function f() internal view override returns(uint) { return readX(); }
}
// ----
// TypeError 7733: (202-203): Immutable variables cannot be read before they are initialized.
@@ -2,11 +2,9 @@ abstract contract A {
uint public t;
constructor() { t = f(); }
function f() virtual view internal returns (uint);
function f() virtual pure internal returns (uint);
}
contract B is A {
uint immutable x = 2;
function f() override view internal returns (uint) { return x; }
function f() override pure internal returns (uint) { return x; }
}
// ----
// TypeError 7733: (223-224): Immutable variables cannot be read before they are initialized.
@@ -3,5 +3,3 @@ contract C {
uint x = f();
function f() internal pure returns (uint) { return t; }
}
// ----
// TypeError 7733: (106-107): Immutable variables cannot be read before they are initialized.
@@ -1,5 +1,5 @@
contract C {
uint immutable x ;
uint immutable x;
constructor()
{
@@ -13,4 +13,3 @@ contract C {
}
}
// ----
// TypeError 7733: (145-146): Immutable variables cannot be read before they are initialized.
@@ -2,5 +2,3 @@ contract C {
uint immutable x = 0;
uint y = x;
}
// ----
// TypeError 7733: (52-53): Immutable variables cannot be read before they are initialized.
@@ -7,4 +7,4 @@ contract C {
}
}
// ----
// TypeError 2658: (63-70): Construction control flow ends without initializing all immutable state variables.
// Warning 5740: (80-85): Unreachable code.
@@ -0,0 +1,13 @@
contract C {
uint immutable public x = 42;
function g() external view returns (uint) {}
function f() public view returns (uint) {
return this.x();
}
function h() public view returns (function () external view returns (uint)) {
return this.x;
}
}
@@ -0,0 +1,11 @@
contract C {
uint immutable public x = 42;
function g() external view returns (uint) {}
function f() public view {
this.x = this.g;
}
}
// ----
// TypeError 4247: (137-143): Expression has to be an lvalue.
@@ -31,12 +31,5 @@ contract B
revert();
}
}
// ====
// EVMVersion: >=byzantium
// ----
// TypeError 4130: (108-116): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
// TypeError 4130: (144-152): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
// TypeError 4130: (216-224): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
// TypeError 4130: (297-305): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
// TypeError 4130: (357-365): Cannot write to immutable here: Immutable variables cannot be initialized inside a try/catch statement.
@@ -1,5 +1,3 @@
contract C {
uint immutable x;
}
// ----
// TypeError 2658: (0-36): Construction control flow ends without initializing all immutable state variables.
@@ -16,6 +16,3 @@ contract C is B {
function f() internal view override returns(uint) { return readX(); }
}
// ----
// TypeError 2658: (0-202): Construction control flow ends without initializing all immutable state variables.
// TypeError 2658: (204-361): Construction control flow ends without initializing all immutable state variables.
@@ -3,6 +3,3 @@ contract C {
uint immutable x = z = y = 3;
uint immutable y = 5;
}
// ----
// TypeError 1581: (66-67): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
// TypeError 1581: (62-63): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.
@@ -1,5 +1,3 @@
contract C {
int immutable x = x = 5;
}
// ----
// TypeError 1581: (35-36): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.