From ddea07666d82f389d4c5d282110e1b3010c0dca7 Mon Sep 17 00:00:00 2001 From: Brummel Date: Fri, 27 Mar 2026 21:16:13 +0100 Subject: [PATCH] Monomorphize function templates by re-type-checking Re-type-checks function templates with concrete argument types to produce specialized TypedNodes for monomorphization. This process leverages the `check_node_as_bound` method, which is generic enough to handle different binding phases, allowing for fresh type inference from the call site. --- src/ast/environment.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 825cc5d..b654216 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -705,24 +705,17 @@ impl Environment { -> Result<(Value, StaticType), String> { let mut diag = Diagnostics::new(); let checker = TypeChecker::new(root_types.clone()); - - // For specialization, we re-type-check the analyzed node. - // Note: AnalyzedNode.ty.original is the TypedNode. - // But TypeChecker expects Node. We need to go from TypedNode -> BoundNode. - // However, since TypedNode is just Node, we can't easily "un-type" it. - // Instead, we access the original AST from the binder if we had it, - // OR we make the TypeChecker generic. - // For now, we assume the TypedNode can be used where a BoundNode is expected - // if we strip the metadata. - // A better way is to store the BoundNode in NodeMetrics as well. - - // Temporary fix: Re-binding from source would be too expensive. - // Let's assume for now that we can specialize directly on the TypedNode - // or that we need a small helper to transform TypedNode -> BoundNode. - - // Realizing that TypedNode (StaticType) is very similar to BoundNode (()), - // we can just use the internal transform. - + + // Monomorphization: re-type-check the function template with the concrete + // call-site argument types, producing a specialized TypedNode. + // + // `func_template` is an AnalyzedNode whose `ty.original` holds the Rc + // preserved by the Analyzer in NodeMetrics. + // + // `check_node_as_bound` is generic over all `BoundLike` phases (BoundPhase, + // TypedPhase, and AnalyzedPhase all share the same binding structure). This lets + // us re-run type inference on the TypedNode with concrete `arg_types`: existing + // `ty` metadata is discarded and all types are inferred fresh from the call site. let retyped_ast = checker.check_node_as_bound(func_template.ty.original.as_ref(), arg_types, &mut diag); if diag.has_errors() {