Fix bug in custom binops where their return types aren't inferred

This commit is contained in:
Sofia 2025-07-26 14:01:53 +03:00
parent 0196fb53ed
commit c316d94b75
6 changed files with 35 additions and 20 deletions

View File

@ -1,19 +1,9 @@
import std::print;
import std::from_str;
import std::concat_strings;
import std::free_string;
import std::String;
fn otus(param: &mut String) {
let b: String = from_str(" bello");
concat_strings(param, b);
free_string(&b);
}
fn main() -> u8 {
let mut otus = from_str("hello");
otus(&mut otus);
print(otus + " beep");
print((from_str("hello") + " beep: ") + 1234u64);
return 0;
}

10
examples/testmod.reid Normal file
View File

@ -0,0 +1,10 @@
struct Otus {}
impl binop (lhs: Otus) + (rhs: u64) -> Otus {
return lhs;
}
pub fn make_otus() -> Otus {
return Otus {};
}

View File

@ -16,7 +16,13 @@ impl binop (lhs: String) + (rhs: *char) -> String {
let added = from_str(rhs);
concat_strings(&mut new, added);
free_string(&added);
return lhs;
return new;
}
impl binop (lhs: String) + (rhs: u64) -> String {
let mut new = lhs;
add_num_to_str(&mut new, rhs);
return new;
}
struct div_t {

View File

@ -173,9 +173,9 @@ pub fn perform_all_passes<'map>(
));
}
let refs = TypeRefs::with_binops(binops);
let mut refs = TypeRefs::with_binops(binops);
let state = context.pass(&mut TypeInference { refs: &refs })?;
let state = context.pass(&mut TypeInference { refs: &mut refs })?;
#[cfg(debug_assertions)]
println!("{:-^100}", "TYPE INFERRER OUTPUT");

View File

@ -33,7 +33,7 @@ use super::{
/// TypeRefs-struct is used as a helper to go through the modules and change
/// types while inferring.
pub struct TypeInference<'t> {
pub refs: &'t TypeRefs,
pub refs: &'t mut TypeRefs,
}
impl<'t> Pass for TypeInference<'t> {
@ -77,7 +77,18 @@ impl<'t> Pass for TypeInference<'t> {
binop.signature(),
);
} else {
seen_binops.insert(binop_key);
seen_binops.insert(binop_key.clone());
self.refs
.binop_types
.set(
binop_key,
crate::mir::pass::ScopeBinopDef {
hands: (binop.lhs.1.clone(), binop.rhs.1.clone()),
operator: binop.op,
return_ty: binop.return_type.clone(),
},
)
.ok();
}
}
@ -119,7 +130,6 @@ impl BinopDefinition {
.fn_kind
.infer_types(state, &scope_hints, Some(self.return_type.clone()))?;
if let Some(mut ret_ty) = ret_ty {
dbg!(&ret_ty, &self.return_type);
ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
}
@ -320,7 +330,7 @@ impl Expression {
continue;
}
if binop.operator.is_commutative() {
if let Some(_) = binop.narrow(&lhs_ty, &rhs_ty) {
if let Some(_) = binop.narrow(&rhs_ty, &lhs_ty) {
applying_binops.push(binop.clone());
continue;
}
@ -330,7 +340,6 @@ impl Expression {
} else {
Vec::new()
};
if binops.len() > 0 {
let binop = unsafe { binops.get_unchecked(0) };
let mut widened_lhs = binop.hands.0.clone();

View File

@ -80,7 +80,7 @@ impl TypeRefKind {
while let Some(other) = binops.next() {
ty = ty.widen_into(&other);
}
ty
ty.clone()
} else {
TypeKind::Vague(VagueType::Unknown)
}