mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11806 from ethereum/user-defined-types
User defined value types
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
type MyInt is int;
|
||||
type MyByte1 is bytes1;
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
type MyUInt8 is uint8;
|
||||
type MyBytes32 is bytes32;
|
||||
|
||||
MyInt public myInt;
|
||||
MyByte1 public myByte1;
|
||||
MyAddress public myAddress;
|
||||
MyUInt8 public myUInt8;
|
||||
MyBytes32 public myBytes32;
|
||||
|
||||
function setMyInt(MyInt a) external {
|
||||
myInt = a;
|
||||
}
|
||||
function setMyByte1(MyByte1 a) external {
|
||||
myByte1 = a;
|
||||
}
|
||||
function setMyAddress(MyAddress a) external {
|
||||
myAddress = a;
|
||||
}
|
||||
function setMyUInt8(MyUInt8 a) external {
|
||||
myUInt8 = a;
|
||||
}
|
||||
function setMyBytes32(MyBytes32 a) external {
|
||||
myBytes32 = a;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// :C
|
||||
// [
|
||||
// {
|
||||
// "inputs": [],
|
||||
// "name": "myAddress",
|
||||
// "outputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyAddress",
|
||||
// "name": "",
|
||||
// "type": "address"
|
||||
// }
|
||||
// ],
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs": [],
|
||||
// "name": "myByte1",
|
||||
// "outputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyByte1",
|
||||
// "name": "",
|
||||
// "type": "bytes1"
|
||||
// }
|
||||
// ],
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs": [],
|
||||
// "name": "myBytes32",
|
||||
// "outputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyBytes32",
|
||||
// "name": "",
|
||||
// "type": "bytes32"
|
||||
// }
|
||||
// ],
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs": [],
|
||||
// "name": "myInt",
|
||||
// "outputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyInt",
|
||||
// "name": "",
|
||||
// "type": "int256"
|
||||
// }
|
||||
// ],
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs": [],
|
||||
// "name": "myUInt8",
|
||||
// "outputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyUInt8",
|
||||
// "name": "",
|
||||
// "type": "uint8"
|
||||
// }
|
||||
// ],
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyAddress",
|
||||
// "name": "a",
|
||||
// "type": "address"
|
||||
// }
|
||||
// ],
|
||||
// "name": "setMyAddress",
|
||||
// "outputs": [],
|
||||
// "stateMutability": "nonpayable",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyByte1",
|
||||
// "name": "a",
|
||||
// "type": "bytes1"
|
||||
// }
|
||||
// ],
|
||||
// "name": "setMyByte1",
|
||||
// "outputs": [],
|
||||
// "stateMutability": "nonpayable",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyBytes32",
|
||||
// "name": "a",
|
||||
// "type": "bytes32"
|
||||
// }
|
||||
// ],
|
||||
// "name": "setMyBytes32",
|
||||
// "outputs": [],
|
||||
// "stateMutability": "nonpayable",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyInt",
|
||||
// "name": "a",
|
||||
// "type": "int256"
|
||||
// }
|
||||
// ],
|
||||
// "name": "setMyInt",
|
||||
// "outputs": [],
|
||||
// "stateMutability": "nonpayable",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "user defined type MyUInt8",
|
||||
// "name": "a",
|
||||
// "type": "uint8"
|
||||
// }
|
||||
// ],
|
||||
// "name": "setMyUInt8",
|
||||
// "outputs": [],
|
||||
// "stateMutability": "nonpayable",
|
||||
// "type": "function"
|
||||
// }
|
||||
// ]
|
||||
@@ -0,0 +1,264 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
21
|
||||
],
|
||||
"MyAddress":
|
||||
[
|
||||
2
|
||||
],
|
||||
"MyUInt":
|
||||
[
|
||||
4
|
||||
],
|
||||
"f":
|
||||
[
|
||||
16
|
||||
]
|
||||
},
|
||||
"id": 22,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"name": "MyAddress",
|
||||
"nameLocation": "5:9:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "0:26:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 1,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "18:7:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "MyUInt",
|
||||
"nameLocation": "32:6:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "27:20:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 3,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "42:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 15,
|
||||
"nodeType": "Block",
|
||||
"src": "61:34:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
9
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 9,
|
||||
"mutability": "mutable",
|
||||
"name": "a",
|
||||
"nameLocation": "77:1:1",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "67:11:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_userDefinedValueType$_MyAddress_$2",
|
||||
"typeString": "user defined type MyAddress"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 8,
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"pathNode":
|
||||
{
|
||||
"id": 7,
|
||||
"name": "MyAddress",
|
||||
"nodeType": "IdentifierPath",
|
||||
"referencedDeclaration": 2,
|
||||
"src": "67:9:1"
|
||||
},
|
||||
"referencedDeclaration": 2,
|
||||
"src": "67:9:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_userDefinedValueType$_MyAddress_$2",
|
||||
"typeString": "user defined type MyAddress"
|
||||
}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 10,
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "67:11:1"
|
||||
},
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
13
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 13,
|
||||
"mutability": "mutable",
|
||||
"name": "b",
|
||||
"nameLocation": "91:1:1",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 15,
|
||||
"src": "84:8:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_userDefinedValueType$_MyUInt_$4",
|
||||
"typeString": "user defined type MyUInt"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 12,
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"pathNode":
|
||||
{
|
||||
"id": 11,
|
||||
"name": "MyUInt",
|
||||
"nodeType": "IdentifierPath",
|
||||
"referencedDeclaration": 4,
|
||||
"src": "84:6:1"
|
||||
},
|
||||
"referencedDeclaration": 4,
|
||||
"src": "84:6:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_userDefinedValueType$_MyUInt_$4",
|
||||
"typeString": "user defined type MyUInt"
|
||||
}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "84:8:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": 16,
|
||||
"implemented": true,
|
||||
"kind": "freeFunction",
|
||||
"modifiers": [],
|
||||
"name": "f",
|
||||
"nameLocation": "57:1:1",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters":
|
||||
{
|
||||
"id": 5,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "58:2:1"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 6,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "61:0:1"
|
||||
},
|
||||
"scope": 22,
|
||||
"src": "48:47:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"fullyImplemented": true,
|
||||
"id": 21,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
21
|
||||
],
|
||||
"name": "C",
|
||||
"nameLocation": "105:1:1",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"id": 18,
|
||||
"name": "MyAddress",
|
||||
"nameLocation": "118:9:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "113:26:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 17,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "131:7:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "MyUInt",
|
||||
"nameLocation": "149:6:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "144:20:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 19,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "159:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scope": 22,
|
||||
"src": "96:70:1",
|
||||
"usedErrors": []
|
||||
}
|
||||
],
|
||||
"src": "0:167:1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
type MyAddress is address;
|
||||
type MyUInt is uint;
|
||||
function f() {
|
||||
MyAddress a;
|
||||
MyUInt b;
|
||||
}
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
type MyUInt is uint;
|
||||
}
|
||||
|
||||
// ----
|
||||
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"id": 22,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"name": "MyAddress",
|
||||
"nameLocation": "5:9:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "0:26:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 1,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "18:7:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"typeDescriptions": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "MyUInt",
|
||||
"nameLocation": "32:6:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "27:20:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 3,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "42:4:1",
|
||||
"typeDescriptions": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 15,
|
||||
"nodeType": "Block",
|
||||
"src": "61:34:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
9
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 9,
|
||||
"mutability": "mutable",
|
||||
"name": "a",
|
||||
"nameLocation": "77:1:1",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"src": "67:11:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {},
|
||||
"typeName":
|
||||
{
|
||||
"id": 8,
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"pathNode":
|
||||
{
|
||||
"id": 7,
|
||||
"name": "MyAddress",
|
||||
"nodeType": "IdentifierPath",
|
||||
"src": "67:9:1"
|
||||
},
|
||||
"src": "67:9:1",
|
||||
"typeDescriptions": {}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 10,
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "67:11:1"
|
||||
},
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
13
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 13,
|
||||
"mutability": "mutable",
|
||||
"name": "b",
|
||||
"nameLocation": "91:1:1",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"src": "84:8:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {},
|
||||
"typeName":
|
||||
{
|
||||
"id": 12,
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"pathNode":
|
||||
{
|
||||
"id": 11,
|
||||
"name": "MyUInt",
|
||||
"nodeType": "IdentifierPath",
|
||||
"src": "84:6:1"
|
||||
},
|
||||
"src": "84:6:1",
|
||||
"typeDescriptions": {}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "84:8:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": 16,
|
||||
"implemented": true,
|
||||
"kind": "freeFunction",
|
||||
"modifiers": [],
|
||||
"name": "f",
|
||||
"nameLocation": "57:1:1",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters":
|
||||
{
|
||||
"id": 5,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "58:2:1"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 6,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "61:0:1"
|
||||
},
|
||||
"src": "48:47:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"id": 21,
|
||||
"name": "C",
|
||||
"nameLocation": "105:1:1",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"id": 18,
|
||||
"name": "MyAddress",
|
||||
"nameLocation": "118:9:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "113:26:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 17,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "131:7:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"typeDescriptions": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "MyUInt",
|
||||
"nameLocation": "149:6:1",
|
||||
"nodeType": "UserDefinedValueTypeDefinition",
|
||||
"src": "144:20:1",
|
||||
"underlyingType":
|
||||
{
|
||||
"id": 19,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "159:4:1",
|
||||
"typeDescriptions": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"src": "96:70:1",
|
||||
"usedErrors": []
|
||||
}
|
||||
],
|
||||
"src": "0:167:1"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
pragma abicoder v2;
|
||||
type MyAddress is address;
|
||||
|
||||
contract C {
|
||||
MyAddress[] public addresses;
|
||||
function f(MyAddress[] calldata _addresses) external {
|
||||
for (uint i = 0; i < _addresses.length; i++) {
|
||||
MyAddress.unwrap(_addresses[i]).call("");
|
||||
}
|
||||
addresses = _addresses;
|
||||
}
|
||||
function g(MyAddress[] memory _addresses) external {
|
||||
for (uint i = 0; i < _addresses.length; i++) {
|
||||
MyAddress.unwrap(_addresses[i]).call("");
|
||||
}
|
||||
addresses = _addresses;
|
||||
}
|
||||
function test_f() external returns (bool) {
|
||||
clean();
|
||||
MyAddress[] memory test = new MyAddress[](3);
|
||||
test[0] = MyAddress.wrap(address(21));
|
||||
test[1] = MyAddress.wrap(address(22));
|
||||
test[2] = MyAddress.wrap(address(23));
|
||||
this.f(test);
|
||||
test_equality(test);
|
||||
return true;
|
||||
}
|
||||
function test_g() external returns (bool) {
|
||||
clean();
|
||||
MyAddress[] memory test = new MyAddress[](5);
|
||||
test[0] = MyAddress.wrap(address(24));
|
||||
test[1] = MyAddress.wrap(address(25));
|
||||
test[2] = MyAddress.wrap(address(26));
|
||||
test[3] = MyAddress.wrap(address(27));
|
||||
test[4] = MyAddress.wrap(address(28));
|
||||
this.g(test);
|
||||
test_equality(test);
|
||||
return true;
|
||||
}
|
||||
function clean() internal {
|
||||
delete addresses;
|
||||
}
|
||||
function test_equality(MyAddress[] memory _addresses) internal view {
|
||||
require (_addresses.length == addresses.length);
|
||||
for (uint i = 0; i < _addresses.length; i++) {
|
||||
require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test_f() -> true
|
||||
// gas irOptimized: 122655
|
||||
// gas legacy: 125037
|
||||
// gas legacyOptimized: 122605
|
||||
// test_g() -> true
|
||||
// gas irOptimized: 95940
|
||||
// gas legacy: 100656
|
||||
// gas legacyOptimized: 96057
|
||||
// addresses(uint256): 0 -> 0x18
|
||||
// addresses(uint256): 1 -> 0x19
|
||||
// addresses(uint256): 3 -> 0x1b
|
||||
// addresses(uint256): 4 -> 0x1c
|
||||
// addresses(uint256): 5 -> FAILURE
|
||||
@@ -0,0 +1,44 @@
|
||||
pragma abicoder v2;
|
||||
type MyUInt8 is uint8;
|
||||
|
||||
// Note that this wraps from a uint256
|
||||
function wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }
|
||||
function unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }
|
||||
|
||||
contract C {
|
||||
uint8 a;
|
||||
MyUInt8 b;
|
||||
uint8 c;
|
||||
function ret() external returns(MyUInt8) {
|
||||
return wrap(0x1ff);
|
||||
}
|
||||
function f(MyUInt8 x) external returns(MyUInt8) {
|
||||
return x;
|
||||
}
|
||||
function mem() external returns (MyUInt8[] memory) {
|
||||
MyUInt8[] memory x = new MyUInt8[](2);
|
||||
x[0] = wrap(0x1ff);
|
||||
x[1] = wrap(0xff);
|
||||
require(unwrap(x[0]) == unwrap(x[1]));
|
||||
assembly {
|
||||
mstore(add(x, 0x20), 0x1ff)
|
||||
}
|
||||
require(unwrap(x[0]) == unwrap(x[1]));
|
||||
return x;
|
||||
}
|
||||
function stor() external returns (uint8, MyUInt8, uint8) {
|
||||
a = 1;
|
||||
c = 2;
|
||||
b = wrap(0x1ff);
|
||||
return (a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// ret() -> 0xff
|
||||
// f(uint8): 0x1ff -> FAILURE
|
||||
// f(uint8): 0xff -> 0xff
|
||||
// mem() -> 0x20, 2, 0xff, 0xff
|
||||
// stor() -> 1, 0xff, 2
|
||||
@@ -0,0 +1,44 @@
|
||||
pragma abicoder v1;
|
||||
type MyUInt8 is uint8;
|
||||
|
||||
// Note that this wraps from a uint256
|
||||
function wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }
|
||||
function unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }
|
||||
|
||||
contract C {
|
||||
uint8 a;
|
||||
MyUInt8 b;
|
||||
uint8 c;
|
||||
function ret() external returns(MyUInt8) {
|
||||
return wrap(0x1ff);
|
||||
}
|
||||
function f(MyUInt8 x) external returns(MyUInt8) {
|
||||
return x;
|
||||
}
|
||||
function mem() external returns (MyUInt8[] memory) {
|
||||
MyUInt8[] memory x = new MyUInt8[](2);
|
||||
x[0] = wrap(0x1ff);
|
||||
x[1] = wrap(0xff);
|
||||
require(unwrap(x[0]) == unwrap(x[1]));
|
||||
assembly {
|
||||
mstore(add(x, 0x20), 0x1ff)
|
||||
}
|
||||
require(unwrap(x[0]) == unwrap(x[1]));
|
||||
return x;
|
||||
}
|
||||
function stor() external returns (uint8, MyUInt8, uint8) {
|
||||
a = 1;
|
||||
c = 2;
|
||||
b = wrap(0x1ff);
|
||||
return (a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: false
|
||||
// ----
|
||||
// ret() -> 0xff
|
||||
// f(uint8): 0x1ff -> 0xff
|
||||
// f(uint8): 0xff -> 0xff
|
||||
// mem() -> 0x20, 2, 0x01ff, 0xff
|
||||
// stor() -> 1, 0xff, 2
|
||||
@@ -0,0 +1,57 @@
|
||||
pragma abicoder v2;
|
||||
|
||||
type MyUInt8 is uint8;
|
||||
type MyInt8 is int8;
|
||||
type MyUInt16 is uint16;
|
||||
|
||||
contract C {
|
||||
function f(uint a) external returns(MyUInt8) {
|
||||
return MyUInt8.wrap(uint8(a));
|
||||
}
|
||||
function g(uint a) external returns(MyInt8) {
|
||||
return MyInt8.wrap(int8(int(a)));
|
||||
}
|
||||
function h(MyUInt8 a) external returns (MyInt8) {
|
||||
return MyInt8.wrap(int8(MyUInt8.unwrap(a)));
|
||||
}
|
||||
function i(MyUInt8 a) external returns(MyUInt16) {
|
||||
return MyUInt16.wrap(MyUInt8.unwrap(a));
|
||||
}
|
||||
function j(MyUInt8 a) external returns (uint) {
|
||||
return MyUInt8.unwrap(a);
|
||||
}
|
||||
function k(MyUInt8 a) external returns (MyUInt16) {
|
||||
return MyUInt16.wrap(MyUInt8.unwrap(a));
|
||||
}
|
||||
function m(MyUInt16 a) external returns (MyUInt8) {
|
||||
return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256): 1 -> 1
|
||||
// f(uint256): 2 -> 2
|
||||
// f(uint256): 257 -> 1
|
||||
// g(uint256): 1 -> 1
|
||||
// g(uint256): 2 -> 2
|
||||
// g(uint256): 255 -> -1
|
||||
// g(uint256): 257 -> 1
|
||||
// h(uint8): 1 -> 1
|
||||
// h(uint8): 2 -> 2
|
||||
// h(uint8): 255 -> -1
|
||||
// h(uint8): 257 -> FAILURE
|
||||
// i(uint8): 250 -> 250
|
||||
// j(uint8): 1 -> 1
|
||||
// j(uint8): 2 -> 2
|
||||
// j(uint8): 255 -> 0xff
|
||||
// j(uint8): 257 -> FAILURE
|
||||
// k(uint8): 1 -> 1
|
||||
// k(uint8): 2 -> 2
|
||||
// k(uint8): 255 -> 0xff
|
||||
// k(uint8): 257 -> FAILURE
|
||||
// m(uint16): 1 -> 1
|
||||
// m(uint16): 2 -> 2
|
||||
// m(uint16): 255 -> 0xff
|
||||
// m(uint16): 257 -> 1
|
||||
@@ -0,0 +1,57 @@
|
||||
pragma abicoder v1;
|
||||
|
||||
type MyUInt8 is uint8;
|
||||
type MyInt8 is int8;
|
||||
type MyUInt16 is uint16;
|
||||
|
||||
contract C {
|
||||
function f(uint a) external returns(MyUInt8) {
|
||||
return MyUInt8.wrap(uint8(a));
|
||||
}
|
||||
function g(uint a) external returns(MyInt8) {
|
||||
return MyInt8.wrap(int8(int(a)));
|
||||
}
|
||||
function h(MyUInt8 a) external returns (MyInt8) {
|
||||
return MyInt8.wrap(int8(MyUInt8.unwrap(a)));
|
||||
}
|
||||
function i(MyUInt8 a) external returns(MyUInt16) {
|
||||
return MyUInt16.wrap(MyUInt8.unwrap(a));
|
||||
}
|
||||
function j(MyUInt8 a) external returns (uint) {
|
||||
return MyUInt8.unwrap(a);
|
||||
}
|
||||
function k(MyUInt8 a) external returns (MyUInt16) {
|
||||
return MyUInt16.wrap(MyUInt8.unwrap(a));
|
||||
}
|
||||
function m(MyUInt16 a) external returns (MyUInt8) {
|
||||
return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: false
|
||||
// ----
|
||||
// f(uint256): 1 -> 1
|
||||
// f(uint256): 2 -> 2
|
||||
// f(uint256): 257 -> 1
|
||||
// g(uint256): 1 -> 1
|
||||
// g(uint256): 2 -> 2
|
||||
// g(uint256): 255 -> -1
|
||||
// g(uint256): 257 -> 1
|
||||
// h(uint8): 1 -> 1
|
||||
// h(uint8): 2 -> 2
|
||||
// h(uint8): 255 -> -1
|
||||
// h(uint8): 257 -> 1
|
||||
// i(uint8): 250 -> 250
|
||||
// j(uint8): 1 -> 1
|
||||
// j(uint8): 2 -> 2
|
||||
// j(uint8): 255 -> 0xff
|
||||
// j(uint8): 257 -> 1
|
||||
// k(uint8): 1 -> 1
|
||||
// k(uint8): 2 -> 2
|
||||
// k(uint8): 255 -> 0xff
|
||||
// k(uint8): 257 -> 1
|
||||
// m(uint16): 1 -> 1
|
||||
// m(uint16): 2 -> 2
|
||||
// m(uint16): 255 -> 0xff
|
||||
// m(uint16): 257 -> 1
|
||||
@@ -0,0 +1,147 @@
|
||||
pragma abicoder v2;
|
||||
// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value
|
||||
// types.
|
||||
|
||||
// User defined type name. Indicating a type with 18 decimals.
|
||||
type UFixed18 is uint256;
|
||||
|
||||
library FixedMath
|
||||
{
|
||||
function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {
|
||||
return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));
|
||||
}
|
||||
function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {
|
||||
return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));
|
||||
}
|
||||
}
|
||||
|
||||
contract ERC20 {
|
||||
using FixedMath for UFixed18;
|
||||
|
||||
event Transfer(address indexed from, address indexed to, UFixed18 value);
|
||||
event Approval(address indexed owner, address indexed spender, UFixed18 value);
|
||||
|
||||
mapping (address => UFixed18) private _balances;
|
||||
mapping (address => mapping (address => UFixed18)) private _allowances;
|
||||
UFixed18 private _totalSupply;
|
||||
|
||||
constructor() {
|
||||
_mint(msg.sender, UFixed18.wrap(20));
|
||||
}
|
||||
|
||||
function totalSupply() public view returns (UFixed18) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
function balanceOf(address owner) public view returns (UFixed18) {
|
||||
return _balances[owner];
|
||||
}
|
||||
|
||||
function allowance(address owner, address spender) public view returns (UFixed18) {
|
||||
return _allowances[owner][spender];
|
||||
}
|
||||
|
||||
function transfer(address to, UFixed18 value) public returns (bool) {
|
||||
_transfer(msg.sender, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function approve(address spender, UFixed18 value) public returns (bool) {
|
||||
_approve(msg.sender, spender, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(address from, address to, UFixed18 value) public returns (bool) {
|
||||
_transfer(from, to, value);
|
||||
// The subtraction here will revert on overflow.
|
||||
_approve(from, msg.sender, _allowances[from][msg.sender].sub(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {
|
||||
// The addition here will revert on overflow.
|
||||
_approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {
|
||||
// The subtraction here will revert on overflow.
|
||||
_approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
function _transfer(address from, address to, UFixed18 value) internal {
|
||||
require(to != address(0), "ERC20: transfer to the zero address");
|
||||
|
||||
// The subtraction and addition here will revert on overflow.
|
||||
_balances[from] = _balances[from].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
emit Transfer(from, to, value);
|
||||
}
|
||||
|
||||
function _mint(address account, UFixed18 value) internal {
|
||||
require(account != address(0), "ERC20: mint to the zero address");
|
||||
|
||||
// The additions here will revert on overflow.
|
||||
_totalSupply = _totalSupply.add(value);
|
||||
_balances[account] = _balances[account].add(value);
|
||||
emit Transfer(address(0), account, value);
|
||||
}
|
||||
|
||||
function _burn(address account, UFixed18 value) internal {
|
||||
require(account != address(0), "ERC20: burn from the zero address");
|
||||
|
||||
// The subtractions here will revert on overflow.
|
||||
_totalSupply = _totalSupply.sub(value);
|
||||
_balances[account] = _balances[account].sub(value);
|
||||
emit Transfer(account, address(0), value);
|
||||
}
|
||||
|
||||
function _approve(address owner, address spender, UFixed18 value) internal {
|
||||
require(owner != address(0), "ERC20: approve from the zero address");
|
||||
require(spender != address(0), "ERC20: approve to the zero address");
|
||||
|
||||
_allowances[owner][spender] = value;
|
||||
emit Approval(owner, spender, value);
|
||||
}
|
||||
|
||||
function _burnFrom(address account, UFixed18 value) internal {
|
||||
_burn(account, value);
|
||||
_approve(account, msg.sender, _allowances[account][msg.sender].sub(value));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor()
|
||||
// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14
|
||||
// gas irOptimized: 460447
|
||||
// gas legacy: 861547
|
||||
// gas legacyOptimized: 420959
|
||||
// totalSupply() -> 20
|
||||
// gas irOptimized: 23378
|
||||
// gas legacy: 23653
|
||||
// gas legacyOptimized: 23368
|
||||
// transfer(address,uint256): 2, 5 -> true
|
||||
// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05
|
||||
// gas irOptimized: 48514
|
||||
// gas legacy: 49572
|
||||
// gas legacyOptimized: 48575
|
||||
// decreaseAllowance(address,uint256): 2, 0 -> true
|
||||
// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00
|
||||
// gas irOptimized: 26316
|
||||
// gas legacy: 27204
|
||||
// gas legacyOptimized: 26317
|
||||
// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11
|
||||
// gas irOptimized: 24040
|
||||
// gas legacy: 24506
|
||||
// gas legacyOptimized: 24077
|
||||
// transfer(address,uint256): 2, 14 -> true
|
||||
// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e
|
||||
// gas irOptimized: 28614
|
||||
// gas legacy: 29672
|
||||
// gas legacyOptimized: 28675
|
||||
// transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11
|
||||
// gas irOptimized: 24052
|
||||
// gas legacy: 24492
|
||||
// gas legacyOptimized: 24074
|
||||
@@ -0,0 +1,42 @@
|
||||
// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.
|
||||
type UFixed256x18 is uint256;
|
||||
|
||||
/// A minimal library to do fixed point operations on UFixed256x18.
|
||||
library FixedMath {
|
||||
/// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on
|
||||
/// uint256.
|
||||
function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {
|
||||
return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));
|
||||
}
|
||||
/// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on
|
||||
/// uint256.
|
||||
function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {
|
||||
return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);
|
||||
}
|
||||
/// Truncates UFixed256x18 to the nearest uint256 number.
|
||||
function truncate(UFixed256x18 a) internal returns (uint256) {
|
||||
return UFixed256x18.unwrap(a) / 10**18;
|
||||
}
|
||||
}
|
||||
|
||||
contract TestFixedMath {
|
||||
function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {
|
||||
return FixedMath.add(a, b);
|
||||
}
|
||||
function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {
|
||||
return FixedMath.mul(a, b);
|
||||
}
|
||||
function truncate(UFixed256x18 a) external returns (uint256) {
|
||||
return FixedMath.truncate(a);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// add(uint256,uint256): 0, 0 -> 0
|
||||
// add(uint256,uint256): 25, 45 -> 0x46
|
||||
// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex"4e487b71", 0x11
|
||||
// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex"4e487b71", 0x11
|
||||
// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120
|
||||
// truncate(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457
|
||||
// truncate(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457
|
||||
@@ -0,0 +1,32 @@
|
||||
// Implementation of OpenZepplin's
|
||||
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol
|
||||
// using user defined value types.
|
||||
|
||||
contract Ownable {
|
||||
type Owner is address;
|
||||
Owner public owner = Owner.wrap(msg.sender);
|
||||
error OnlyOwner();
|
||||
modifier onlyOwner() {
|
||||
if (Owner.unwrap(owner) != msg.sender)
|
||||
revert OnlyOwner();
|
||||
|
||||
_;
|
||||
}
|
||||
event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);
|
||||
function setOwner(Owner newOwner) onlyOwner external {
|
||||
emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});
|
||||
owner = newOwner;
|
||||
}
|
||||
function renounceOwnership() onlyOwner external {
|
||||
owner = Owner.wrap(address(0));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// owner() -> 0x1212121212121212121212121212120000000012
|
||||
// setOwner(address): 0x1212121212121212121212121212120000000012 ->
|
||||
// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012
|
||||
// renounceOwnership() ->
|
||||
// owner() -> 0
|
||||
// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex"5fc483c5"
|
||||
@@ -0,0 +1,42 @@
|
||||
pragma abicoder v2;
|
||||
|
||||
type MyAddress is address;
|
||||
contract C {
|
||||
function id(MyAddress a) external returns (MyAddress b) {
|
||||
b = a;
|
||||
}
|
||||
|
||||
function unwrap_assembly(MyAddress a) external returns (address b) {
|
||||
assembly { b := a }
|
||||
}
|
||||
|
||||
function wrap_assembly(address a) external returns (MyAddress b) {
|
||||
assembly { b := a }
|
||||
}
|
||||
|
||||
function unwrap(MyAddress a) external returns (address b) {
|
||||
b = MyAddress.unwrap(a);
|
||||
}
|
||||
function wrap(address a) external returns (MyAddress b) {
|
||||
b = MyAddress.wrap(a);
|
||||
}
|
||||
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// id(address): 5 -> 5
|
||||
// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff
|
||||
// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
|
||||
// unwrap(address): 5 -> 5
|
||||
// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff
|
||||
// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
|
||||
// wrap(address): 5 -> 5
|
||||
// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff
|
||||
// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
|
||||
// unwrap_assembly(address): 5 -> 5
|
||||
// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff
|
||||
// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
|
||||
// wrap_assembly(address): 5 -> 5
|
||||
// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff
|
||||
// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
|
||||
@@ -0,0 +1,14 @@
|
||||
type MyInt is int;
|
||||
contract C {
|
||||
function f() external pure returns (MyInt a) {
|
||||
}
|
||||
function g() external pure returns (MyInt b, MyInt c) {
|
||||
b = MyInt.wrap(int(1));
|
||||
c = MyInt.wrap(1);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0
|
||||
// g() -> 1, 1
|
||||
@@ -0,0 +1,11 @@
|
||||
type MyAddress is address;
|
||||
contract C {
|
||||
function f() pure public {
|
||||
MyAddress.wrap;
|
||||
MyAddress.unwrap;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() ->
|
||||
@@ -0,0 +1,5 @@
|
||||
type MyInt is uint;
|
||||
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
type(MyInt) is uint256;
|
||||
// ----
|
||||
// ParserError 2314: (4-5): Expected identifier but got '('
|
||||
@@ -0,0 +1,6 @@
|
||||
function f() {
|
||||
type(uint).max;
|
||||
type MyInt is int;
|
||||
}
|
||||
// ----
|
||||
// ParserError 2314: (44-49): Expected ';' but got identifier
|
||||
@@ -0,0 +1,12 @@
|
||||
type MyAddress is address;
|
||||
type MyAddressPayable is address payable;
|
||||
type MyInt is int;
|
||||
type MyUInt is uint;
|
||||
type MyInt128 is int128;
|
||||
type MyUInt128 is uint128;
|
||||
// TODO add fixed point type, when it's implemented
|
||||
type MyFixedBytes32 is bytes32;
|
||||
type MyFixedBytes1 is bytes1;
|
||||
type MyBool is bool;
|
||||
/// test to see if having NatSpec causes issues
|
||||
type redundantNatSpec is bytes2;
|
||||
@@ -0,0 +1,6 @@
|
||||
type MyAddress is address;
|
||||
function f() {
|
||||
MyAddress a = MyAddress(5, 2);
|
||||
}
|
||||
// ----
|
||||
// TypeError 2558: (60-75): Exactly one argument expected for explicit type conversion.
|
||||
@@ -0,0 +1,4 @@
|
||||
type MyInt is int;
|
||||
function f(MyInt a) pure returns (MyInt b) {
|
||||
b = MyInt(a);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
type MyUInt is uint;
|
||||
type MyAddress is address;
|
||||
type AnotherUInt is uint;
|
||||
|
||||
function f() pure {
|
||||
MyUInt(-1);
|
||||
MyAddress(-1);
|
||||
MyUInt(5);
|
||||
MyAddress(address(5));
|
||||
|
||||
AnotherUInt(MyUInt.wrap(5));
|
||||
MyUInt(AnotherUInt.wrap(10));
|
||||
AnotherUInt.unwrap(MyUInt.wrap(5));
|
||||
MyUInt.unwrap(AnotherUInt.wrap(10));
|
||||
}
|
||||
// ----
|
||||
// TypeError 9640: (99-109): Explicit type conversion not allowed from "int_const -1" to "user defined type MyUInt".
|
||||
// TypeError 9640: (115-128): Explicit type conversion not allowed from "int_const -1" to "user defined type MyAddress".
|
||||
// TypeError 9640: (134-143): Explicit type conversion not allowed from "int_const 5" to "user defined type MyUInt".
|
||||
// TypeError 9640: (149-170): Explicit type conversion not allowed from "address" to "user defined type MyAddress".
|
||||
// TypeError 9640: (177-204): Explicit type conversion not allowed from "user defined type MyUInt" to "user defined type AnotherUInt".
|
||||
// TypeError 9640: (210-238): Explicit type conversion not allowed from "user defined type AnotherUInt" to "user defined type MyUInt".
|
||||
// TypeError 9553: (263-277): Invalid type for argument in function call. Invalid implicit conversion from user defined type MyUInt to user defined type AnotherUInt requested.
|
||||
// TypeError 9553: (298-318): Invalid type for argument in function call. Invalid implicit conversion from user defined type AnotherUInt to user defined type MyUInt requested.
|
||||
@@ -0,0 +1,8 @@
|
||||
type MyUint is uint;
|
||||
type MyAddress is address;
|
||||
|
||||
function f() pure {
|
||||
MyUint.wrap(5);
|
||||
MyAddress.wrap(address(5));
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,9 @@
|
||||
type MyAddress is address;
|
||||
type MyUInt8 is uint8;
|
||||
|
||||
function f() pure {
|
||||
MyAddress.wrap(address(5));
|
||||
MyUInt8.wrap(5);
|
||||
MyUInt8.wrap(50);
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,4 @@
|
||||
function f(MyIntB x) pure {}
|
||||
type MyIntB is MyIntB;
|
||||
// ----
|
||||
// TypeError 8657: (44-50): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,14 @@
|
||||
type MyInt is uint;
|
||||
type MyAddress is address;
|
||||
function f() pure {
|
||||
MyInt a;
|
||||
MyInt b = a;
|
||||
MyAddress c;
|
||||
MyAddress d = c;
|
||||
b;
|
||||
d;
|
||||
}
|
||||
|
||||
function g(MyInt a) pure returns (MyInt) {
|
||||
return a;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
type MyInt is int;
|
||||
function f(int a) pure returns (int) {
|
||||
MyInt b = a;
|
||||
|
||||
int c = b;
|
||||
|
||||
address d = b;
|
||||
|
||||
MyInt e = d;
|
||||
|
||||
uint x = 0;
|
||||
MyInt y = MyInt(x);
|
||||
|
||||
return e;
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (62-73): Type int256 is not implicitly convertible to expected type user defined type MyInt.
|
||||
// TypeError 9574: (80-89): Type user defined type MyInt is not implicitly convertible to expected type int256.
|
||||
// TypeError 9574: (96-109): Type user defined type MyInt is not implicitly convertible to expected type address.
|
||||
// TypeError 9574: (116-127): Type address is not implicitly convertible to expected type user defined type MyInt.
|
||||
// TypeError 9640: (160-168): Explicit type conversion not allowed from "uint256" to "user defined type MyInt".
|
||||
// TypeError 6359: (182-183): Return argument type user defined type MyInt is not implicitly convertible to expected type (type of first return variable) int256.
|
||||
@@ -0,0 +1,7 @@
|
||||
type MyInt is int;
|
||||
function f() pure {
|
||||
(MyInt).wrap;
|
||||
(MyInt).wrap(5);
|
||||
(MyInt).unwrap;
|
||||
(MyInt).unwrap(MyInt.wrap(5));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
type MyAddress is address;
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
}
|
||||
// ----
|
||||
// Warning 2519: (44-70): This declaration shadows an existing declaration.
|
||||
@@ -0,0 +1,9 @@
|
||||
type MyInt is int;
|
||||
type MyInt is address;
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
type MyAddress is address;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 2333: (19-41): Identifier already declared.
|
||||
// DeclarationError 2333: (90-116): Identifier already declared.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyBytes is bytes;
|
||||
// ----
|
||||
// TypeError 8129: (0-22): The underlying type of the user defined value type "MyBytes" is not a value type.
|
||||
@@ -0,0 +1,4 @@
|
||||
contract C {}
|
||||
type MyContract is C;
|
||||
// ----
|
||||
// TypeError 8657: (33-34): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyFunction is function(uint) returns (uint);
|
||||
// ----
|
||||
// TypeError 8657: (19-49): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyInt is mapping(uint => uint);
|
||||
// ----
|
||||
// TypeError 8657: (14-35): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyString is string;
|
||||
// ----
|
||||
// TypeError 8129: (0-24): The underlying type of the user defined value type "MyString" is not a value type.
|
||||
@@ -0,0 +1,7 @@
|
||||
struct S {uint x;}
|
||||
|
||||
contract C {
|
||||
type MyType is S;
|
||||
}
|
||||
// ----
|
||||
// TypeError 8657: (52-53): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,19 @@
|
||||
type MyAddress is address;
|
||||
interface I {}
|
||||
contract C {
|
||||
function f(MyAddress a) external {
|
||||
}
|
||||
function f(address a) external {
|
||||
}
|
||||
}
|
||||
contract D {
|
||||
function g(MyAddress a) external {
|
||||
}
|
||||
}
|
||||
contract E is D {
|
||||
function g(I a) external {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9914: (104-142): Function overload clash during conversion to external types for arguments.
|
||||
// TypeError 9914: (162-202): Function overload clash during conversion to external types for arguments.
|
||||
@@ -0,0 +1,4 @@
|
||||
type MyInt1 is MyInt2;
|
||||
type MyInt2 is MyInt1;
|
||||
// ----
|
||||
// TypeError 8657: (15-21): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyFunction is function(MyFunction) external returns(MyFunction);
|
||||
// ----
|
||||
// TypeError 8657: (19-69): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,13 @@
|
||||
library L {
|
||||
type MyInt is int;
|
||||
}
|
||||
|
||||
contract C {
|
||||
L.MyInt a;
|
||||
type MyInt is int8;
|
||||
}
|
||||
|
||||
contract D is C {
|
||||
C.MyInt b;
|
||||
L.MyInt c;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
type MyInt is int;
|
||||
type MyInt is int;
|
||||
type MyAddress is address;
|
||||
type MyAddress is uint;
|
||||
// ----
|
||||
// DeclarationError 2333: (19-37): Identifier already declared.
|
||||
// DeclarationError 2333: (65-88): Identifier already declared.
|
||||
@@ -0,0 +1,3 @@
|
||||
type MyInt is MyInt;
|
||||
// ----
|
||||
// TypeError 8657: (14-19): The underlying type for a user defined value type has to be an elementary value type.
|
||||
@@ -0,0 +1,8 @@
|
||||
type MyInt is int;
|
||||
function test() pure {
|
||||
function (MyInt) returns (int) f = MyInt.unwrap;
|
||||
function (int) returns (MyInt) g = MyInt.wrap;
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (46-93): Type function (user defined type MyInt) pure returns (int256) is not implicitly convertible to expected type function (user defined type MyInt) returns (int256). Special functions can not be converted to function types.
|
||||
// TypeError 9574: (99-144): Type function (int256) pure returns (user defined type MyInt) is not implicitly convertible to expected type function (int256) returns (user defined type MyInt). Special functions can not be converted to function types.
|
||||
@@ -0,0 +1,16 @@
|
||||
type MyInt is int;
|
||||
function f() {
|
||||
MyInt.wrap(5, 6, 7);
|
||||
MyInt.wrap({test: 5});
|
||||
MyInt.wrap();
|
||||
MyInt.unwrap(5);
|
||||
MyInt.unwrap({test: 5});
|
||||
MyInt.unwrap(MyInt.wrap(1), MyInt.wrap(2));
|
||||
}
|
||||
// ----
|
||||
// TypeError 6160: (38-57): Wrong argument count for function call: 3 arguments given but expected 1.
|
||||
// TypeError 4974: (63-84): Named argument "test" does not match function declaration.
|
||||
// TypeError 6160: (90-102): Wrong argument count for function call: 0 arguments given but expected 1.
|
||||
// TypeError 9553: (121-122): Invalid type for argument in function call. Invalid implicit conversion from int_const 5 to user defined type MyInt requested.
|
||||
// TypeError 4974: (129-152): Named argument "test" does not match function declaration.
|
||||
// TypeError 6160: (158-200): Wrong argument count for function call: 2 arguments given but expected 1.
|
||||
Reference in New Issue
Block a user