diff --git a/libsolidity/analysis/experimental/TypeInference.cpp b/libsolidity/analysis/experimental/TypeInference.cpp index 1e78b5401..14a1b87b9 100644 --- a/libsolidity/analysis/experimental/TypeInference.cpp +++ b/libsolidity/analysis/experimental/TypeInference.cpp @@ -272,6 +272,12 @@ bool TypeInference::visit(Identifier const& _identifier) auto const* referencedDeclaration = _identifier.annotation().referencedDeclaration; solAssert(referencedDeclaration); + if ( + !dynamic_cast(referencedDeclaration) && + !dynamic_cast(referencedDeclaration) + ) + m_errorReporter.fatalTypeError(0000_error, referencedDeclaration->location(), "Attempt to type ídentifier referring to unexpected node."); + auto& declarationAnnotation = annotation(*referencedDeclaration); if (!declarationAnnotation.type) referencedDeclaration->accept(*this); @@ -290,6 +296,11 @@ bool TypeInference::visit(IdentifierPath const& _identifier) auto const* referencedDeclaration = _identifier.annotation().referencedDeclaration; solAssert(referencedDeclaration); + if ( + !dynamic_cast(referencedDeclaration) && + !dynamic_cast(referencedDeclaration) + ) + m_errorReporter.fatalTypeError(0000_error, referencedDeclaration->location(), "Attempt to type ídentifier referring to unexpected node."); auto& declarationAnnotation = annotation(*referencedDeclaration); if (!declarationAnnotation.type) diff --git a/libsolidity/ast/experimental/TypeSystem.cpp b/libsolidity/ast/experimental/TypeSystem.cpp index d911b03f8..47f98783a 100644 --- a/libsolidity/ast/experimental/TypeSystem.cpp +++ b/libsolidity/ast/experimental/TypeSystem.cpp @@ -176,22 +176,31 @@ void TypeSystem::validate(TypeVariable _variable) const experimental::Type TypeSystem::fresh(Type _type, bool _generalize) { - return std::visit(util::GenericVisitor{ - [&](TypeExpression const& _type) -> Type { - return TypeExpression{ - _type.constructor, - _type.arguments | ranges::view::transform([&](Type _argType) { - return fresh(_argType, _generalize); - }) | ranges::to> - }; - }, - [&](TypeVariable const& _var) { - if (_generalize || _var.generic()) - return freshTypeVariable(true); - else - return _type; - }, - }, resolve(_type)); + std::unordered_map mapping; + auto freshImpl = [&](Type _type, bool _generalize, auto _recurse) -> Type { + return std::visit(util::GenericVisitor{ + [&](TypeExpression const& _type) -> Type { + return TypeExpression{ + _type.constructor, + _type.arguments | ranges::view::transform([&](Type _argType) { + return _recurse(_argType, _generalize, _recurse); + }) | ranges::to> + }; + }, + [&](TypeVariable const& _var) -> Type { + validate(_var); + if (_generalize || _var.generic()) + { + if (mapping.count(_var.index())) + return mapping[_var.index()]; + return mapping[_var.index()] = freshTypeVariable(true); + } + else + return _type; + }, + }, resolve(_type)); + }; + return freshImpl(_type, _generalize, freshImpl); } experimental::Type TypeSystemHelpers::tupleType(vector _elements) const diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index b4d9f0f17..3aba46305 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -622,7 +622,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari m_scanner->currentToken() == (m_experimentalSolidityEnabledInCurrentSourceUnit ? Token::RightArrow : Token::Returns) ) { - bool const permitEmptyParameterList = false; + bool const permitEmptyParameterList = m_experimentalSolidityEnabledInCurrentSourceUnit; advance(); result.returnParameters = parseParameterList(options, permitEmptyParameterList); }