aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp27
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp15
-rw-r--r--test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol7
-rw-r--r--test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol9
-rw-r--r--test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mappings.sol10
-rw-r--r--test/libsolidity/syntaxTests/memberLookup/push_on_memory_types.sol8
7 files changed, 51 insertions, 26 deletions
diff --git a/Changelog.md b/Changelog.md
index 8812bace..3922c641 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -6,6 +6,7 @@ Features:
* Syntax Checker: Warn about functions named "constructor".
Bugfixes:
+ * Type Checker: Improve error message for failed function overload resolution.
* Type Checker: Do not complain about new-style constructor and fallback function to have the same name.
* Type Checker: Detect multiple constructor declarations in the new syntax and old syntax.
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 87d69d97..72d29762 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1904,7 +1904,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
// Retrieve the types of the arguments if this is used to call a function.
auto const& argumentTypes = _memberAccess.annotation().argumentTypes;
MemberList::MemberMap possibleMembers = exprType->members(m_scope).membersByName(memberName);
- if (possibleMembers.size() > 1 && argumentTypes)
+ size_t const initialMemberCount = possibleMembers.size();
+ if (initialMemberCount > 1 && argumentTypes)
{
// do overload resolution
for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
@@ -1918,17 +1919,21 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
}
if (possibleMembers.size() == 0)
{
- auto storageType = ReferenceType::copyForLocationIfReference(
- DataLocation::Storage,
- exprType
- );
- if (!storageType->members(m_scope).membersByName(memberName).empty())
- m_errorReporter.fatalTypeError(
- _memberAccess.location(),
- "Member \"" + memberName + "\" is not available in " +
- exprType->toString() +
- " outside of storage."
+ if (initialMemberCount == 0)
+ {
+ // Try to see if the member was removed because it is only available for storage types.
+ auto storageType = ReferenceType::copyForLocationIfReference(
+ DataLocation::Storage,
+ exprType
);
+ if (!storageType->members(m_scope).membersByName(memberName).empty())
+ m_errorReporter.fatalTypeError(
+ _memberAccess.location(),
+ "Member \"" + memberName + "\" is not available in " +
+ exprType->toString() +
+ " outside of storage."
+ );
+ }
m_errorReporter.fatalTypeError(
_memberAccess.location(),
"Member \"" + memberName + "\" not found or not visible "
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 7c0e8643..97cf0410 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2993,21 +2993,6 @@ BOOST_AUTO_TEST_CASE(literal_strings)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
-{
- char const* text = R"(
- contract Test {
- struct S { uint8 a; mapping(uint => uint) b; uint8 c; }
- S s;
- function f() public {
- S memory x;
- x.b[1];
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Member \"b\" is not available in struct Test.S memory outside of storage.");
-}
-
BOOST_AUTO_TEST_CASE(string_bytes_conversion)
{
char const* text = R"(
diff --git a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol
new file mode 100644
index 00000000..c23992e9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f(uint, uint) {}
+ function f(uint) {}
+ function g() { f(1, 2, 3); }
+}
+// ----
+// TypeError: (80-81): No matching declaration found after argument-dependent lookup.
diff --git a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol
new file mode 100644
index 00000000..310c4a10
--- /dev/null
+++ b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol
@@ -0,0 +1,9 @@
+library L {
+ function f(uint, uint) {}
+ function f(uint) {}
+}
+contract C {
+ function g() { L.f(1, 2, 3); }
+}
+// ----
+// TypeError: (94-97): Member "f" not found or not visible after argument-dependent lookup in type(library L)
diff --git a/test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mappings.sol b/test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mappings.sol
new file mode 100644
index 00000000..bdafc754
--- /dev/null
+++ b/test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mappings.sol
@@ -0,0 +1,10 @@
+contract Test {
+ struct S { uint8 a; mapping(uint => uint) b; uint8 c; }
+ S s;
+ function f() public {
+ S memory x;
+ x.b[1];
+ }
+}
+// ----
+// TypeError: (118-121): Member "b" is not available in struct Test.S memory outside of storage.
diff --git a/test/libsolidity/syntaxTests/memberLookup/push_on_memory_types.sol b/test/libsolidity/syntaxTests/memberLookup/push_on_memory_types.sol
new file mode 100644
index 00000000..310c073f
--- /dev/null
+++ b/test/libsolidity/syntaxTests/memberLookup/push_on_memory_types.sol
@@ -0,0 +1,8 @@
+contract Test {
+ function f() public pure {
+ uint[] memory x;
+ x.push(1);
+ }
+}
+// ----
+// TypeError: (77-83): Member "push" is not available in uint256[] memory outside of storage.