mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow using overloaded functions as literal suffixes
This commit is contained in:
parent
976f014c12
commit
2bf76afec1
@ -3034,10 +3034,6 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
|
|||||||
|
|
||||||
bool TypeChecker::visit(FunctionCall const& _functionCall)
|
bool TypeChecker::visit(FunctionCall const& _functionCall)
|
||||||
{
|
{
|
||||||
solAssert(!m_currentSuffixCall);
|
|
||||||
if (_functionCall.isSuffixCall())
|
|
||||||
m_currentSuffixCall = &_functionCall;
|
|
||||||
|
|
||||||
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
|
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
|
||||||
bool argumentsArePure = true;
|
bool argumentsArePure = true;
|
||||||
|
|
||||||
@ -3058,7 +3054,8 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
|
|||||||
for (ASTPointer<Expression const> const& argument: arguments)
|
for (ASTPointer<Expression const> const& argument: arguments)
|
||||||
funcCallArgs.types.push_back(type(*argument));
|
funcCallArgs.types.push_back(type(*argument));
|
||||||
|
|
||||||
_functionCall.expression().annotation().arguments = std::move(funcCallArgs);
|
if (!_functionCall.isSuffixCall())
|
||||||
|
_functionCall.expression().annotation().arguments = std::move(funcCallArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
_functionCall.expression().accept(*this);
|
_functionCall.expression().accept(*this);
|
||||||
@ -3234,7 +3231,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentSuffixCall = nullptr;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3453,62 +3449,15 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
size_t const initialMemberCount = possibleMembers.size();
|
size_t const initialMemberCount = possibleMembers.size();
|
||||||
if (initialMemberCount > 1 && arguments)
|
if (initialMemberCount > 1 && arguments)
|
||||||
{
|
{
|
||||||
RationalNumberType const* mantissa = nullptr;
|
|
||||||
RationalNumberType const* exponent = nullptr;
|
|
||||||
RationalNumberType const* literalRationalType = nullptr;
|
|
||||||
if (m_currentSuffixCall)
|
|
||||||
{
|
|
||||||
if (annotation.arguments->types.size() == 1)
|
|
||||||
{
|
|
||||||
solAssert(annotation.arguments->types[0]);
|
|
||||||
literalRationalType = dynamic_cast<RationalNumberType const*>(annotation.arguments->types[0]);
|
|
||||||
if (literalRationalType)
|
|
||||||
tie(mantissa, exponent) = literalRationalType->fractionalDecomposition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do overload resolution
|
// do overload resolution
|
||||||
for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
|
for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
|
||||||
{
|
if (
|
||||||
bool viableCandidate = false;
|
it->type->category() == Type::Category::Function &&
|
||||||
if (it->type->category() == Type::Category::Function)
|
!dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*arguments, exprType)
|
||||||
{
|
)
|
||||||
FunctionTypePointer functionType = dynamic_cast<FunctionType const*>(it->type);
|
|
||||||
solAssert(functionType);
|
|
||||||
|
|
||||||
if (!m_currentSuffixCall || m_currentSuffixCall->expression() != _memberAccess)
|
|
||||||
viableCandidate = functionType->canTakeArguments(*arguments, exprType);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: We're before type-checking of suffix calls so we can't yet assume that
|
|
||||||
// the suffix is not something weird, including being a bound function.
|
|
||||||
|
|
||||||
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(it->declaration);
|
|
||||||
|
|
||||||
bool isSuffixFunction =
|
|
||||||
functionDefinition &&
|
|
||||||
functionDefinition->usableAsSuffix();
|
|
||||||
bool singleArgumentMatch =
|
|
||||||
functionType->parameterTypes().size() == 1 &&
|
|
||||||
functionType->canTakeArguments(*annotation.arguments);
|
|
||||||
bool mantissaExponentMatch =
|
|
||||||
functionType->parameterTypes().size() == 2 &&
|
|
||||||
literalRationalType &&
|
|
||||||
// NOTE: If the literal cannot be decomposed it's fine to act as if suffix could not take it.
|
|
||||||
// It will be reported as error when type-checking the suffix call anyway.
|
|
||||||
mantissa &&
|
|
||||||
exponent &&
|
|
||||||
functionType->canTakeArguments({{mantissa, exponent}, {}});
|
|
||||||
|
|
||||||
viableCandidate = isSuffixFunction && (singleArgumentMatch || mantissaExponentMatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viableCandidate)
|
|
||||||
++it;
|
|
||||||
else
|
|
||||||
it = possibleMembers.erase(it);
|
it = possibleMembers.erase(it);
|
||||||
}
|
else
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation.isConstant = false;
|
annotation.isConstant = false;
|
||||||
@ -4018,8 +3967,6 @@ bool TypeChecker::visit(Identifier const& _identifier)
|
|||||||
annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin();
|
annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin();
|
||||||
else if (!annotation.arguments)
|
else if (!annotation.arguments)
|
||||||
{
|
{
|
||||||
solAssert(!m_currentSuffixCall);
|
|
||||||
|
|
||||||
// The identifier should be a public state variable shadowing other functions
|
// The identifier should be a public state variable shadowing other functions
|
||||||
vector<Declaration const*> candidates;
|
vector<Declaration const*> candidates;
|
||||||
|
|
||||||
@ -4037,54 +3984,16 @@ bool TypeChecker::visit(Identifier const& _identifier)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vector<Declaration const*> candidates;
|
// NOTE: Suffix calls intentionally have no 'arguments' annotation so that they never enter this branch.
|
||||||
|
|
||||||
RationalNumberType const* mantissa = nullptr;
|
vector<Declaration const*> candidates;
|
||||||
RationalNumberType const* exponent = nullptr;
|
|
||||||
RationalNumberType const* literalRationalType = nullptr;
|
|
||||||
if (m_currentSuffixCall)
|
|
||||||
{
|
|
||||||
if (annotation.arguments->types.size() == 1)
|
|
||||||
{
|
|
||||||
solAssert(annotation.arguments->types[0]);
|
|
||||||
literalRationalType = dynamic_cast<RationalNumberType const*>(annotation.arguments->types[0]);
|
|
||||||
if (literalRationalType)
|
|
||||||
tie(mantissa, exponent) = literalRationalType->fractionalDecomposition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Declaration const* declaration: annotation.overloadedDeclarations)
|
for (Declaration const* declaration: annotation.overloadedDeclarations)
|
||||||
{
|
{
|
||||||
FunctionTypePointer functionType = declaration->functionType(true /* _internal */);
|
FunctionTypePointer functionType = declaration->functionType(true /* _internal */);
|
||||||
solAssert(!!functionType, "Requested type not present.");
|
solAssert(!!functionType, "Requested type not present.");
|
||||||
|
if (functionType->canTakeArguments(*annotation.arguments))
|
||||||
if (!m_currentSuffixCall)
|
candidates.push_back(declaration);
|
||||||
{
|
|
||||||
if (functionType->canTakeArguments(*annotation.arguments))
|
|
||||||
candidates.push_back(declaration);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(declaration);
|
|
||||||
|
|
||||||
bool isSuffixFunction =
|
|
||||||
functionDefinition &&
|
|
||||||
functionDefinition->usableAsSuffix();
|
|
||||||
bool singleArgumentMatch =
|
|
||||||
functionType->parameterTypes().size() == 1 &&
|
|
||||||
functionType->canTakeArguments(*annotation.arguments);
|
|
||||||
bool mantissaExponentMatch =
|
|
||||||
functionType->parameterTypes().size() == 2 &&
|
|
||||||
literalRationalType &&
|
|
||||||
// NOTE: If the literal cannot be decomposed it's fine to act as if suffix could not take it.
|
|
||||||
// It will be reported as error when type-checking the suffix call anyway.
|
|
||||||
mantissa &&
|
|
||||||
exponent &&
|
|
||||||
functionType->canTakeArguments({{mantissa, exponent}, {}});
|
|
||||||
|
|
||||||
if (isSuffixFunction && (singleArgumentMatch || mantissaExponentMatch))
|
|
||||||
candidates.push_back(declaration);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (candidates.size() == 1)
|
if (candidates.size() == 1)
|
||||||
annotation.referencedDeclaration = candidates.front();
|
annotation.referencedDeclaration = candidates.front();
|
||||||
|
@ -206,7 +206,6 @@ private:
|
|||||||
|
|
||||||
SourceUnit const* m_currentSourceUnit = nullptr;
|
SourceUnit const* m_currentSourceUnit = nullptr;
|
||||||
ContractDefinition const* m_currentContract = nullptr;
|
ContractDefinition const* m_currentContract = nullptr;
|
||||||
FunctionCall const* m_currentSuffixCall = nullptr;
|
|
||||||
|
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
|
|
||||||
|
@ -214,13 +214,6 @@
|
|||||||
],
|
],
|
||||||
"expression":
|
"expression":
|
||||||
{
|
{
|
||||||
"argumentTypes":
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"typeIdentifier": "t_rational_123345789_by_1000000",
|
|
||||||
"typeString": "rational_const 123345789 / 1000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"id": 13,
|
"id": 13,
|
||||||
"name": "str",
|
"name": "str",
|
||||||
"nodeType": "Identifier",
|
"nodeType": "Identifier",
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
function suffix(uint x) pure suffix returns (uint) { return x; }
|
|
||||||
function suffix(bool x) pure suffix returns (bool) { return x; }
|
|
||||||
function suffix(address x) pure suffix returns (address) { return x; }
|
|
||||||
function suffix(string memory x) pure suffix returns (string memory) { return x; }
|
|
||||||
|
|
||||||
contract C {
|
|
||||||
function run() public returns (bytes memory) {
|
|
||||||
return abi.encode(
|
|
||||||
42 suffix,
|
|
||||||
true suffix,
|
|
||||||
0x1234567890123456789012345678901234567890 suffix,
|
|
||||||
"a" suffix
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ----
|
|
||||||
// run() -> 0x20, 0xc0, 0x2a, 1, 0x1234567890123456789012345678901234567890, 0x80, 1, "a"
|
|
@ -5,7 +5,6 @@ function suffix(string memory) pure suffix returns (string memory) {}
|
|||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
int a = 1 suffix;
|
int a = 1 suffix;
|
||||||
bool b = true suffix;
|
|
||||||
address c = 0x1234567890123456789012345678901234567890 suffix;
|
|
||||||
string d = "a" suffix;
|
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (259-265): No matching declaration found after variable lookup.
|
||||||
|
@ -6,4 +6,4 @@ contract C {
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2998: (74-89): This literal suffix function is not usable as a suffix because no literal is implicitly convertible to its parameter type.
|
// TypeError 2998: (74-89): This literal suffix function is not usable as a suffix because no literal is implicitly convertible to its parameter type.
|
||||||
// TypeError 7407: (170-219): Type address is not implicitly convertible to expected type address payable.
|
// TypeError 2144: (213-219): No matching declaration found after variable lookup.
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
function s(uint) pure suffix returns (uint) {}
|
||||||
|
function s(string memory) pure returns (string memory) {}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function run() public pure {
|
||||||
|
"a" s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (164-165): No matching declaration found after variable lookup.
|
@ -0,0 +1,10 @@
|
|||||||
|
function s(uint) pure suffix returns (uint) {}
|
||||||
|
function s(string memory) pure returns (string memory) {}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function run() public pure {
|
||||||
|
1 s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (162-163): No matching declaration found after variable lookup.
|
@ -1,13 +0,0 @@
|
|||||||
function s(uint) pure suffix returns (uint) {}
|
|
||||||
function s(string memory) pure returns (string memory) {}
|
|
||||||
|
|
||||||
contract C {
|
|
||||||
function run() public pure {
|
|
||||||
1 s; // OK
|
|
||||||
s(1); // OK
|
|
||||||
"a" s; // not allowed
|
|
||||||
s("a"); // OK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ----
|
|
||||||
// TypeError 9322: (208-209): No matching declaration found after argument-dependent lookup.
|
|
@ -6,14 +6,10 @@ function f(string memory) pure suffix returns (string memory) {}
|
|||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
function run() public pure {
|
function run() public pure {
|
||||||
1 s;
|
|
||||||
s(1);
|
s(1);
|
||||||
//"a" s; // not allowed
|
|
||||||
s("a");
|
s("a");
|
||||||
|
|
||||||
//1 f; // not allowed
|
|
||||||
f(1);
|
f(1);
|
||||||
"a" f;
|
|
||||||
f("a");
|
f("a");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
int32 a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 uSuffix; // 2**256
|
int32 a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 uSuffix; // 2**256
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9322: (229-236): No matching declaration found after argument-dependent lookup.
|
// TypeError 2144: (229-236): No matching declaration found after variable lookup.
|
||||||
|
@ -1,19 +1,8 @@
|
|||||||
function uSuffix(uint8, uint) pure suffix returns (uint) {}
|
function uSuffix(uint8, uint) pure suffix returns (uint) {}
|
||||||
function uSuffix(uint16, uint) pure suffix returns (int) {}
|
function uSuffix(uint16, uint) pure suffix returns (int) {}
|
||||||
|
|
||||||
function iSuffix(int8, uint) pure suffix returns (uint) {}
|
|
||||||
function iSuffix(int16, uint) pure suffix returns (int) {}
|
|
||||||
|
|
||||||
function iuSuffix(uint8, uint) pure suffix returns (int) {}
|
|
||||||
function iuSuffix(int8, uint) pure suffix returns (uint) {}
|
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
int a = 1.024 uSuffix;
|
int a = 1.024 uSuffix;
|
||||||
int b = 1.024 iSuffix;
|
|
||||||
|
|
||||||
int c = -1.024 uSuffix;
|
|
||||||
int d = -1.024 iSuffix;
|
|
||||||
|
|
||||||
int e = 2.55 iuSuffix;
|
|
||||||
int f = -2.55 iuSuffix;
|
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (152-159): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
uint a = 1.27 iuSuffix;
|
uint a = 1.27 iuSuffix;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (151-159): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (151-159): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
uint a = 1.27 uSuffix;
|
uint a = 1.27 uSuffix;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (151-158): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (151-158): No matching declaration found after variable lookup.
|
||||||
|
@ -1,31 +1,14 @@
|
|||||||
==== Source: A.sol ====
|
==== Source: A.sol ====
|
||||||
function s(uint, uint) pure suffix returns (uint) {}
|
function s(uint, uint) pure suffix returns (uint) {}
|
||||||
|
|
||||||
function f(uint, uint) pure returns (uint) {}
|
|
||||||
|
|
||||||
==== Source: B.sol ====
|
==== Source: B.sol ====
|
||||||
import "A.sol";
|
import {s} from "A.sol";
|
||||||
|
|
||||||
function s(string memory) pure returns (string memory) {}
|
function s(string memory) pure returns (string memory) {}
|
||||||
|
|
||||||
function f(string memory) pure suffix returns (string memory) {}
|
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
function run() public pure {
|
function run() public pure {
|
||||||
1024 s;
|
1024 s;
|
||||||
"a" f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
==== Source: C.sol ====
|
|
||||||
import {s, f} from "A.sol";
|
|
||||||
|
|
||||||
function s(string memory) pure returns (string memory) {}
|
|
||||||
|
|
||||||
function f(string memory) pure suffix returns (string memory) {}
|
|
||||||
|
|
||||||
contract D {
|
|
||||||
function run() public pure {
|
|
||||||
1024 s;
|
|
||||||
"a" f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (B.sol:144-145): No matching declaration found after variable lookup.
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
function suffix256(uint) pure suffix returns (bool) {}
|
|
||||||
function suffix256(uint, uint) pure suffix returns (address) {}
|
|
||||||
|
|
||||||
function suffix8(uint) pure suffix returns (bool) {}
|
|
||||||
function suffix8(uint8, uint) pure suffix returns (address) {}
|
|
||||||
|
|
||||||
contract C {
|
|
||||||
// Not ambiguous: no way to convert 1.1 into uint.
|
|
||||||
address a = 1.1 suffix256;
|
|
||||||
|
|
||||||
// Not ambiguous: 1024 won't fit into uint8.
|
|
||||||
bool b = 1024 suffix8;
|
|
||||||
}
|
|
@ -7,4 +7,4 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (176-182): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (176-182): No matching declaration found after variable lookup.
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
function suffix256(uint) pure suffix returns (bool) {}
|
||||||
|
function suffix256(uint, uint) pure suffix returns (address) {}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
address a = 1.1 suffix256;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (153-162): No matching declaration found after variable lookup.
|
@ -0,0 +1,8 @@
|
|||||||
|
function suffix8(uint) pure suffix returns (bool) {}
|
||||||
|
function suffix8(uint8, uint) pure suffix returns (address) {}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
bool b = 1024 suffix8;
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (148-155): No matching declaration found after variable lookup.
|
@ -1,19 +1,8 @@
|
|||||||
function uSuffix(uint8) pure suffix returns (uint) {}
|
function uSuffix(uint8) pure suffix returns (uint) {}
|
||||||
function uSuffix(uint16) pure suffix returns (int) {}
|
function uSuffix(uint16) pure suffix returns (int) {}
|
||||||
|
|
||||||
function iSuffix(int8) pure suffix returns (uint) {}
|
|
||||||
function iSuffix(int16) pure suffix returns (int) {}
|
|
||||||
|
|
||||||
function iuSuffix(uint8) pure suffix returns (int) {}
|
|
||||||
function iuSuffix(int8) pure suffix returns (uint) {}
|
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
int a = 1024 uSuffix;
|
int a = 1024 uSuffix;
|
||||||
int b = 1024 iSuffix;
|
|
||||||
|
|
||||||
int c = -1024 uSuffix;
|
|
||||||
int d = -1024 iSuffix;
|
|
||||||
|
|
||||||
int e = 255 iuSuffix;
|
|
||||||
int f = -255 iuSuffix;
|
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (139-146): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
int a = 127 iuSuffix;
|
int a = 127 iuSuffix;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (137-145): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (137-145): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
int a = 127 uSuffix;
|
int a = 127 uSuffix;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (137-144): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (137-144): No matching declaration found after variable lookup.
|
||||||
|
@ -9,7 +9,6 @@ import "A.sol" as A;
|
|||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
int a = 1 A.suffix;
|
int a = 1 A.suffix;
|
||||||
bool b = true A.suffix;
|
|
||||||
address c = 0x1234567890123456789012345678901234567890 A.suffix;
|
|
||||||
string d = "a" A.suffix;
|
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 6675: (B.sol:49-57): Member "suffix" not unique after argument-dependent lookup in module "A.sol".
|
||||||
|
@ -4,3 +4,5 @@ function suffix(bytes memory) pure suffix returns (bytes memory) {}
|
|||||||
contract C {
|
contract C {
|
||||||
bytes a = hex"abcd" suffix;
|
bytes a = hex"abcd" suffix;
|
||||||
}
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 2144: (176-182): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
uint a = "abcd" suffix;
|
uint a = "abcd" suffix;
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 4487: (155-161): No unique declaration found after argument-dependent lookup.
|
// TypeError 2144: (155-161): No matching declaration found after variable lookup.
|
||||||
|
@ -11,4 +11,4 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9582: (218-226): Member "suffix" not found or not visible after argument-dependent lookup in uint8.
|
// TypeError 6675: (218-226): Member "suffix" not unique after argument-dependent lookup in uint8.
|
||||||
|
@ -7,4 +7,4 @@ abstract contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9322: (194-200): No matching declaration found after argument-dependent lookup.
|
// TypeError 2144: (194-200): No matching declaration found after variable lookup.
|
||||||
|
@ -5,4 +5,4 @@ contract C {
|
|||||||
function suffix(address) public pure returns (uint) {}
|
function suffix(address) public pure returns (uint) {}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9322: (31-37): No matching declaration found after argument-dependent lookup.
|
// TypeError 2144: (31-37): No matching declaration found after variable lookup.
|
||||||
|
@ -4,4 +4,4 @@ contract C {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9322: (54-60): No matching declaration found after argument-dependent lookup.
|
// TypeError 2144: (54-60): No matching declaration found after variable lookup.
|
||||||
|
Loading…
Reference in New Issue
Block a user