diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 9d536a3ab..6d5d5cb71 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -21,17 +21,24 @@ */ #include -#include +#include + +#include +#include +#include + +#include + +#include +#include + #include #include #include #include -#include -#include -#include -#include -#include -#include + +#include +#include using namespace std; using namespace dev; @@ -814,11 +821,25 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (!varType->canLiveOutsideStorage()) m_errorReporter.typeError(_variable.location(), "Type " + varType->toString() + " is only valid in storage."); } - else if ( - _variable.visibility() >= VariableDeclaration::Visibility::Public && - !FunctionType(_variable).interfaceFunctionType() - ) - m_errorReporter.typeError(_variable.location(), "Internal or recursive type is not allowed for public state variables."); + else if (_variable.visibility() >= VariableDeclaration::Visibility::Public) + { + FunctionType getter(_variable); + if (!_variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2)) + { + vector unsupportedTypes; + for (auto const& param: getter.parameterTypes() + getter.returnParameterTypes()) + if (!typeSupportedByOldABIEncoder(*param)) + unsupportedTypes.emplace_back(param->toString()); + if (!unsupportedTypes.empty()) + m_errorReporter.typeError(_variable.location(), + "The following types are only supported for getters in the new experimental ABI encoder: " + + joinHumanReadable(unsupportedTypes) + + ". Either remove \"public\" or use \"pragma experimental ABIEncoderV2;\" to enable the feature." + ); + } + if (!getter.interfaceFunctionType()) + m_errorReporter.typeError(_variable.location(), "Internal or recursive type is not allowed for public state variables."); + } switch (varType->category()) {