Merge pull request #10051 from ethereum/contractArrayTypeStatement

Allow arrays of contract types as type expressions e.g. for abi.decode.
This commit is contained in:
Daniel Kirchner 2020-10-18 15:32:57 +02:00 committed by GitHub
commit 6aae7caec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 11 deletions

View File

@ -22,6 +22,7 @@ Bugfixes:
* Code generator: Fix internal compiler error when referencing members via module name but not using the reference. * Code generator: Fix internal compiler error when referencing members via module name but not using the reference.
* Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers. * Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers.
* Code generator: Use revert instead of invalid opcode for out-of-bounds array index access in getter. * Code generator: Use revert instead of invalid opcode for out-of-bounds array index access in getter.
* Type Checker: Allow arrays of contract types as type expressions and as arguments for ``abi.decode``.
* Type Checker: Disallow invalid use of library names as type name. * Type Checker: Disallow invalid use of library names as type name.
* Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries. * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries.
* Name Resolver: Fix shadowing/same-name warnings for later declarations. * Name Resolver: Fix shadowing/same-name warnings for later declarations.

View File

@ -2915,8 +2915,9 @@ bool TypeChecker::visit(IndexAccess const& _access)
case Type::Category::TypeType: case Type::Category::TypeType:
{ {
TypeType const& typeType = dynamic_cast<TypeType const&>(*baseType); TypeType const& typeType = dynamic_cast<TypeType const&>(*baseType);
if (dynamic_cast<ContractType const*>(typeType.actualType())) if (auto const* contractType = dynamic_cast<ContractType const*>(typeType.actualType()))
m_errorReporter.typeError(2876_error, _access.location(), "Index access for contracts or libraries is not possible."); if (contractType->contractDefinition().isLibrary())
m_errorReporter.typeError(2876_error, _access.location(), "Index access for library types and arrays of libraries are not possible.");
if (!index) if (!index)
resultType = TypeProvider::typeType(TypeProvider::array(DataLocation::Memory, typeType.actualType())); resultType = TypeProvider::typeType(TypeProvider::array(DataLocation::Memory, typeType.actualType()));
else else

View File

@ -0,0 +1,17 @@
contract C {
function f(bytes calldata x) public returns (C[] memory) {
return abi.decode(x, (C[]));
}
function g() public returns (bytes memory) {
C[] memory c = new C[](3);
c[0] = C(address(0x42));
c[1] = C(address(0x21));
c[2] = C(address(0x23));
return abi.encode(c);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03
// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23

View File

@ -0,0 +1,20 @@
pragma experimental ABIEncoderV2;
contract C {
function f(bytes calldata x) public returns (C[] memory) {
return abi.decode(x, (C[]));
}
function g() public returns (bytes memory) {
C[] memory c = new C[](3);
c[0] = C(address(0x42));
c[1] = C(address(0x21));
c[2] = C(address(0x23));
return abi.encode(c);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03
// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314
// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE
// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23

View File

@ -0,0 +1,8 @@
contract C {
function f() view public {
C[0];
}
}
// ----
// Warning 6133: (52-56): Statement has no effect.
// Warning 2018: (17-63): Function state mutability can be restricted to pure

View File

@ -1,7 +0,0 @@
contract C {
function f() view public {
C[0];
}
}
// ----
// TypeError 2876: (52-56): Index access for contracts or libraries is not possible.

View File

@ -4,4 +4,4 @@ library C {
} }
} }
// ---- // ----
// TypeError 2876: (51-55): Index access for contracts or libraries is not possible. // TypeError 2876: (51-55): Index access for library types and arrays of libraries are not possible.

View File

@ -3,4 +3,3 @@ contract s{}
function f() {s[:][];} function f() {s[:][];}
// ---- // ----
// TypeError 1760: (53-57): Types cannot be sliced. // TypeError 1760: (53-57): Types cannot be sliced.
// TypeError 2876: (53-59): Index access for contracts or libraries is not possible.

View File

@ -0,0 +1,5 @@
contract C {
function f(bytes calldata x) public pure returns (C[] memory c) {
c = abi.decode(x, (C[]));
}
}