Refactor InferenceAccess for call hooks
The `TypeInferenceAccess` and `TypeSlotAccess` traits have been consolidated into a single `InferenceAccess` trait. This simplifies the call hook interface by providing a unified way to access type inference operations and scope slot types. A new struct, `CheckerInferenceAccess`, is introduced to provide a concrete implementation of `InferenceAccess` for the `TypeChecker`. This struct wraps both the `TypeChecker` and the `TypeContext`, allowing call hooks to interact with both without needing to know their specific types. This avoids potential circular dependencies between modules. The `get_slot_type` method has been moved to the new `InferenceAccess` trait. This method is crucial for call hooks that need to recover the original `TypeVar` ID after substitutions have occurred, particularly in the `push_post_call` function for series.
This commit is contained in:
+11
-14
@@ -5,7 +5,7 @@ use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::ast::compiler::call_hooks::{FinalizeHook, PostCallHook, TypeInferenceAccess, TypeSlotAccess};
|
||||
use crate::ast::compiler::call_hooks::{FinalizeHook, InferenceAccess, PostCallHook};
|
||||
use crate::ast::diagnostics::Diagnostics;
|
||||
use crate::ast::environment::Environment;
|
||||
use crate::ast::nodes::{IdentifierBinding, Node, NodeKind, TypedNode, TypedPhase};
|
||||
@@ -36,14 +36,13 @@ pub(crate) fn series_element_type(ty: &StaticType) -> Option<StaticType> {
|
||||
fn series_post_call(
|
||||
_args: &TypedNode,
|
||||
ret_ty: StaticType,
|
||||
inference: &dyn TypeInferenceAccess,
|
||||
_ctx: &mut dyn TypeSlotAccess,
|
||||
ctx: &dyn InferenceAccess,
|
||||
_diag: &mut Diagnostics,
|
||||
) -> StaticType {
|
||||
if let StaticType::Series(inner) = &ret_ty
|
||||
&& **inner == StaticType::Any
|
||||
{
|
||||
return StaticType::Series(Box::new(inference.fresh_var()));
|
||||
return StaticType::Series(Box::new(ctx.fresh_var()));
|
||||
}
|
||||
ret_ty
|
||||
}
|
||||
@@ -130,8 +129,7 @@ fn series_finalize(
|
||||
fn push_post_call(
|
||||
args: &TypedNode,
|
||||
ret_ty: StaticType,
|
||||
inference: &dyn TypeInferenceAccess,
|
||||
ctx: &mut dyn TypeSlotAccess,
|
||||
ctx: &dyn InferenceAccess,
|
||||
diag: &mut Diagnostics,
|
||||
) -> StaticType {
|
||||
let NodeKind::Tuple { elements } = &args.kind else { return ret_ty };
|
||||
@@ -149,28 +147,27 @@ fn push_post_call(
|
||||
..
|
||||
} = &series_arg.kind
|
||||
{
|
||||
// Recover the raw inner type from ctx (before apply_subst) so we can
|
||||
// find the TypeVar ID even after the first push resolved it.
|
||||
// Recover the raw inner type from the scope slot (before apply_subst)
|
||||
// so we can find the TypeVar ID even after the first push resolved it.
|
||||
let raw_inner = match ctx.get_slot_type(*addr) {
|
||||
StaticType::Series(ri) => *ri,
|
||||
_ => inner_ty.clone(),
|
||||
};
|
||||
|
||||
if let Some(promoted) = inference
|
||||
if let Some(promoted) = ctx
|
||||
.try_numeric_widen(&inner_ty, &val_ty)
|
||||
.or_else(|| inference.try_record_promote(&inner_ty, &val_ty))
|
||||
.or_else(|| ctx.try_record_promote(&inner_ty, &val_ty))
|
||||
{
|
||||
// Rebind the TypeVar to the promoted type so that finalize
|
||||
// injects the correct schema (e.g. :float instead of :int).
|
||||
if let StaticType::TypeVar(n) = raw_inner {
|
||||
inference.bind_typevar(n, promoted.clone());
|
||||
ctx.bind_typevar(n, promoted.clone());
|
||||
}
|
||||
ctx.set_slot_type(*addr, StaticType::Series(Box::new(promoted)));
|
||||
} else {
|
||||
inference.unify(inner_ty, val_ty, diag);
|
||||
ctx.unify(inner_ty, val_ty, diag);
|
||||
}
|
||||
} else {
|
||||
inference.unify(inner_ty, val_ty, diag);
|
||||
ctx.unify(inner_ty, val_ty, diag);
|
||||
}
|
||||
ret_ty
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user