| 375 | } |
| 376 | |
| 377 | std::string TypeEnvironmentHelpers::typeToString(Type const& _type) const |
| 378 | { |
| 379 | std::map<TypeConstructor, std::function<std::string(std::vector<Type>)>> formatters{ |
| 380 | {env.typeSystem().constructor(PrimitiveType::Function), [&](auto const& _args) { |
| 381 | solAssert(_args.size() == 2); |
| 382 | return fmt::format("{} -> {}", typeToString(_args.front()), typeToString(_args.back())); |
| 383 | }}, |
| 384 | {env.typeSystem().constructor(PrimitiveType::Unit), [&](auto const& _args) { |
| 385 | solAssert(_args.size() == 0); |
| 386 | return "()"; |
| 387 | }}, |
| 388 | {env.typeSystem().constructor(PrimitiveType::Pair), [&](auto const& _arguments) { |
| 389 | auto tupleTypes = TypeSystemHelpers{env.typeSystem()}.destTupleType(_arguments.back()); |
| 390 | std::string result = "("; |
| 391 | result += typeToString(_arguments.front()); |
| 392 | for (auto type: tupleTypes) |
| 393 | result += ", " + typeToString(type); |
| 394 | result += ")"; |
| 395 | return result; |
| 396 | }}, |
| 397 | }; |
| 398 | return std::visit(util::GenericVisitor{ |
| 399 | [&](TypeConstant const& _type) { |
| 400 | if (auto* formatter = util::valueOrNullptr(formatters, _type.constructor)) |
| 401 | return (*formatter)(_type.arguments); |
| 402 | std::stringstream stream; |
| 403 | stream << env.typeSystem().constructorInfo(_type.constructor).name; |
| 404 | if (!_type.arguments.empty()) |
| 405 | { |
| 406 | stream << "("; |
| 407 | for (auto type: _type.arguments | ranges::views::drop_last(1)) |
| 408 | stream << typeToString(type) << ", "; |
| 409 | stream << typeToString(_type.arguments.back()); |
| 410 | stream << ")"; |
| 411 | } |
| 412 | return stream.str(); |
| 413 | }, |
| 414 | [&](TypeVariable const& _type) { |
| 415 | std::stringstream stream; |
| 416 | std::string varName; |
| 417 | size_t index = _type.index(); |
| 418 | varName += static_cast<char>('a' + (index%26)); |
| 419 | while (index /= 26) |
| 420 | varName += static_cast<char>('a' + (index%26)); |
| 421 | reverse(varName.begin(), varName.end()); |
| 422 | stream << (env.isFixedTypeVar(_type) ? "'" : "?") << varName; |
| 423 | switch (_type.sort().classes.size()) |
| 424 | { |
| 425 | case 0: |
| 426 | break; |
| 427 | case 1: |
| 428 | stream << ":" << env.typeSystem().typeClassName(*_type.sort().classes.begin()); |
| 429 | break; |
| 430 | default: |
| 431 | stream << ":("; |
| 432 | for (auto typeClass: _type.sort().classes | ranges::views::drop_last(1)) |
| 433 | stream << env.typeSystem().typeClassName(typeClass) << ", "; |
| 434 | stream << env.typeSystem().typeClassName(*_type.sort().classes.rbegin()); |
no test coverage detected