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

View File

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

View File

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

View File

@ -559,6 +559,9 @@ impl Expression {
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1); 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_res = rhs.typecheck(state, &typerefs, Some(&lhs_type));
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); 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)?; 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 lhs_ref = lhs.infer_types(state, type_refs)?;
let mut rhs_ref = rhs.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) .binop(op, &mut lhs_ref, &mut rhs_ref, &state.scope.binops)
.ok_or(ErrorKind::TypesIncompatible( .ok_or(ErrorKind::TypesIncompatible(
lhs_ref.resolve_deep().unwrap(), lhs_ref.resolve_deep().unwrap(),
rhs_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) => { ExprKind::FunctionCall(function_call) => {
// Get function definition and types // Get function definition and types

View File

@ -238,9 +238,14 @@ impl<'outer> ScopeTypeRefs<'outer> {
{ {
return self.from_type(&TypeKind::Vague(VagueType::Unknown)); 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) { if let Some(ret) = try_binop(lhs, rhs, binop) {
return Some(ret); break Some(ret);
} }
if binop.operator.is_commutative() { if binop.operator.is_commutative() {
if let Some(ret) = try_binop(rhs, lhs, binop) { 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))
} }
} }