mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
tmp
This commit is contained in:
parent
156d5c7cb7
commit
ea9dfca1ae
@ -121,22 +121,18 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)
|
||||
|
||||
Type typeVar = m_typeSystem.freshTypeVariable({});
|
||||
|
||||
auto& typeMembers = annotation().members[typeConstructor(&_typeClassDefinition)];
|
||||
|
||||
for (auto subNode: _typeClassDefinition.subNodes())
|
||||
{
|
||||
subNode->accept(*this);
|
||||
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());
|
||||
solAssert(functionDefinition);
|
||||
auto functionType = m_env->fresh(getType(*functionDefinition));
|
||||
functionTypes[functionDefinition->name()] = functionType;
|
||||
if (!functionTypes.emplace(functionDefinition->name(), functionType).second)
|
||||
m_errorReporter.fatalTypeError(0000_error, functionDefinition->location(), "Function in type class declared multiple times.");
|
||||
auto typeVars = TypeEnvironmentHelpers{*m_env}.typeVars(functionType);
|
||||
if(typeVars.size() != 1)
|
||||
m_errorReporter.fatalTypeError(0000_error, functionDefinition->location(), "Function in type class may only depend on the type class variable.");
|
||||
unify(typeVars.front(), typeVar, functionDefinition->location());
|
||||
|
||||
if (!typeMembers.emplace(functionDefinition->name(), TypeMember{functionType}).second)
|
||||
m_errorReporter.fatalTypeError(0000_error, functionDefinition->location(), "Function in type class declared multiple times.");
|
||||
}
|
||||
|
||||
TypeClass typeClass = std::visit(util::GenericVisitor{
|
||||
@ -146,7 +142,18 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)
|
||||
util::unreachable();
|
||||
}
|
||||
}, m_typeSystem.declareTypeClass(typeVar, std::move(functionTypes), _typeClassDefinition.name(), &_typeClassDefinition));
|
||||
annotation(_typeClassDefinition).typeClass = typeClass;
|
||||
|
||||
auto& typeMembers = annotation().members[typeConstructor(&_typeClassDefinition)];
|
||||
|
||||
for (auto subNode: _typeClassDefinition.subNodes())
|
||||
{
|
||||
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());
|
||||
solAssert(functionDefinition);
|
||||
auto functionType = m_env->typeClassFunction(typeClass, functionDefinition->name());
|
||||
solAssert(functionType);
|
||||
typeMembers[functionDefinition->name()] = TypeMember{*functionType};
|
||||
}
|
||||
|
||||
unify(getType(_typeClassDefinition.typeVariable()), m_typeSystem.freshTypeVariable({{typeClass}}), _typeClassDefinition.location());
|
||||
for (auto instantiation: m_analysis.annotation<TypeRegistration>(_typeClassDefinition).instantiations | ranges::views::values)
|
||||
@ -258,15 +265,24 @@ bool TypeInference::visit(BinaryOperation const& _binaryOperation)
|
||||
unify(*functionType, genericFunctionType, _binaryOperation.location());
|
||||
|
||||
operationAnnotation.type = m_env->resolve(std::get<1>(helper.destFunctionType(m_env->resolve(genericFunctionType))));
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (_binaryOperation.getOperator() == Token::Colon)
|
||||
{
|
||||
_binaryOperation.leftExpression().accept(*this);
|
||||
{
|
||||
ScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};
|
||||
_binaryOperation.rightExpression().accept(*this);
|
||||
}
|
||||
Type leftType = getType(_binaryOperation.leftExpression());
|
||||
unify(leftType, getType(_binaryOperation.rightExpression()), _binaryOperation.location());
|
||||
operationAnnotation.type = leftType;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorReporter.typeError(0000_error, _binaryOperation.location(), "Binary operation in term context not yet supported.");
|
||||
operationAnnotation.type = m_typeSystem.freshTypeVariable({});
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
case ExpressionContext::Type:
|
||||
if (_binaryOperation.getOperator() == Token::Colon)
|
||||
{
|
||||
@ -395,7 +411,13 @@ experimental::Type TypeInference::handleIdentifierByReferencedDeclaration(langut
|
||||
else if (dynamic_cast<TypeClassDefinition const*>(&_declaration))
|
||||
return m_env->fresh(*declarationAnnotation.type);
|
||||
else if (dynamic_cast<TypeDefinition const*>(&_declaration))
|
||||
return m_env->fresh(*declarationAnnotation.type);
|
||||
{
|
||||
// TODO: can we avoid this?
|
||||
Type type = *declarationAnnotation.type;
|
||||
if (TypeSystemHelpers{m_typeSystem}.isTypeFunctionType(type))
|
||||
type = std::get<1>(TypeSystemHelpers{m_typeSystem}.destTypeFunctionType(type));
|
||||
return m_env->fresh(type);
|
||||
}
|
||||
else
|
||||
solAssert(false);
|
||||
break;
|
||||
@ -539,6 +561,8 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
|
||||
// visiting the type class will re-visit this instantiation
|
||||
typeClass->accept(*this);
|
||||
// TODO: more error handling? Should be covered by the visit above.
|
||||
if (!annotation(*typeClass).typeClass)
|
||||
m_errorReporter.typeError(0000_error, _typeClassInstantiation.typeClass().location(), "Expected type class.");
|
||||
return annotation(*typeClass).typeClass;
|
||||
}
|
||||
else
|
||||
@ -719,7 +743,7 @@ void TypeInference::endVisit(FunctionCall const& _functionCall)
|
||||
case ExpressionContext::Type:
|
||||
{
|
||||
Type argTuple = helper.tupleType(argTypes);
|
||||
Type genericFunctionType = helper.typeFunctionType(argTuple, m_typeSystem.freshKindVariable({}));
|
||||
Type genericFunctionType = helper.typeFunctionType(argTuple, m_typeSystem.freshTypeVariable({}));
|
||||
unify(functionType, genericFunctionType, _functionCall.location());
|
||||
functionCallAnnotation.type = m_env->resolve(std::get<1>(helper.destTypeFunctionType(m_env->resolve(genericFunctionType))));
|
||||
break;
|
||||
|
@ -148,9 +148,9 @@ TypeSystem::TypeSystem()
|
||||
m_primitiveTypeConstructors.emplace(type, declareTypeConstructor(name, name, arity, nullptr));
|
||||
|
||||
TypeClass classType = primitiveClass(PrimitiveClass::Type);
|
||||
TypeClass classKind = primitiveClass(PrimitiveClass::Kind);
|
||||
//TypeClass classKind = primitiveClass(PrimitiveClass::Kind);
|
||||
Sort typeSort{{classType}};
|
||||
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::TypeFunction).m_index).arities = {Arity{vector<Sort>{{typeSort},{typeSort}}, classKind}};
|
||||
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::TypeFunction).m_index).arities = {Arity{vector<Sort>{{typeSort},{typeSort}}, classType}};
|
||||
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Function).m_index).arities = {Arity{vector<Sort>{{typeSort, typeSort}}, classType}};
|
||||
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Function).m_index).arities = {Arity{vector<Sort>{{typeSort, typeSort}}, classType}};
|
||||
}
|
||||
@ -269,7 +269,7 @@ TypeConstructor TypeSystem::declareTypeConstructor(string _name, string _canonic
|
||||
std::generate_n(std::back_inserter(argumentSorts), _arguments, [&](){ return Sort{{primitiveClass(PrimitiveClass::Type)}}; });
|
||||
std::vector<Type> argumentTypes;
|
||||
std::generate_n(std::back_inserter(argumentTypes), _arguments, [&](){ return freshVariable({}); });
|
||||
auto error = instantiateClass(type(constructor, argumentTypes), Arity{argumentSorts, primitiveClass(PrimitiveClass::Kind)}, {});
|
||||
auto error = instantiateClass(type(constructor, argumentTypes), Arity{argumentSorts, primitiveClass(PrimitiveClass::Type)}, {});
|
||||
solAssert(!error, *error);
|
||||
}
|
||||
else
|
||||
|
@ -304,12 +304,13 @@ std::string TypeEnvironmentHelpers::typeToString(Type const& _type) const
|
||||
solAssert(_args.size() == 0);
|
||||
return "()";
|
||||
}},
|
||||
{env.typeSystem().constructor(PrimitiveType::Pair), [&](auto const&) {
|
||||
auto tupleTypes = TypeSystemHelpers{env.typeSystem()}.destTupleType(_type);
|
||||
{env.typeSystem().constructor(PrimitiveType::Pair), [&](auto const& _arguments) {
|
||||
auto tupleTypes = TypeSystemHelpers{env.typeSystem()}.destTupleType(_arguments.back());
|
||||
string result = "(";
|
||||
for (auto type: tupleTypes | ranges::views::drop_last(1))
|
||||
result += typeToString(type) + ", ";
|
||||
result += typeToString(tupleTypes.back()) + ")";
|
||||
result += typeToString(_arguments.front());
|
||||
for (auto type: tupleTypes)
|
||||
result += ", " + typeToString(type);
|
||||
result += ")";
|
||||
return result;
|
||||
}},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user