| 40 | using namespace solidity::frontend::experimental; |
| 41 | |
| 42 | std::vector<TypeEnvironment::UnificationFailure> TypeEnvironment::unify(Type _a, Type _b) |
| 43 | { |
| 44 | std::vector<UnificationFailure> failures; |
| 45 | auto unificationFailure = [&]() { |
| 46 | failures.emplace_back(UnificationFailure{TypeMismatch{_a, _b}}); |
| 47 | }; |
| 48 | _a = resolve(_a); |
| 49 | _b = resolve(_b); |
| 50 | std::visit(util::GenericVisitor{ |
| 51 | [&](TypeVariable _left, TypeVariable _right) { |
| 52 | if (_left.index() == _right.index()) |
| 53 | solAssert(_left.sort() == _right.sort()); |
| 54 | else if (isFixedTypeVar(_left) && isFixedTypeVar(_right)) |
| 55 | unificationFailure(); |
| 56 | else if (isFixedTypeVar(_left)) |
| 57 | failures += instantiate(_right, _left); |
| 58 | else if (isFixedTypeVar(_right)) |
| 59 | failures += instantiate(_left, _right); |
| 60 | else if (_left.sort() <= _right.sort()) |
| 61 | failures += instantiate(_left, _right); |
| 62 | else if (_right.sort() <= _left.sort()) |
| 63 | failures += instantiate(_right, _left); |
| 64 | else |
| 65 | { |
| 66 | Type newVar = m_typeSystem.freshVariable(_left.sort() + _right.sort()); |
| 67 | failures += instantiate(_left, newVar); |
| 68 | failures += instantiate(_right, newVar); |
| 69 | } |
| 70 | }, |
| 71 | [&](TypeVariable _var, auto) { |
| 72 | failures += instantiate(_var, _b); |
| 73 | }, |
| 74 | [&](auto, TypeVariable _var) { |
| 75 | failures += instantiate(_var, _a); |
| 76 | }, |
| 77 | [&](TypeConstant _left, TypeConstant _right) { |
| 78 | if (_left.constructor != _right.constructor) |
| 79 | return unificationFailure(); |
| 80 | if (_left.arguments.size() != _right.arguments.size()) |
| 81 | return unificationFailure(); |
| 82 | for (auto&& [left, right]: ranges::zip_view(_left.arguments, _right.arguments)) |
| 83 | failures += unify(left, right); |
| 84 | }, |
| 85 | [&](auto, auto) { |
| 86 | unificationFailure(); |
| 87 | } |
| 88 | }, _a, _b); |
| 89 | return failures; |
| 90 | } |
| 91 | |
| 92 | bool TypeEnvironment::typeEquals(Type _lhs, Type _rhs) const |
| 93 | { |
no test coverage detected