Simplify address overloading

This commit is contained in:
Alex Beregszaszi 2017-09-25 12:58:32 +01:00
parent 7cb4d714c7
commit aa6de49457
2 changed files with 39 additions and 30 deletions

View File

@ -1720,34 +1720,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
);
}
else if (possibleMembers.size() > 1)
{
// Remove builtins (i.e. not having a declaration) first
for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
if (
(
// Overloaded functions without declaration (e.g. transfer(), send(), call(), etc.)
it->type->category() == Type::Category::Function &&
!dynamic_cast<FunctionType const&>(*it->type).hasDeclaration()
)
||
(
// Overloaded members (e.g. balance)
it->type->category() == Type::Category::Integer &&
memberName == "balance"
)
)
it = possibleMembers.erase(it);
else
++it;
if (possibleMembers.size() > 1)
m_errorReporter.fatalTypeError(
_memberAccess.location(),
"Member \"" + memberName + "\" not unique "
"after argument-dependent lookup in " + exprType->toString() +
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : "")
);
}
m_errorReporter.fatalTypeError(
_memberAccess.location(),
"Member \"" + memberName + "\" not unique "
"after argument-dependent lookup in " + exprType->toString() +
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : "")
);
auto& annotation = _memberAccess.annotation();
annotation.referencedDeclaration = possibleMembers.front().declaration;

View File

@ -1618,8 +1618,7 @@ string ContractType::canonicalName() const
MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const*) const
{
// All address members and all interface functions
MemberList::MemberMap members(IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr));
MemberList::MemberMap members;
if (m_super)
{
// add the most derived of all functions which are visible in derived contracts
@ -1661,6 +1660,38 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const*) con
&it.second->declaration()
));
}
// Add overloads from address only if there is no conflict
MemberList::MemberMap addressMembers = IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr);
for (auto const& addressMember: addressMembers)
{
bool clash = false;
for (auto const& member: members)
{
if (
member.name == addressMember.name &&
(
// Members with different types are not allowed
member.type->category() != addressMember.type->category() ||
// Members must overload functions without clash
(
member.type->category() == Type::Category::Function &&
dynamic_cast<FunctionType const&>(*member.type).hasEqualArgumentTypes(dynamic_cast<FunctionType const&>(*addressMember.type))
)
)
)
{
clash = true;
break;
}
}
if (!clash)
members.push_back(MemberList::Member(
addressMember.name,
addressMember.type,
addressMember.declaration
));
}
return members;
}