mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
User-defined operators on structs
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
struct S {
|
||||
uint v;
|
||||
}
|
||||
|
||||
using {bitand as &} for S;
|
||||
|
||||
function bitand(S storage, S storage) returns (S storage) {
|
||||
S storage rTmp;
|
||||
return rTmp;
|
||||
}
|
||||
|
||||
contract C {
|
||||
S s;
|
||||
function f() public {
|
||||
S storage sTmp;
|
||||
sTmp & s;
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError 3464: (145-149): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError 3464: (234-238): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
struct S {
|
||||
uint v;
|
||||
}
|
||||
|
||||
using {bitor as |} for S;
|
||||
|
||||
function bitor(S storage, S storage) returns (S storage) {
|
||||
S storage rTmp;
|
||||
return rTmp;
|
||||
}
|
||||
|
||||
contract C {
|
||||
S s;
|
||||
function f() public {
|
||||
S storage sTmp;
|
||||
sTmp | s;
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError 3464: (143-147): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
// TypeError 3464: (232-236): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
struct S { Z z; }
|
||||
struct Z { int x; }
|
||||
|
||||
using {addS as +} for S;
|
||||
using {addZ as +} for Z;
|
||||
|
||||
function addS(S memory, S memory) pure returns (S memory) {}
|
||||
function addZ(Z memory, Z memory) pure returns (Z memory) { revert(); }
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
S(Z(1)) + S(Z(2) + Z(3));
|
||||
S(Z(4)) + S(Z(5)); // Unreachable
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 5740: (310-327): Unreachable code.
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
struct S { Z z; }
|
||||
struct Z { int x; }
|
||||
|
||||
using {unsubS as -} for S;
|
||||
using {unsubZ as -} for Z;
|
||||
|
||||
function unsubS(S memory) pure returns (S memory) {}
|
||||
function unsubZ(Z memory) pure returns (Z memory) { revert(); }
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
-S(-Z(1));
|
||||
-S(Z(2)); // Unreachable
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 5740: (283-291): Unreachable code.
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
struct S {
|
||||
uint8 a;
|
||||
}
|
||||
|
||||
using {
|
||||
add as +,
|
||||
sub as -,
|
||||
mul as *
|
||||
} for S;
|
||||
|
||||
function add(S memory, S memory) pure returns (S memory) {}
|
||||
function sub(S calldata, S calldata) pure returns (S calldata) {}
|
||||
function mul(S storage, S storage) pure returns (S storage) {}
|
||||
|
||||
contract C {
|
||||
S s;
|
||||
function test(S calldata c) public {
|
||||
S memory m;
|
||||
|
||||
c + c; // operator accepts memory, arguments are calldata
|
||||
s + s; // operator accepts memory, arguments are storage
|
||||
|
||||
m - m; // operator accepts calldata, arguments are memory
|
||||
s - s; // operator accepts calldata, arguments are storage
|
||||
|
||||
c * c; // operator accepts storage, arguments are calldata
|
||||
m * m; // operator accepts storage, arguments are memory
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 1349: (368-373): User-defined binary operator + cannot be applied to type struct S calldata. None of the available definitions accepts calldata arguments.
|
||||
// TypeError 1349: (434-439): User-defined binary operator + cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (500-505): User-defined binary operator - cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 1349: (566-571): User-defined binary operator - cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (634-639): User-defined binary operator * cannot be applied to type struct S calldata. None of the available definitions accepts calldata arguments.
|
||||
// TypeError 1349: (701-706): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
struct S {
|
||||
uint8 a;
|
||||
}
|
||||
|
||||
using {
|
||||
add as +,
|
||||
sub as -,
|
||||
mul as *
|
||||
} for S;
|
||||
|
||||
function add(S memory, S memory) pure returns (S memory) {}
|
||||
function sub(S calldata, S calldata) pure returns (S calldata) {}
|
||||
function mul(S storage, S storage) pure returns (S storage) {}
|
||||
|
||||
contract C {
|
||||
S s;
|
||||
function test(S calldata c) public {
|
||||
S memory m;
|
||||
|
||||
// operator accepts only memory
|
||||
m + c;
|
||||
m + s;
|
||||
c + m;
|
||||
s + m;
|
||||
|
||||
// operator accepts only calldata
|
||||
c - m;
|
||||
c - s;
|
||||
m - c;
|
||||
s - c;
|
||||
|
||||
// operator accepts only storage
|
||||
s * c;
|
||||
s * m;
|
||||
c * s;
|
||||
m * s;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 5653: (408-413): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is struct S memory.
|
||||
// TypeError 5653: (423-428): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is struct S memory.
|
||||
// TypeError 1349: (438-443): User-defined binary operator + cannot be applied to type struct S calldata. None of the available definitions accepts calldata arguments.
|
||||
// TypeError 1349: (453-458): User-defined binary operator + cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 5653: (511-516): The type of the second operand of this user-defined binary operator - does not match the type of the first operand, which is struct S calldata.
|
||||
// TypeError 5653: (526-531): The type of the second operand of this user-defined binary operator - does not match the type of the first operand, which is struct S calldata.
|
||||
// TypeError 1349: (541-546): User-defined binary operator - cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 1349: (556-561): User-defined binary operator - cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 5653: (613-618): The type of the second operand of this user-defined binary operator * does not match the type of the first operand, which is struct S storage pointer.
|
||||
// TypeError 5653: (628-633): The type of the second operand of this user-defined binary operator * does not match the type of the first operand, which is struct S storage pointer.
|
||||
// TypeError 1349: (643-648): User-defined binary operator * cannot be applied to type struct S calldata. None of the available definitions accepts calldata arguments.
|
||||
// TypeError 1349: (658-663): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
using {add as +, unsub as -} for S;
|
||||
using {mul as *, not as !} for S;
|
||||
|
||||
struct S {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function add(S memory, S memory) returns (S memory) {}
|
||||
function mul(S storage, S storage) returns (S storage) {}
|
||||
function unsub(S memory) returns (S memory) {}
|
||||
function not(S storage) returns (S storage) {}
|
||||
|
||||
contract C {
|
||||
S sRef;
|
||||
|
||||
function storageToMemory() public {
|
||||
S storage sPtr;
|
||||
S memory sMem;
|
||||
|
||||
sMem + sPtr;
|
||||
sPtr + sMem;
|
||||
sPtr + sPtr;
|
||||
|
||||
sMem + sRef;
|
||||
sRef + sMem;
|
||||
sRef + sRef;
|
||||
|
||||
sRef + sPtr;
|
||||
sPtr + sRef;
|
||||
|
||||
-sPtr;
|
||||
-sRef;
|
||||
}
|
||||
|
||||
function memoryToStorage() public {
|
||||
S memory sMem;
|
||||
S storage sPtr;
|
||||
|
||||
sMem * sPtr;
|
||||
sPtr * sMem;
|
||||
sMem * sMem;
|
||||
|
||||
sMem * sRef;
|
||||
sRef * sMem;
|
||||
sMem * sMem;
|
||||
|
||||
sRef * sPtr;
|
||||
sPtr * sRef;
|
||||
|
||||
!sMem;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 5653: (427-438): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is struct S memory.
|
||||
// TypeError 1349: (448-459): User-defined binary operator + cannot be applied to type struct S storage pointer. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (469-480): User-defined binary operator + cannot be applied to type struct S storage pointer. None of the available definitions accepts storage arguments.
|
||||
// TypeError 5653: (491-502): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is struct S memory.
|
||||
// TypeError 1349: (512-523): User-defined binary operator + cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (533-544): User-defined binary operator + cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (555-566): User-defined binary operator + cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (576-587): User-defined binary operator + cannot be applied to type struct S storage pointer. None of the available definitions accepts storage arguments.
|
||||
// TypeError 5652: (598-603): User-defined unary operator - cannot be applied to type struct S storage pointer. None of the available definitions accepts storage arguments.
|
||||
// TypeError 5652: (613-618): User-defined unary operator - cannot be applied to type struct S storage ref. None of the available definitions accepts storage arguments.
|
||||
// TypeError 1349: (723-734): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 5653: (744-755): The type of the second operand of this user-defined binary operator * does not match the type of the first operand, which is struct S storage pointer.
|
||||
// TypeError 1349: (765-776): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 1349: (787-798): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 5653: (808-819): The type of the second operand of this user-defined binary operator * does not match the type of the first operand, which is struct S storage pointer.
|
||||
// TypeError 1349: (829-840): User-defined binary operator * cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
// TypeError 5652: (894-899): User-defined unary operator ! cannot be applied to type struct S memory. None of the available definitions accepts memory arguments.
|
||||
+5
-5
@@ -6,8 +6,8 @@ using {f as +} for string;
|
||||
|
||||
function f(uint, uint) pure returns (uint) {}
|
||||
// ----
|
||||
// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (32-33): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (60-61): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (102-103): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (158-159): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types and structs.
|
||||
// TypeError 5332: (32-33): Operators can only be implemented for user-defined value types and structs.
|
||||
// TypeError 5332: (60-61): Operators can only be implemented for user-defined value types and structs.
|
||||
// TypeError 5332: (102-103): Operators can only be implemented for user-defined value types and structs.
|
||||
// TypeError 5332: (158-159): Operators can only be implemented for user-defined value types and structs.
|
||||
|
||||
+2
-2
@@ -7,5 +7,5 @@ function fa(A, A) pure returns (A) {}
|
||||
contract C {}
|
||||
abstract contract A {}
|
||||
// ----
|
||||
// TypeError 5332: (7-9): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (30-32): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (7-9): Operators can only be implemented for user-defined value types and structs.
|
||||
// TypeError 5332: (30-32): Operators can only be implemented for user-defined value types and structs.
|
||||
|
||||
@@ -7,4 +7,4 @@ enum E {
|
||||
|
||||
function add(E, E) pure returns (E) {}
|
||||
// ----
|
||||
// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types and structs.
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@ function f(I, I) pure returns (I) {}
|
||||
|
||||
interface I {}
|
||||
// ----
|
||||
// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types.
|
||||
// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types and structs.
|
||||
|
||||
@@ -5,5 +5,3 @@ struct S {
|
||||
}
|
||||
|
||||
function add(S memory, S memory) pure returns (S memory) {}
|
||||
// ----
|
||||
// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types.
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using {add as +} for S;
|
||||
|
||||
function add(S memory, S memory) pure returns (S memory) {}
|
||||
function add(S storage, S storage) pure returns (S storage) {}
|
||||
|
||||
struct S { int x; }
|
||||
// ----
|
||||
// DeclarationError 7920: (7-10): Identifier not found or not unique.
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
using {add as +} for S;
|
||||
using {add as +} for Z;
|
||||
|
||||
function add(S memory, S memory) pure returns (S memory) {}
|
||||
function add(Z memory, Z memory) pure returns (Z memory) {}
|
||||
|
||||
struct S { int x; }
|
||||
struct Z { int x; }
|
||||
// ----
|
||||
// DeclarationError 7920: (7-10): Identifier not found or not unique.
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
struct S { uint128 x; }
|
||||
|
||||
using {add as +} for S;
|
||||
using {sub as -} for S;
|
||||
using {mul as *} for S;
|
||||
using {div as *} for S;
|
||||
using {bitor as |} for S;
|
||||
using {unsub as -} for S;
|
||||
|
||||
function add(S memory, S storage) returns (S memory) {}
|
||||
function sub(S memory, S storage) returns (S storage) {}
|
||||
function mul(S storage, S memory) returns (S memory) {}
|
||||
function div(S storage, S memory) returns (S storage) {}
|
||||
function bitor(S storage, S storage) pure returns (S memory) {}
|
||||
function unsub(S memory, S memory) pure returns (S storage) {}
|
||||
// ----
|
||||
// TypeError 1884: (186-207): Wrong parameters in operator definition. The function "add" needs to have two parameters of type S and the same data location to be used for the operator +.
|
||||
// TypeError 1884: (242-263): Wrong parameters in operator definition. The function "sub" needs to have one or two parameters of type S and the same data location to be used for the operator -.
|
||||
// TypeError 7743: (272-283): Wrong return parameters in operator definition. The function "sub" needs to return a value of the same type and data location as its parameters to be used for the operator -.
|
||||
// TypeError 1884: (299-320): Wrong parameters in operator definition. The function "mul" needs to have two parameters of type S and the same data location to be used for the operator *.
|
||||
// TypeError 7743: (329-339): Wrong return parameters in operator definition. The function "mul" needs to return a value of the same type and data location as its parameters to be used for the operator *.
|
||||
// TypeError 1884: (355-376): Wrong parameters in operator definition. The function "div" needs to have two parameters of type S and the same data location to be used for the operator *.
|
||||
// TypeError 7743: (450-460): Wrong return parameters in operator definition. The function "bitor" needs to return a value of the same type and data location as its parameters to be used for the operator |.
|
||||
// TypeError 7743: (512-523): Wrong return parameters in operator definition. The function "unsub" needs to return a value of the same type and data location as its parameters to be used for the operator -.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using {
|
||||
sub as -,
|
||||
mul as *,
|
||||
div as /,
|
||||
mod as %,
|
||||
unsub as -,
|
||||
bitnot as ~
|
||||
} for S;
|
||||
|
||||
struct S {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function sub(S calldata, uint) pure returns (S calldata r) {}
|
||||
function mul(S calldata) pure returns (S calldata r) {}
|
||||
function div(S calldata, S calldata) pure returns (uint) {}
|
||||
function mod(S calldata, S calldata) pure {}
|
||||
function unsub(uint) pure returns (S calldata r) {}
|
||||
function bitnot(S calldata) pure {}
|
||||
|
||||
function test(S calldata s) pure {
|
||||
s - s;
|
||||
s * s;
|
||||
s / s;
|
||||
s % s;
|
||||
-s;
|
||||
~s;
|
||||
}
|
||||
// ----
|
||||
// TypeError 1884: (144-162): Wrong parameters in operator definition. The function "sub" needs to have one or two parameters of type S and the same data location to be used for the operator -.
|
||||
// TypeError 1884: (206-218): Wrong parameters in operator definition. The function "mul" needs to have two parameters of type S and the same data location to be used for the operator *.
|
||||
// TypeError 7743: (300-306): Wrong return parameters in operator definition. The function "div" needs to return exactly one value of type S to be used for the operator /.
|
||||
// TypeError 7743: (352-352): Wrong return parameters in operator definition. The function "mod" needs to return exactly one value of type S to be used for the operator %.
|
||||
// TypeError 1884: (369-375): Wrong parameters in operator definition. The function "unsub" needs to have one or two parameters of type S and the same data location to be used for the operator -.
|
||||
// TypeError 7743: (389-403): Wrong return parameters in operator definition. The function "unsub" needs to return a value of the same type and data location as its parameters to be used for the operator -.
|
||||
// TypeError 7743: (440-440): Wrong return parameters in operator definition. The function "bitnot" needs to return exactly one value of type S to be used for the operator ~.
|
||||
// TypeError 2271: (494-499): Built-in binary operator * cannot be applied to types struct S calldata and struct S calldata. No matching user-defined operator found.
|
||||
// TypeError 4907: (527-529): Built-in unary operator - cannot be applied to type struct S calldata. No matching user-defined operator found.
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
using {
|
||||
add as +,
|
||||
sub as -,
|
||||
mul as *,
|
||||
div as /,
|
||||
mod as %,
|
||||
unsub as -,
|
||||
bitnot as ~
|
||||
} for S;
|
||||
|
||||
struct S {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function add(S storage a, S storage) pure returns (S storage) {}
|
||||
function sub(S storage a, uint) pure returns (S storage) {}
|
||||
function mul(S storage a) pure returns (S storage) {}
|
||||
function div(S storage a, S storage) pure returns (uint) {}
|
||||
function mod(S storage a, S storage) pure {}
|
||||
function unsub(S storage a) pure {}
|
||||
function bitnot(S storage a, S storage) pure returns (S storage) {}
|
||||
|
||||
contract C {
|
||||
S a;
|
||||
S b;
|
||||
|
||||
function test() public view {
|
||||
S storage c;
|
||||
S storage d;
|
||||
|
||||
// storage ref
|
||||
a + b; // OK
|
||||
a - b;
|
||||
a * b;
|
||||
a / b;
|
||||
a % b;
|
||||
-a;
|
||||
~a;
|
||||
|
||||
// storage ptr
|
||||
c + d; // OK
|
||||
c - d;
|
||||
c * a;
|
||||
a / d;
|
||||
-c;
|
||||
~c;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 1884: (223-242): Wrong parameters in operator definition. The function "sub" needs to have one or two parameters of type S and the same data location to be used for the operator -.
|
||||
// TypeError 1884: (283-296): Wrong parameters in operator definition. The function "mul" needs to have two parameters of type S and the same data location to be used for the operator *.
|
||||
// TypeError 7743: (375-381): Wrong return parameters in operator definition. The function "div" needs to return exactly one value of type S to be used for the operator /.
|
||||
// TypeError 7743: (427-427): Wrong return parameters in operator definition. The function "mod" needs to return exactly one value of type S to be used for the operator %.
|
||||
// TypeError 7743: (463-463): Wrong return parameters in operator definition. The function "unsub" needs to return exactly one value of type S to be used for the operator -.
|
||||
// TypeError 1884: (481-505): Wrong parameters in operator definition. The function "bitnot" needs to have exactly one parameter of type S to be used for the operator ~.
|
||||
// TypeError 2271: (711-716): Built-in binary operator * cannot be applied to types struct S storage ref and struct S storage ref. No matching user-defined operator found.
|
||||
// TypeError 4907: (768-770): Built-in unary operator ~ cannot be applied to type struct S storage ref. No matching user-defined operator found.
|
||||
// TypeError 2271: (840-845): Built-in binary operator * cannot be applied to types struct S storage pointer and struct S storage ref. No matching user-defined operator found.
|
||||
// TypeError 4907: (882-884): Built-in unary operator ~ cannot be applied to type struct S storage pointer. No matching user-defined operator found.
|
||||
Reference in New Issue
Block a user