Merge pull request #11939 from ethereum/userdefined-types-mapping-key

Allow Mapping keys to have type UserDefinedValueType.
This commit is contained in:
Harikrishnan Mulackal 2021-09-13 15:06:14 +02:00 committed by GitHub
commit 8fafdeacac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 158 additions and 16 deletions

View File

@ -253,12 +253,13 @@ void DeclarationTypeChecker::endVisit(Mapping const& _mapping)
{ {
case Type::Category::Enum: case Type::Category::Enum:
case Type::Category::Contract: case Type::Category::Contract:
case Type::Category::UserDefinedValueType:
break; break;
default: default:
m_errorReporter.fatalTypeError( m_errorReporter.fatalTypeError(
7804_error, 7804_error,
typeName->location(), typeName->location(),
"Only elementary types, contract types or enums are allowed as mapping keys." "Only elementary types, user defined value types, contract types or enums are allowed as mapping keys."
); );
break; break;
} }

View File

@ -4,7 +4,7 @@
{ {
"C": "C":
[ [
21 27
], ],
"MyAddress": "MyAddress":
[ [
@ -19,7 +19,7 @@
16 16
] ]
}, },
"id": 22, "id": 28,
"nodeType": "SourceUnit", "nodeType": "SourceUnit",
"nodes": "nodes":
[ [
@ -193,7 +193,7 @@
"parameters": [], "parameters": [],
"src": "61:0:1" "src": "61:0:1"
}, },
"scope": 22, "scope": 28,
"src": "48:47:1", "src": "48:47:1",
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"virtual": false, "virtual": false,
@ -205,10 +205,10 @@
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
"fullyImplemented": true, "fullyImplemented": true,
"id": 21, "id": 27,
"linearizedBaseContracts": "linearizedBaseContracts":
[ [
21 27
], ],
"name": "C", "name": "C",
"nameLocation": "105:1:1", "nameLocation": "105:1:1",
@ -253,12 +253,82 @@
"typeString": "uint256" "typeString": "uint256"
} }
} }
},
{
"constant": false,
"functionSelector": "97682884",
"id": 26,
"mutability": "mutable",
"name": "m",
"nameLocation": "205:1:1",
"nodeType": "VariableDeclaration",
"scope": 27,
"src": "169:37:1",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions":
{
"typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$",
"typeString": "mapping(user defined type MyAddress => user defined type MyUInt)"
},
"typeName":
{
"id": 25,
"keyType":
{
"id": 22,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 21,
"name": "MyAddress",
"nodeType": "IdentifierPath",
"referencedDeclaration": 18,
"src": "177:9:1"
},
"referencedDeclaration": 18,
"src": "177:9:1",
"typeDescriptions":
{
"typeIdentifier": "t_userDefinedValueType$_MyAddress_$18",
"typeString": "user defined type MyAddress"
}
},
"nodeType": "Mapping",
"src": "169:28:1",
"typeDescriptions":
{
"typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$",
"typeString": "mapping(user defined type MyAddress => user defined type MyUInt)"
},
"valueType":
{
"id": 24,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 23,
"name": "MyUInt",
"nodeType": "IdentifierPath",
"referencedDeclaration": 20,
"src": "190:6:1"
},
"referencedDeclaration": 20,
"src": "190:6:1",
"typeDescriptions":
{
"typeIdentifier": "t_userDefinedValueType$_MyUInt_$20",
"typeString": "user defined type MyUInt"
}
}
},
"visibility": "public"
} }
], ],
"scope": 22, "scope": 28,
"src": "96:70:1", "src": "96:113:1",
"usedErrors": [] "usedErrors": []
} }
], ],
"src": "0:167:1" "src": "0:210:1"
} }

View File

@ -7,6 +7,7 @@ function f() {
contract C { contract C {
type MyAddress is address; type MyAddress is address;
type MyUInt is uint; type MyUInt is uint;
mapping(MyAddress => MyUInt) public m;
} }
// ---- // ----

View File

@ -1,6 +1,6 @@
{ {
"absolutePath": "a", "absolutePath": "a",
"id": 22, "id": 28,
"nodeType": "SourceUnit", "nodeType": "SourceUnit",
"nodes": "nodes":
[ [
@ -154,7 +154,7 @@
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
"id": 21, "id": 27,
"name": "C", "name": "C",
"nameLocation": "105:1:1", "nameLocation": "105:1:1",
"nodeType": "ContractDefinition", "nodeType": "ContractDefinition",
@ -190,11 +190,59 @@
"src": "159:4:1", "src": "159:4:1",
"typeDescriptions": {} "typeDescriptions": {}
} }
},
{
"constant": false,
"id": 26,
"mutability": "mutable",
"name": "m",
"nameLocation": "205:1:1",
"nodeType": "VariableDeclaration",
"src": "169:37:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 25,
"keyType":
{
"id": 22,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 21,
"name": "MyAddress",
"nodeType": "IdentifierPath",
"src": "177:9:1"
},
"src": "177:9:1",
"typeDescriptions": {}
},
"nodeType": "Mapping",
"src": "169:28:1",
"typeDescriptions": {},
"valueType":
{
"id": 24,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 23,
"name": "MyUInt",
"nodeType": "IdentifierPath",
"src": "190:6:1"
},
"src": "190:6:1",
"typeDescriptions": {}
}
},
"visibility": "public"
} }
], ],
"src": "96:70:1", "src": "96:113:1",
"usedErrors": [] "usedErrors": []
} }
], ],
"src": "0:167:1" "src": "0:210:1"
} }

View File

@ -0,0 +1,18 @@
type MyInt is int;
contract C {
mapping(MyInt => int) public m;
function set(MyInt key, int value) external {
m[key] = value;
}
function set_unwrapped(int key, int value) external {
m[MyInt.wrap(key)] = value;
}
}
// ====
// compileViaYul: also
// ----
// set(int256,int256): 1, 1 ->
// m(int256): 1 -> 1
// set_unwrapped(int256,int256): 1, 2 ->
// m(int256): 1 -> 2
// m(int256): 2 -> 0

View File

@ -5,4 +5,4 @@ contract c {
mapping(S => uint) data; mapping(S => uint) data;
} }
// ---- // ----
// TypeError 7804: (47-48): Only elementary types, contract types or enums are allowed as mapping keys. // TypeError 7804: (47-48): Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.

View File

@ -5,4 +5,4 @@ contract c {
mapping(S => uint) data; mapping(S => uint) data;
} }
// ---- // ----
// TypeError 7804: (49-50): Only elementary types, contract types or enums are allowed as mapping keys. // TypeError 7804: (49-50): Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.

View File

@ -6,4 +6,4 @@ contract C {
function g (S calldata) external view {} function g (S calldata) external view {}
} }
// ---- // ----
// TypeError 7804: (56-57): Only elementary types, contract types or enums are allowed as mapping keys. // TypeError 7804: (56-57): Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.

View File

@ -0,0 +1,4 @@
type MyInt is int;
contract C {
mapping(MyInt => int) m;
}