Allow user-defined types as mapping keys in parser and restrict to contracts during type checking.

This commit is contained in:
Daniel Kirchner
2020-02-04 17:22:03 +01:00
parent 7a194ffdab
commit d3cbfb0c5c
25 changed files with 808 additions and 18 deletions
@@ -0,0 +1,28 @@
interface A {}
contract test {
mapping(A => uint8) table;
function get(A k) public returns (uint8 v) {
return table[k];
}
function set(A k, uint8 v) public {
table[k] = v;
}
}
// ====
// compileViaYul: also
// ----
// get(address): 0 -> 0
// get(address): 0x01 -> 0
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0xa1 ->
// get(address): 0 -> 0
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x00, 0xef ->
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0x05 ->
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0x05
// get(address): 0xa7 -> 0
@@ -0,0 +1,38 @@
interface A {}
contract test {
mapping(A => uint8) public table;
function set(A k, uint8 v) public {
table[k] = v;
}
function get(A k) public returns (uint8) {
return this.table(k);
}
}
// ----
// table(address): 0 -> 0
// table(address): 0x01 -> 0
// table(address): 0xa7 -> 0
// get(address): 0 -> 0
// get(address): 0x01 -> 0
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0xa1 ->
// table(address): 0 -> 0
// table(address): 0x01 -> 0xa1
// table(address): 0xa7 -> 0
// get(address): 0 -> 0
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x00, 0xef ->
// table(address): 0 -> 0xef
// table(address): 0x01 -> 0xa1
// table(address): 0xa7 -> 0
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0x05 ->
// table(address): 0 -> 0xef
// table(address): 0x01 -> 0x05
// table(address): 0xa7 -> 0
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0x05
// get(address): 0xa7 -> 0
@@ -0,0 +1,35 @@
interface A {}
library L {
function get(mapping(A => uint8) storage table, A k) external returns (uint8) {
return table[k];
}
function set(mapping(A => uint8) storage table, A k, uint8 v) external {
table[k] = v;
}
}
contract test {
mapping(A => uint8) table;
function get(A k) public returns (uint8 v) {
return L.get(table, k);
}
function set(A k, uint8 v) public {
L.set(table, k, v);
}
}
// ----
// library: L
// get(address): 0 -> 0
// get(address): 0x01 -> 0
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0xa1 ->
// get(address): 0 -> 0
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x00, 0xef ->
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0xa1
// get(address): 0xa7 -> 0
// set(address,uint8): 0x01, 0x05 ->
// get(address): 0 -> 0xef
// get(address): 0x01 -> 0x05
// get(address): 0xa7 -> 0
@@ -0,0 +1,30 @@
enum E { A, B, C }
contract test {
mapping(E => uint8) table;
function get(E k) public returns (uint8 v) {
return table[k];
}
function set(E k, uint8 v) public {
table[k] = v;
}
}
// ====
// compileViaYul: also
// ----
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0
// get(uint8): 0x02 -> 0
// get(uint8): 0x03 -> FAILURE
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0xa1 ->
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x00, 0xef ->
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0x05 ->
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0x05
// get(uint8): 0xa7 -> FAILURE
@@ -0,0 +1,38 @@
contract test {
enum E { A, B, C }
mapping(E => uint8) public table;
function set(E k, uint8 v) public {
table[k] = v;
}
function get(E k) public returns (uint8) {
return this.table(k);
}
}
// ----
// table(uint8): 0 -> 0
// table(uint8): 0x01 -> 0
// table(uint8): 0xa7 -> 0
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0xa1 ->
// table(uint8): 0 -> 0
// table(uint8): 0x01 -> 0xa1
// table(uint8): 0xa7 -> 0
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x00, 0xef ->
// table(uint8): 0 -> 0xef
// table(uint8): 0x01 -> 0xa1
// table(uint8): 0xa7 -> 0
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0x05 ->
// table(uint8): 0 -> 0xef
// table(uint8): 0x01 -> 0x05
// table(uint8): 0xa7 -> 0
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0x05
// get(uint8): 0xa7 -> FAILURE
@@ -0,0 +1,39 @@
pragma experimental ABIEncoderV2;
contract test {
enum E { A, B, C }
mapping(E => uint8) public table;
function set(E k, uint8 v) public {
table[k] = v;
}
function get(E k) public returns (uint8) {
return this.table(k);
}
}
// ----
// table(uint8): 0 -> 0
// table(uint8): 0x01 -> 0
// table(uint8): 0xa7 -> FAILURE
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0xa1 ->
// table(uint8): 0 -> 0
// table(uint8): 0x01 -> 0xa1
// table(uint8): 0xa7 -> FAILURE
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x00, 0xef ->
// table(uint8): 0 -> 0xef
// table(uint8): 0x01 -> 0xa1
// table(uint8): 0xa7 -> FAILURE
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0x05 ->
// table(uint8): 0 -> 0xef
// table(uint8): 0x01 -> 0x05
// table(uint8): 0xa7 -> FAILURE
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0x05
// get(uint8): 0xa7 -> FAILURE
@@ -0,0 +1,35 @@
enum E { A, B, C }
library L {
function get(mapping(E => uint8) storage table, E k) external returns (uint8) {
return table[k];
}
function set(mapping(E => uint8) storage table, E k, uint8 v) external {
table[k] = v;
}
}
contract test {
mapping(E => uint8) table;
function get(E k) public returns (uint8 v) {
return L.get(table, k);
}
function set(E k, uint8 v) public {
L.set(table, k, v);
}
}
// ----
// library: L
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0xa1 ->
// get(uint8): 0 -> 0
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x00, 0xef ->
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0xa1
// get(uint8): 0xa7 -> FAILURE
// set(uint8,uint8): 0x01, 0x05 ->
// get(uint8): 0 -> 0xef
// get(uint8): 0x01 -> 0x05
// get(uint8): 0xa7 -> FAILURE