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.
This commit is contained in:
+11
-18
@@ -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<BoundPhase>. We need to go from TypedNode -> BoundNode.
|
||||
// However, since TypedNode is just Node<TypedPhase>, 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<TypedNode>
|
||||
// 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() {
|
||||
|
||||
Reference in New Issue
Block a user