aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CODING_STYLE.md345
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp27
-rwxr-xr-xtest/externalTests.sh7
-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
9 files changed, 214 insertions, 215 deletions
diff --git a/CODING_STYLE.md b/CODING_STYLE.md
index 2cc9ac70..3244466b 100644
--- a/CODING_STYLE.md
+++ b/CODING_STYLE.md
@@ -1,35 +1,24 @@
-0. Formatting
-
-GOLDEN RULE: Follow the style of the existing code when you make changes.
-
-a. Use tabs for leading indentation
-- tab stops are every 4 characters (only relevant for line length).
-- One indentation level -> exactly one byte (i.e. a tab character) in the source file.
-b. Line widths:
-- Lines should be at most 99 characters wide to make diff views readable and reduce merge conflicts.
-- Lines of comments should be formatted according to ease of viewing, but simplicity is to be preferred over beauty.
-c. Single-statement blocks should not have braces, unless required for clarity.
-d. Never place condition bodies on same line as condition.
-e. Space between keyword and opening parenthesis, but not following opening parenthesis or before final parenthesis.
-f. No spaces for unary operators, `->` or `.`.
-g. No space before ':' but one after it, except in the ternary operator: one on both sides.
-h. Add spaces around all other operators.
-i. Braces, when used, always have their own lines and are at same indentation level as "parent" scope.
-j. If lines are broken, a list of elements enclosed with parentheses (of any kind) and separated by a
- separator (of any kind) are formatted such that there is exactly one element per line, followed by
- the separator, the opening parenthesis is on the first line, followed by a line break and the closing
- parenthesis is on a line of its own (unindented). See example below.
-
-(WRONG)
-if( a==b[ i ] ) { printf ("Hello\n"); }
-foo->bar(someLongVariableName,
- anotherLongVariableName,
- anotherLongVariableName,
- anotherLongVariableName,
- anotherLongVariableName);
-cout << "some very long string that contains completely irrelevant text that talks about this and that and contains the words \"lorem\" and \"ipsum\"" << endl;
-
-(RIGHT)
+## 0. Formatting
+
+**GOLDEN RULE**: Follow the style of the existing code when you make changes.
+
+1. Use tabs for leading indentation:
+ - tab stops are every 4 characters (only relevant for line length).
+ - one indentation level -> exactly one byte (i.e. a tab character) in the source file.
+2. Line widths:
+ - Lines should be at most 99 characters wide to make diff views readable and reduce merge conflicts.
+ - Lines of comments should be formatted according to ease of viewing, but simplicity is to be preferred over beauty.
+3. Single-statement blocks should not have braces, unless required for clarity.
+4. Never place condition bodies on same line as condition.
+5. Space between keyword and opening parenthesis, but not following opening parenthesis or before final parenthesis.
+6. No spaces for unary operators, `->` or `.`.
+7. No space before `:` but one after it, except in the ternary operator: one on both sides.
+8. Add spaces around all other operators.
+9. Braces, when used, always have their own lines and are at same indentation level as "parent" scope.
+10. If lines are broken, a list of elements enclosed with parentheses (of any kind) and separated by a separator (of any kind) are formatted such that there is exactly one element per line, followed by the separator, the opening parenthesis is on the first line, followed by a line break and the closing parenthesis is on a line of its own unindented). See example below.
+
+Yes:
+```cpp
if (a == b[i])
printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'.
foo->bar(
@@ -44,99 +33,92 @@ cout <<
"text that talks about this and that and contains the words " <<
"\"lorem\" and \"ipsum\"" <<
endl;
+```
+No:
+```cpp
+if( a==b[ i ] ) { printf ("Hello\n"); }
+foo->bar(someLongVariableName,
+ anotherLongVariableName,
+ anotherLongVariableName,
+ anotherLongVariableName,
+ anotherLongVariableName);
+cout << "some very long string that contains completely irrelevant text that talks about this and that and contains the words \"lorem\" and \"ipsum\"" << endl;
+```
+## 1. Namespaces
-1. Namespaces;
+1. No `using namespace` declarations in header files.
+2. All symbols should be declared in a namespace except for final applications.
+3. Use anonymous namespaces for helpers whose scope is a cpp file only.
+4. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
-a. No "using namespace" declarations in header files.
-b. All symbols should be declared in a namespace except for final applications.
-c. Use anonymous namespaces for helpers whose scope is a cpp file only.
-d. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
+Yes:
+```cpp
+#include <cassert>
+std::tuple<float, float> meanAndSigma(std::vector<float> const& _v);
+```
-(WRONG)
+No:
+```cpp
#include <cassert>
using namespace std;
tuple<float, float> meanAndSigma(vector<float> const& _v);
+```
-(CORRECT)
-#include <cassert>
-std::tuple<float, float> meanAndSigma(std::vector<float> const& _v);
-
-
-
-2. Preprocessor;
-
-a. File comment is always at top, and includes:
-- Copyright.
-- License (e.g. see COPYING).
-b. Never use #ifdef/#define/#endif file guards. Prefer #pragma once as first line below file comment.
-c. Prefer static const variable to value macros.
-d. Prefer inline constexpr functions to function macros.
-e. Split complex macro on multiple lines with '\'.
-
-
+## 2. Preprocessor
-3. Capitalization;
+1. File comment is always at top, and includes:
+ - Copyright
+ - License (e.g. see COPYING)
+2. Never use `#ifdef`/`#define`/`#endif` file guards. Prefer `#pragma` once as first line below file comment.
+3. Prefer static const variable to value macros.
+4. Prefer inline constexpr functions to function macros.
+5. Split complex macro on multiple lines with `\`.
-GOLDEN RULE: Preprocessor: ALL_CAPS; C++: camelCase.
+## 3. Capitalization
-a. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions.
-b. The following entities' first alpha is upper case:
-- Type names.
-- Template parameters.
-- Enum members.
-- static const variables that form an external API.
-c. All preprocessor symbols (macros, macro arguments) in full uppercase with underscore word separation.
+**GOLDEN RULE**: Preprocessor: `ALL_CAPS`; C++: `camelCase`.
+1. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions.
+2. The following entities' first alpha is upper case:
+ - Type names
+ - Template parameters
+ - Enum members
+ - static const variables that form an external API.
+3. All preprocessor symbols (macros, macro arguments) in full uppercase with underscore word separation.
All other entities' first alpha is lower case.
+## 4. Variable prefixes
+1. Leading underscore "_" to parameter names:
+ - Exception: "o_parameterName" when it is used exclusively for output. See 6(f).
+ - Exception: "io_parameterName" when it is used for both input and output. See 6(f).
+2. Leading "g_" to global (non-const) variables.
+3. Leading "s_" to static (non-const, non-global) variables.
-4. Variable prefixes:
-
-a. Leading underscore "_" to parameter names.
-- Exception: "o_parameterName" when it is used exclusively for output. See 6(f).
-- Exception: "io_parameterName" when it is used for both input and output. See 6(f).
-b. Leading "g_" to global (non-const) variables.
-c. Leading "s_" to static (non-const, non-global) variables.
-
-
-
-5. Assertions:
-
-- use `solAssert` and `solUnimplementedAssert` generously to check assumptions
- that span across different parts of the code base, for example before dereferencing
- a pointer.
-
-
-6. Declarations:
-
-a. {Typename} + {qualifiers} + {name}.
-b. Only one per line.
-c. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)).
-d. Favour declarations close to use; don't habitually declare at top of scope ala C.
-e. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move.
-f. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments.
-g. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``boost::optional`` is better suited than a raw pointer.
-h. Never use a macro where adequate non-preprocessor C++ can be written.
-i. Only use ``auto`` if the type is very long and rather irrelevant.
-j. Do not pass bools: prefer enumerations instead.
-k. Prefer enum class to straight enum.
-l. Always initialize POD variables, even if their value is overwritten later.
+## 5. Assertions
+Use `solAssert` and `solUnimplementedAssert` generously to check assumptions that span across different parts of the code base, for example before dereferencing a pointer.
-(WRONG)
-const double d = 0;
-int i, j;
-char *s;
-float meanAndSigma(std::vector<float> _v, float* _sigma, bool _approximate);
-Derived* x(dynamic_cast<Derived*>(base));
-for (map<ComplexTypeOne, ComplexTypeTwo>::iterator i = l.begin(); i != l.end(); ++l) {}
+## 6. Declarations
+1. {Typename} + {qualifiers} + {name}.
+2. Only one per line.
+3. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)).
+4. Favour declarations close to use; don't habitually declare at top of scope ala C.
+5. Pass non-trivial parameters as const reference, unless the data is to be copied into the function, then either pass by const reference or by value and use std::move.
+6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments.
+7. Use parameters of pointer type only if ``nullptr`` is a valid argument, use references otherwise. Often, ``boost::optional`` is better suited than a raw pointer.
+8. Never use a macro where adequate non-preprocessor C++ can be written.
+9. Only use ``auto`` if the type is very long and rather irrelevant.
+10. Do not pass bools: prefer enumerations instead.
+11. Prefer enum class to straight enum.
+12. Always initialize POD variables, even if their value is overwritten later.
-(CORRECT)
+Yes:
+```cpp
enum class Accuracy
{
Approximate,
@@ -154,78 +136,78 @@ char* s;
MeanAndSigma ms meanAndSigma(std::vector<float> const& _v, Accuracy _a);
Derived* x = dynamic_cast<Derived*>(base);
for (auto i = x->begin(); i != x->end(); ++i) {}
+```
+No:
+```cp
+const double d = 0;
+int i, j;
+char *s;
+float meanAndSigma(std::vector<float> _v, float* _sigma, bool _approximate);
+Derived* x(dynamic_cast<Derived*>(base));
+for (map<ComplexTypeOne, ComplexTypeTwo>::iterator i = l.begin(); i != l.end(); ++l) {}
+```
-7. Structs & classes
-
-a. Structs to be used when all members public and no virtual functions.
-- In this case, members should be named naturally and not prefixed with 'm_'
-b. Classes to be used in all other circumstances.
-
-
-
-8. Members:
-
-a. One member per line only.
-b. Private, non-static, non-const fields prefixed with m_.
-c. Avoid public fields, except in structs.
-d. Use override, final and const as much as possible.
-e. No implementations with the class declaration, except:
-- template or force-inline method (though prefer implementation at bottom of header file).
-- one-line implementation (in which case include it in same line as declaration).
-f. For a property 'foo'
-- Member: m_foo;
-- Getter: foo() [ also: for booleans, isFoo() ];
-- Setter: setFoo();
-
-
-
-9. Naming
-
-a. Avoid unpronouncable names
-b. Names should be shortened only if they are extremely common, but shortening should be generally avoided
-c. Avoid prefixes of initials (e.g. do not use IMyInterface, CMyImplementation)
-c. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments.
-- A dictionary and thesaurus are your friends.
-- Spell correctly.
-- Think carefully about the class's purpose.
-- Imagine it as an isolated component to try to decontextualise it when considering its name.
-- Don't be trapped into naming it (purely) in terms of its implementation.
-
-
-
-10. Type-definitions
-
-a. Prefer 'using' to 'typedef'. e.g. using ints = std::vector<int>; rather than typedef std::vector<int> ints;
-b. Generally avoid shortening a standard form that already includes all important information:
-- e.g. stick to shared_ptr<X> rather than shortening to ptr<X>.
-c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently.
-- e.g. using Guard = std::lock_guard<std::mutex>; ///< Guard is used throughout the codebase since it is clear in meaning and used commonly.
-d. In general expressions should be roughly as important/semantically meaningful as the space they occupy.
-e. Avoid introducing aliases for types unless they are very complicated. Consider the number of items a brain can keep track of at the same time.
-
-
-
-11. Commenting
-
-a. Comments should be doxygen-compilable, using @notation rather than \notation.
-b. Document the interface, not the implementation.
-- Documentation should be able to remain completely unchanged, even if the method is reimplemented.
-- Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports).
-- Be careful to scrutinise documentation that extends only to intended purpose and usage.
-- Reject documentation that is simply an English transaction of the implementation.
-c. Avoid in-code comments. Instead, try to extract blocks of functionality into functions. This often already eliminates the need for an in-code comment.
-
-
-12. Include Headers
-
-Includes should go in increasing order of generality (libsolidity -> libevmasm -> libdevcore -> boost -> STL).
-The corresponding .h file should be the first include in the respective .cpp file.
-Insert empty lines between blocks of include files.
+## 7. Structs & classes
+
+1. Structs to be used when all members public and no virtual functions:
+ - In this case, members should be named naturally and not prefixed with `m_`.
+2. Classes to be used in all other circumstances.
+
+## 8. Members
+
+1. One member per line only.
+2. Private, non-static, non-const fields prefixed with `m_`.
+3. Avoid public fields, except in structs.
+4. Use override, final and const as much as possible.
+5. No implementations with the class declaration, except:
+ - template or force-inline method (though prefer implementation at bottom of header file).
+ - one-line implementation (in which case include it in same line as declaration).
+6. For a property `foo`
+ - Member: `m_foo`
+ - Getter: `foo()` [ also: for booleans, `isFoo()` ]
+ - Setter: `setFoo()`
+
+## 9. Naming
+
+1. Avoid unpronouncable names.
+2. Names should be shortened only if they are extremely common, but shortening should be generally avoided
+3. Avoid prefixes of initials (e.g. do not use `IMyInterface`, `CMyImplementation`)
+4. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments:
+ - A dictionary and thesaurus are your friends;
+ - Spell correctly;
+ - Think carefully about the class's purpose;
+ - Imagine it as an isolated component to try to decontextualise it when considering its name;
+ - Don't be trapped into naming it (purely) in terms of its implementation.
+
+## 10. Type definitions
+
+1. Prefer `using` to `typedef`. e.g. `using ints = std::vector<int>;` rather than typedef `std::vector<int> ints;`
+2. Generally avoid shortening a standard form that already includes all important information:
+ - e.g. stick to `shared_ptr<X>` rather than shortening to `ptr<X>`.
+3. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently:
+ - e.g. `using Guard = std::lock_guard<std::mutex>;` ///< Guard is used throughout the codebase since it is clear in meaning and used commonly.
+4. In general expressions should be roughly as important/semantically meaningful as the space they occupy.
+5. Avoid introducing aliases for types unless they are very complicated. Consider the number of items a brain can keep track of at the same time.
+
+## 11. Commenting
+
+1. Comments should be doxygen-compilable, using @notation rather than \notation.
+2. Document the interface, not the implementation:
+ - Documentation should be able to remain completely unchanged, even if the method is reimplemented;
+ - Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports);
+ - Be careful to scrutinise documentation that extends only to intended purpose and usage;
+ - Reject documentation that is simply an English transaction of the implementation.
+3. Avoid in-code comments. Instead, try to extract blocks of functionality into functions. This often already eliminates the need for an in-code comment.
+
+## 12. Include Headers
+
+1. Includes should go in increasing order of generality (`libsolidity` -> `libevmasm` -> `libdevcore` -> `boost` -> `STL`).
+2. The corresponding `.h` file should be the first include in the respective `.cpp` file.
+3. Insert empty lines between blocks of include files.
Example:
-
-```
+```cpp
#include <libsolidity/codegen/ExpressionCompiler.h>
#include <libsolidity/ast/AST.h>
@@ -245,18 +227,17 @@ Example:
#include <numeric>
```
-See http://stackoverflow.com/questions/614302/c-header-order/614333#614333 for the reason: this makes it easier to find missing includes in header files.
-
+See [this issue](http://stackoverflow.com/questions/614302/c-header-order/614333#614333 "C header order") for the reason: this makes it easier to find missing includes in header files.
-13. Recommended reading
+## 13. Recommended reading
-Herb Sutter and Bjarne Stroustrup
-- "C++ Core Guidelines" (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
+- Herb Sutter and Bjarne Stroustrup:
+ - [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
-Herb Sutter and Andrei Alexandrescu
-- "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices"
+- Herb Sutter and Andrei Alexandrescu:
+ - "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices"
-Scott Meyers
-- "Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)"
-- "More Effective C++: 35 New Ways to Improve Your Programs and Designs"
-- "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14"
+- Scott Meyers:
+ - "Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)"
+ - "More Effective C++: 35 New Ways to Improve Your Programs and Designs"
+ - "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14"
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/externalTests.sh b/test/externalTests.sh
index 2a5ff7ef..cd6deb75 100755
--- a/test/externalTests.sh
+++ b/test/externalTests.sh
@@ -47,13 +47,6 @@ function test_truffle
cd "$DIR"
npm install
find . -name soljson.js -exec cp "$SOLJSON" {} \;
- if [ "$name" == "Zeppelin" ]; then
- # Fix some things that look like bugs (only seemed to fail on Node 6 and not Node 8)
- # FIXME: report upstream or to web3.js?
- sed -i -e 's/let token = await ERC827TokenMock.new();//;' test/token/ERC827/ERC827Token.js
- sed -i -e 's/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0)/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address)/' test/crowdsale/CappedCrowdsale.test.js
- sed -i -e 's/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, { from: owner })/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address, { from: owner })/' test/crowdsale/RefundableCrowdsale.test.js
- fi
if [ "$name" == "Gnosis" ]; then
# Replace fixed-version pragmas in Gnosis (part of Consensys best practice)
find contracts test -name '*.sol' -type f -print0 | xargs -0 sed -i -e 's/pragma solidity 0/pragma solidity ^0/'
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.