Fix collapsing of both types in type inferrer

This commit is contained in:
Sofia 2025-07-24 19:03:03 +03:00
parent 27db67dd99
commit bb0b7c12c3
6 changed files with 38 additions and 14 deletions

View File

@ -900,13 +900,8 @@ impl mir::Expression {
if let Some(operation) = operation {
let a = operation.codegen(&lhs_val, &rhs_val, scope)?;
dbg!(&scope.context);
dbg!(&a);
Some(a)
} else {
dbg!((lhs_val.1.clone(), rhs_val.1.clone()));
dbg!(&operation.map(|b| &b.return_ty));
let lhs_type = lhs_exp
.return_type(&Default::default(), scope.module_id)
.unwrap()
@ -972,6 +967,7 @@ impl mir::Expression {
Instr::Sub(lhs, mul)
}
};
dbg!(&instr);
Some(StackValue(
StackValueKind::Immutable(
scope

View File

@ -47,6 +47,13 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> {
pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
let mut intrinsics = Vec::new();
intrinsics.push(intrinsic_binop(
BinaryOperator::Add,
TypeKind::U8,
TypeKind::U8,
TypeKind::U8,
IntrinsicIAdd(TypeKind::U8),
));
intrinsics.push(intrinsic_binop(
BinaryOperator::Add,
TypeKind::U32,
@ -54,6 +61,13 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
TypeKind::U32,
IntrinsicIAdd(TypeKind::U32),
));
intrinsics.push(intrinsic_binop(
BinaryOperator::Add,
TypeKind::U16,
TypeKind::U16,
TypeKind::U16,
IntrinsicIAdd(TypeKind::U16),
));
intrinsics
}

View File

@ -294,10 +294,10 @@ impl TypeKind {
(lhs1, rhs1): (&TypeKind, &TypeKind),
(lhs2, rhs2): (&TypeKind, &TypeKind),
) -> Option<(TypeKind, TypeKind)> {
if lhs1.collapse_into(&lhs2).is_ok() && rhs1.collapse_into(&rhs2).is_ok() {
Some((lhs1.clone(), rhs2.clone()))
} else if lhs1.collapse_into(&rhs2).is_ok() && rhs1.collapse_into(&lhs2).is_ok() {
Some((rhs1.clone(), lhs1.clone()))
if let (Ok(lhs), Ok(rhs)) = (lhs1.collapse_into(&lhs2), rhs1.collapse_into(&rhs2)) {
Some((lhs, rhs))
} else if let (Ok(lhs), Ok(rhs)) = (lhs1.collapse_into(&rhs2), rhs1.collapse_into(&lhs2)) {
Some((rhs, lhs))
} else {
None
}

View File

@ -559,6 +559,9 @@ impl Expression {
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1);
let rhs_res = rhs.typecheck(state, &typerefs, Some(&lhs_type));
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1);
dbg!(&op, &hint_t);
dbg!(&lhs_type);
dbg!(&rhs_type);
let both_t = lhs_type.collapse_into(&rhs_type)?;

View File

@ -312,12 +312,20 @@ impl Expression {
let mut lhs_ref = lhs.infer_types(state, type_refs)?;
let mut rhs_ref = rhs.infer_types(state, type_refs)?;
type_refs
if let Ok(binop) = type_refs
.binop(op, &mut lhs_ref, &mut rhs_ref, &state.scope.binops)
.ok_or(ErrorKind::TypesIncompatible(
lhs_ref.resolve_deep().unwrap(),
rhs_ref.resolve_deep().unwrap(),
))
{
Ok(binop)
} else {
let typeref = lhs_ref.narrow(&rhs_ref).unwrap();
Ok(type_refs
.from_type(&typeref.resolve_deep().unwrap().simple_binop_type(op))
.unwrap())
}
}
ExprKind::FunctionCall(function_call) => {
// Get function definition and types

View File

@ -238,9 +238,14 @@ impl<'outer> ScopeTypeRefs<'outer> {
{
return self.from_type(&TypeKind::Vague(VagueType::Unknown));
}
for (_, binop) in binops.iter() {
let mut iter = binops.iter();
loop {
let Some((_, binop)) = iter.next() else {
break None;
};
if let Some(ret) = try_binop(lhs, rhs, binop) {
return Some(ret);
break Some(ret);
}
if binop.operator.is_commutative() {
if let Some(ret) = try_binop(rhs, lhs, binop) {
@ -248,8 +253,6 @@ impl<'outer> ScopeTypeRefs<'outer> {
}
}
}
let ty = lhs.narrow(rhs)?;
self.from_type(&ty.as_type().simple_binop_type(op))
}
}