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::print;
import std::from_str; import std::from_str;
import std::concat_strings;
import std::free_string;
import std::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 { fn main() -> u8 {
let mut otus = from_str("hello"); print((from_str("hello") + " beep: ") + 1234u64);
otus(&mut otus);
print(otus + " beep");
return 0; 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); let added = from_str(rhs);
concat_strings(&mut new, added); concat_strings(&mut new, added);
free_string(&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 { 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)] #[cfg(debug_assertions)]
println!("{:-^100}", "TYPE INFERRER OUTPUT"); 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 /// TypeRefs-struct is used as a helper to go through the modules and change
/// types while inferring. /// types while inferring.
pub struct TypeInference<'t> { pub struct TypeInference<'t> {
pub refs: &'t TypeRefs, pub refs: &'t mut TypeRefs,
} }
impl<'t> Pass for TypeInference<'t> { impl<'t> Pass for TypeInference<'t> {
@ -77,7 +77,18 @@ impl<'t> Pass for TypeInference<'t> {
binop.signature(), binop.signature(),
); );
} else { } 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 .fn_kind
.infer_types(state, &scope_hints, Some(self.return_type.clone()))?; .infer_types(state, &scope_hints, Some(self.return_type.clone()))?;
if let Some(mut ret_ty) = ret_ty { 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()); ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
} }
@ -320,7 +330,7 @@ impl Expression {
continue; continue;
} }
if binop.operator.is_commutative() { 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()); applying_binops.push(binop.clone());
continue; continue;
} }
@ -330,7 +340,6 @@ impl Expression {
} else { } else {
Vec::new() Vec::new()
}; };
if binops.len() > 0 { if binops.len() > 0 {
let binop = unsafe { binops.get_unchecked(0) }; let binop = unsafe { binops.get_unchecked(0) };
let mut widened_lhs = binop.hands.0.clone(); let mut widened_lhs = binop.hands.0.clone();

View File

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