diff --git a/codon/parser/cache.cpp b/codon/parser/cache.cpp index e94ca102..1af811eb 100644 --- a/codon/parser/cache.cpp +++ b/codon/parser/cache.cpp @@ -111,14 +111,18 @@ ir::Func *Cache::realizeFunction(types::FuncTypePtr type, } } } + int oldAge = typeCtx->age; + typeCtx->age = 99999; auto tv = TypecheckVisitor(typeCtx); + ir::Func *f = nullptr; if (auto rtv = tv.realize(type)) { auto pr = pendingRealizations; // copy it as it might be modified for (auto &fn : pr) TranslateVisitor(codegenCtx).transform(functions[fn.first].ast->clone()); - return functions[rtv->getFunc()->ast->name].realizations[rtv->realizedName()]->ir; + f = functions[rtv->getFunc()->ast->name].realizations[rtv->realizedName()]->ir; } - return nullptr; + typeCtx->age = oldAge; + return f; } ir::types::Type *Cache::makeTuple(const std::vector &types) { diff --git a/codon/parser/visitors/typecheck/typecheck_expr.cpp b/codon/parser/visitors/typecheck/typecheck_expr.cpp index 683ac510..7625dc38 100644 --- a/codon/parser/visitors/typecheck/typecheck_expr.cpp +++ b/codon/parser/visitors/typecheck/typecheck_expr.cpp @@ -867,7 +867,8 @@ ExprPtr TypecheckVisitor::transformDot(DotExpr *expr, N(N(expr->expr, "_getattr"), N(expr->member))); } else { // For debugging purposes: - ctx->findMethod(typ->name, expr->member); + if (expr->member == "ticker") + ctx->findMethod(typ->name, expr->member); error("cannot find '{}' in {}", expr->member, typ->toString()); } } @@ -1392,13 +1393,13 @@ ExprPtr TypecheckVisitor::transformCall(CallExpr *expr, const types::TypePtr &in // TODO: needs cleaner logic for this. Maybe just use normal record type // and just track partialized function args, not the whole function as it's done // now. Major caveat: needs rewiring of the function generic partialization logic. - if (startswith(calleeFn->ast->name, TYPE_PARTIAL) && - endswith(calleeFn->ast->name, ".__new__:0")) { - seqassert(expr->type->getRecord(), "expected a partial record"); - auto r = expr->type->getRecord(); - expr->type = std::make_shared(r, ctx->cache->partials[r->name].first, - ctx->cache->partials[r->name].second); - } + // if (startswith(calleeFn->ast->name, TYPE_PARTIAL) && + // endswith(calleeFn->ast->name, ".__new__:0")) { + // seqassert(expr->type->getRecord(), "expected a partial record"); + // auto r = expr->type->getRecord(); + // expr->type = std::make_shared(r, ctx->cache->partials[r->name].first, + // ctx->cache->partials[r->name].second); + // } return nullptr; } } diff --git a/codon/parser/visitors/typecheck/typecheck_stmt.cpp b/codon/parser/visitors/typecheck/typecheck_stmt.cpp index 42ece717..c7aa05e9 100644 --- a/codon/parser/visitors/typecheck/typecheck_stmt.cpp +++ b/codon/parser/visitors/typecheck/typecheck_stmt.cpp @@ -508,6 +508,13 @@ void TypecheckVisitor::visit(ClassStmt *stmt) { else typ = std::make_shared( stmt->name, ctx->cache->reverseIdentifierLookup[stmt->name]); + if (stmt->isRecord() && startswith(stmt->name, TYPE_PARTIAL)) { + seqassert(in(ctx->cache->partials, stmt->name), + "invalid partial initialization: {}", stmt->name); + typ = std::make_shared(typ->getRecord(), + ctx->cache->partials[stmt->name].first, + ctx->cache->partials[stmt->name].second); + } typ->setSrcInfo(stmt->getSrcInfo()); ctx->add(TypecheckItem::Type, stmt->name, typ); ctx->bases[0].visitedAsts[stmt->name] = {TypecheckItem::Type, typ}; diff --git a/codon/sir/module.cpp b/codon/sir/module.cpp index e01e8808..b5036f9a 100644 --- a/codon/sir/module.cpp +++ b/codon/sir/module.cpp @@ -142,7 +142,8 @@ Func *Module::getOrRealizeFunc(const std::string &funcName, try { return cache->realizeFunction(func, arg, gens); } catch (const exc::ParserException &e) { - LOG_IR("getOrRealizeFunc parser error: {}", e.what()); + for (int i = 0; i < e.messages.size(); i++) + LOG_IR("getOrRealizeFunc parser error at {}: {}", e.locations[i], e.messages[i]); return nullptr; } }