From ed0d2d89f376ad72d43b5cbe52729998688d5ea5 Mon Sep 17 00:00:00 2001 From: Matthias Kurtenacker Date: Wed, 8 Jan 2025 15:59:40 +0100 Subject: [PATCH] WIP: do not extend the type system. Revert adding DefaultParamType. Instead, use CallExpr::infer. This only works if the parameter and argument lists materialize as tuples. Single parameters are not encapsulated like that and need special treatment later down the line. --- include/artic/types.h | 29 -------------------------- src/check.cpp | 47 ++++++++++++++++++++++++++----------------- src/emit.cpp | 10 --------- src/print.cpp | 5 ----- src/summoner.cpp | 3 +-- src/types.cpp | 45 ----------------------------------------- 6 files changed, 30 insertions(+), 109 deletions(-) diff --git a/include/artic/types.h b/include/artic/types.h index 071c9cb..3a6955a 100644 --- a/include/artic/types.h +++ b/include/artic/types.h @@ -301,34 +301,6 @@ struct ImplicitParamType : public Type { friend class TypeTable; }; -struct DefaultParamType : public Type { - const Type* underlying; - const ast::Expr* expr; - - void print(Printer&) const override; - bool equals(const Type*) const override; - size_t hash() const override; - bool contains(const Type*) const override; - - const Type* replace(const ReplaceMap&) const override; - - const thorin::Type* convert(Emitter&) const override; - std::string stringify(Emitter&) const override; - - size_t order(std::unordered_set&) const override; - void variance(TypeVarMap&, bool) const override; - void bounds(TypeVarMap&, const Type*, bool) const override; - bool is_sized(std::unordered_set&) const override; -private: - DefaultParamType(TypeTable& type_table, const Type* underlying, const ast::Expr* expr) - : Type(type_table) - , underlying(underlying) - , expr(expr) - {} - - friend class TypeTable; -}; - /// Function type (can represent continuations when the codomain is a `NoRetType`). struct FnType : public Type { const Type* dom; @@ -700,7 +672,6 @@ class TypeTable { const PtrType* ptr_type(const Type*, bool, size_t); const RefType* ref_type(const Type*, bool, size_t); const ImplicitParamType* implicit_param_type(const Type*); - const DefaultParamType* default_param_type(const Type*, const ast::Expr*); const FnType* fn_type(const Type*, const Type*); const FnType* cn_type(const Type*); const BottomType* bottom_type(); diff --git a/src/check.cpp b/src/check.cpp index f18e82a..1bbf621 100644 --- a/src/check.cpp +++ b/src/check.cpp @@ -161,7 +161,7 @@ static bool is_unit(Ptr& expr) { static bool is_tuple_type_with_implicits(const artic::Type* type) { if (auto tuple_t = type->isa(); tuple_t && !is_unit_type(tuple_t)) - return std::any_of(tuple_t->args.begin(), tuple_t->args.end(), [&](auto arg){ return arg->template isa() || arg->template isa(); }); + return std::any_of(tuple_t->args.begin(), tuple_t->args.end(), [&](auto arg){ return arg->template isa(); }); return false; } @@ -174,15 +174,6 @@ const Type* TypeChecker::coerce(Ptr& expr, const Type* expected) { expr.swap(summoned); return implicit->underlying; } - } else if (auto default_type = expected->isa()) { - if (is_unit(expr)) { - Ptr summoned = make_ptr(expr->loc, Ptr()); - summoned->type = default_type->underlying; - summoned->resolved = default_type->expr; - Ptr swapexp = std::move(summoned); - expr.swap(swapexp); - return default_type->underlying; - } } else if (is_tuple_type_with_implicits(expected)) { auto loc = expr->loc; auto deconstructed = expr->isa(); @@ -207,13 +198,6 @@ const Type* TypeChecker::coerce(Ptr& expr, const Type* expected) { args.push_back(std::move(summoned)); continue; } - if (auto default_type = tuple_t->args[i]->isa()) { - Ptr summoned = make_ptr(loc, Ptr()); - summoned->type = default_type->underlying; - summoned->resolved = default_type->expr; - args.push_back(std::move(summoned)); - continue; - } bad_arguments(loc, "non-implicit arguments", i, tuple_t->args.size()); } @@ -1184,6 +1168,33 @@ const artic::Type* CallExpr::infer(TypeChecker& checker) { auto [ref_type, callee_type] = remove_ref(checker.infer(*callee)); if (auto fn_type = callee_type->isa()) { checker.coerce(callee, fn_type); + + artic::ast::TupleExpr* args_tuple = arg->isa(); + + const artic::TupleType* from_tuple = fn_type->dom->isa(); + const artic::ast::PathExpr* path_expr = callee_path(callee.get()); + const artic::ast::FnDecl* fn_decl = nullptr; + const artic::ast::FnExpr* decl = nullptr; + const artic::ast::TuplePtrn* fn_params = nullptr; + + if (path_expr) { + fn_decl = path_expr->path.start_decl->isa(); + if (fn_decl) { + decl = fn_decl->fn.get(); + fn_params = decl->param->isa(); + + if (fn_params) { + for (int i = args_tuple->args.size(); i < fn_params->args.size(); i++) { + auto default_param = fn_params->args[i]->isa(); + if (default_param) { + auto default_expr = default_param->default_expr.get(); + args_tuple->args.push_back(std::unique_ptr(default_expr)); + } + } + } + } + } + checker.coerce(arg, fn_type->dom); return fn_type->codom; } else { @@ -1902,7 +1913,7 @@ const artic::Type * ImplicitParamPtrn::check(artic::TypeChecker& checker, const const artic::Type* DefaultParamPtrn::infer(artic::TypeChecker& checker) { checker.infer(*default_expr); checker.check(*underlying, default_expr->type); - return checker.type_table.default_param_type(default_expr->type, &*default_expr); + return default_expr->type; } const artic::Type *DefaultParamPtrn::check(artic::TypeChecker& checker, const artic::Type* expected) { diff --git a/src/emit.cpp b/src/emit.cpp index 5cd3eb5..38a1f0b 100644 --- a/src/emit.cpp +++ b/src/emit.cpp @@ -688,8 +688,6 @@ const thorin::Def* Emitter::down_cast(const thorin::Def* def, const Type* from, if (to->isa()) return def; - if (to->isa()) - return def; auto to_ptr_type = to->isa(); // Casting a value to a pointer to the type of the value effectively creates an allocation @@ -1906,10 +1904,6 @@ std::string ImplicitParamType::stringify(Emitter& emitter) const { return "implicit_" + underlying->stringify(emitter); } -std::string DefaultParamType::stringify(Emitter& emitter) const { - return "default_" + underlying->stringify(emitter); -} - std::string FnType::stringify(Emitter& emitter) const { return "fn_" + dom->stringify(emitter) + "_" + codom->stringify(emitter); } @@ -1918,10 +1912,6 @@ const thorin::Type* ImplicitParamType::convert(artic::Emitter& emitter) const { return underlying->convert(emitter); } -const thorin::Type* DefaultParamType::convert(artic::Emitter& emitter) const { - return underlying->convert(emitter); -} - const thorin::Type* FnType::convert(Emitter& emitter) const { if (codom->isa()) return emitter.continuation_type_with_mem(dom->convert(emitter)); diff --git a/src/print.cpp b/src/print.cpp index feba093..c248628 100644 --- a/src/print.cpp +++ b/src/print.cpp @@ -779,11 +779,6 @@ void ImplicitParamType::print(artic::Printer& p) const { underlying->print(p); } -void DefaultParamType::print(artic::Printer& p) const { - p << "default "; - underlying->print(p); -} - void FnType::print(Printer& p) const { p << log::keyword_style("fn") << ' '; if (!dom->isa()) p << '('; diff --git a/src/summoner.cpp b/src/summoner.cpp index 5332aac..26f61eb 100644 --- a/src/summoner.cpp +++ b/src/summoner.cpp @@ -60,8 +60,7 @@ void TypedExpr::resolve_summons(artic::Summoner& summoner) { } void SummonExpr::resolve_summons(artic::Summoner& summoner) { - if (!resolved) - resolved = summoner.resolve(type, loc); + resolved = summoner.resolve(type, loc); } void FieldExpr::resolve_summons(artic::Summoner& summoner) { diff --git a/src/types.cpp b/src/types.cpp index 01a8217..f7e3bf4 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -58,13 +58,6 @@ bool ImplicitParamType::equals(const artic::Type* other) const { other->as()->underlying == underlying; } -bool DefaultParamType::equals(const artic::Type* other) const { - return - other->isa() && - other->as()->underlying == underlying && - other->as()->expr == expr; -} - bool FnType::equals(const Type* other) const { return other->isa() && @@ -127,13 +120,6 @@ size_t ImplicitParamType::hash() const { .combine(underlying); } -size_t DefaultParamType::hash() const { - return fnv::Hash() - .combine(typeid(*this).hash_code()) - .combine(underlying) - .combine(expr); -} - size_t FnType::hash() const { return fnv::Hash() .combine(typeid(*this).hash_code()) @@ -178,10 +164,6 @@ bool ImplicitParamType::contains(const artic::Type* type) const { return type == this || underlying->contains(type); } -bool DefaultParamType::contains(const artic::Type* type) const { - return type == this || underlying->contains(type); -} - bool FnType::contains(const Type* type) const { return type == this || dom->contains(type) || codom->contains(type); } @@ -224,10 +206,6 @@ const Type* ImplicitParamType::replace(const artic::ReplaceMap& map) const { return type_table.implicit_param_type(underlying->replace(map)); } -const Type* DefaultParamType::replace(const artic::ReplaceMap& map) const { - return type_table.default_param_type(underlying->replace(map), expr); -} - const Type* FnType::replace(const std::unordered_map& map) const { return type_table.fn_type(dom->replace(map), codom->replace(map)); } @@ -255,10 +233,6 @@ size_t ImplicitParamType::order(std::unordered_set& seen) const { return underlying->order(seen); } -size_t DefaultParamType::order(std::unordered_set& seen) const { - return underlying->order(seen); -} - size_t FnType::order(std::unordered_set& seen) const { return 1 + std::max(dom->order(seen), codom->order(seen)); } @@ -320,10 +294,6 @@ void ImplicitParamType::variance(TypeVarMap& vars, bool dir return underlying->variance(vars, dir); } -void DefaultParamType::variance(TypeVarMap& vars, bool dir) const { - return underlying->variance(vars, dir); -} - void TypeVar::variance(std::unordered_map& vars, bool dir) const { if (auto it = vars.find(this); it != vars.end()) { bool var_dir = it->second == TypeVariance::Covariant ? true : false; @@ -363,10 +333,6 @@ void ImplicitParamType::bounds(TypeVarMap& bounds, const arti underlying->bounds(bounds, type, dir); } -void DefaultParamType::bounds(TypeVarMap& bounds, const artic::Type* type, bool dir) const { - underlying->bounds(bounds, type, dir); -} - void FnType::bounds(std::unordered_map& bounds, const Type* type, bool dir) const { if (auto fn_type = type->isa()) { dom->bounds(bounds, fn_type->dom, !dir); @@ -404,10 +370,6 @@ bool ImplicitParamType::is_sized(std::unordered_set& seen) const { return underlying->is_sized(seen); } -bool DefaultParamType::is_sized(std::unordered_set& seen) const { - return underlying->is_sized(seen); -} - bool FnType::is_sized(std::unordered_set& seen) const { return dom->is_sized(seen) && codom->is_sized(seen); } @@ -529,9 +491,6 @@ bool Type::subtype(const Type* other) const { if (auto implicit = other->isa()) return this->subtype(implicit->underlying) || is_unit_type(this); - if (auto default_type = other->isa()) - return this->subtype(default_type->underlying) || is_unit_type(this); - auto other_ptr_type = other->isa(); // Take the address of values automatically: @@ -719,10 +678,6 @@ const ImplicitParamType* TypeTable::implicit_param_type(const Type* underlying) return insert(underlying); } -const DefaultParamType* TypeTable::default_param_type(const Type* underlying, const ast::Expr* expr) { - return insert(underlying, expr); -} - const FnType* TypeTable::fn_type(const Type* dom, const Type* codom) { return insert(dom, codom); }