Skip to content

Assorted bugfixes for new analysis #14658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions libsolidity/experimental/analysis/DebugWarner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,12 @@ bool DebugWarner::analyze(ASTNode const& _astRoot)

bool DebugWarner::visitNode(ASTNode const& _node)
{
auto const& typeInferenceAnnotation = m_analysis.annotation<TypeInference>(_node);
if (typeInferenceAnnotation.type)
{
Type type = *typeInferenceAnnotation.type;
Sort sort = m_analysis.typeSystem().env().sort(type);
std::string sortString;
if (sort.classes.size() != 1 || *sort.classes.begin() != m_analysis.typeSystem().primitiveClass(PrimitiveClass::Type))
sortString = ":" + TypeSystemHelpers{m_analysis.typeSystem()}.sortToString(m_analysis.typeSystem().env().sort(type));
std::optional<Type> const& inferredType = m_analysis.annotation<TypeInference>(_node).type;
if (inferredType.has_value())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for random style remarks: I find .has_value() on optionals horrible myself personally :-D... but it doesn't matter at all, ultimately everybody can read both, so I don't bother pushing my own preferred style through.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me it's if (inferredType) that's horrible. It does not read like a condition at all. It forces me stop and think in which way this can be interpreted as a boolean, while on seeing inferredType.has_value() I immediately know it's an optional and can move on smoothly. I'm really not sure why people don't find this jarring.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my point, though - it's purely subjective and we spend way too much time and effort in general in flipping back and forth around purely subjective taste that has no actual bearing on overall readability.

Copy link
Member

@ekpyron ekpyron Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in: I find this significantly less readable with .has_value() than without - and I don't buy that it'd be worse for you to read it without that than it is for me to read it with that - we should just generally have a bit more flexibility around stuff like this (that would already significantly reduce number of comments on PRs).

m_errorReporter.info(
4164_error,
_node.location(),
"Inferred type: " + TypeEnvironmentHelpers{m_analysis.typeSystem().env()}.typeToString(type) + sortString
"Inferred type: " + TypeEnvironmentHelpers{m_analysis.typeSystem().env()}.typeToString(*inferredType)
);
}
return true;
}
30 changes: 14 additions & 16 deletions libsolidity/experimental/ast/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ std::vector<TypeEnvironment::UnificationFailure> TypeEnvironment::unify(Type _a,
std::visit(util::GenericVisitor{
[&](TypeVariable _left, TypeVariable _right) {
if (_left.index() == _right.index())
{
if (_left.sort() != _right.sort())
unificationFailure();
}
solAssert(_left.sort() == _right.sort());
else
{
if (_left.sort() <= _right.sort())
Expand Down Expand Up @@ -154,7 +151,7 @@ TypeSystem::TypeSystem()
Sort typeSort{{classType}};
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::TypeFunction).m_index).arities = {Arity{std::vector<Sort>{{typeSort},{typeSort}}, classType}};
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Function).m_index).arities = {Arity{std::vector<Sort>{{typeSort, typeSort}}, classType}};
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Function).m_index).arities = {Arity{std::vector<Sort>{{typeSort, typeSort}}, classType}};
m_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Itself).m_index).arities = {Arity{std::vector<Sort>{{typeSort, typeSort}}, classType}};
}

experimental::Type TypeSystem::freshVariable(Sort _sort)
Expand All @@ -171,9 +168,10 @@ experimental::Type TypeSystem::freshTypeVariable(Sort _sort)

std::vector<TypeEnvironment::UnificationFailure> TypeEnvironment::instantiate(TypeVariable _variable, Type _type)
{
for (auto typeVar: TypeEnvironmentHelpers{*this}.typeVars(_type))
if (typeVar.index() == _variable.index())
return {UnificationFailure{RecursiveUnification{_variable, _type}}};
for (auto const& maybeTypeVar: TypeEnvironmentHelpers{*this}.typeVars(_type))
if (auto const* typeVar = std::get_if<TypeVariable>(&maybeTypeVar))
if (typeVar->index() == _variable.index())
return {UnificationFailure{RecursiveUnification{_variable, _type}}};
Sort typeSort = sort(_type);
if (!(_variable.sort() <= typeSort))
{
Expand All @@ -197,19 +195,19 @@ experimental::Type TypeEnvironment::resolve(Type _type) const
experimental::Type TypeEnvironment::resolveRecursive(Type _type) const
{
return std::visit(util::GenericVisitor{
[&](TypeConstant const& _type) -> Type {
[&](TypeConstant const& _typeConstant) -> Type {
return TypeConstant{
_type.constructor,
_type.arguments | ranges::views::transform([&](Type _argType) {
_typeConstant.constructor,
_typeConstant.arguments | ranges::views::transform([&](Type const& _argType) {
return resolveRecursive(_argType);
}) | ranges::to<std::vector<Type>>
};
},
[&](TypeVariable const&) -> Type {
return _type;
[](TypeVariable const& _typeVar) -> Type {
return _typeVar;
},
[&](std::monostate) -> Type {
return _type;
[](std::monostate _nothing) -> Type {
return _nothing;
}
}, resolve(_type));
}
Expand Down Expand Up @@ -306,7 +304,7 @@ experimental::Type TypeSystem::type(TypeConstructor _constructor, std::vector<Ty

experimental::Type TypeEnvironment::fresh(Type _type)
{
std::unordered_map<uint64_t, Type> mapping;
std::unordered_map<size_t, Type> mapping;
auto freshImpl = [&](Type _type, auto _recurse) -> Type {
return std::visit(util::GenericVisitor{
[&](TypeConstant const& _type) -> Type {
Expand Down