From c316d94b75914a18f6154141f21df5583c7ff101 Mon Sep 17 00:00:00 2001 From: sofia Date: Sat, 26 Jul 2025 14:01:53 +0300 Subject: [PATCH] Fix bug in custom binops where their return types aren't inferred --- examples/imported_type.reid | 12 +----------- examples/testmod.reid | 10 ++++++++++ reid/lib/std.reid | 8 +++++++- reid/src/lib.rs | 4 ++-- reid/src/mir/typecheck/typeinference.rs | 19 ++++++++++++++----- reid/src/mir/typecheck/typerefs.rs | 2 +- 6 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 examples/testmod.reid diff --git a/examples/imported_type.reid b/examples/imported_type.reid index 9d06a13..8a64c52 100644 --- a/examples/imported_type.reid +++ b/examples/imported_type.reid @@ -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; } \ No newline at end of file diff --git a/examples/testmod.reid b/examples/testmod.reid new file mode 100644 index 0000000..f00dedb --- /dev/null +++ b/examples/testmod.reid @@ -0,0 +1,10 @@ + +struct Otus {} + +impl binop (lhs: Otus) + (rhs: u64) -> Otus { + return lhs; +} + +pub fn make_otus() -> Otus { + return Otus {}; +} \ No newline at end of file diff --git a/reid/lib/std.reid b/reid/lib/std.reid index e133222..e7dbf9b 100644 --- a/reid/lib/std.reid +++ b/reid/lib/std.reid @@ -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 { diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 6dcb79c..eb50c2b 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -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"); diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index d103586..21ea795 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -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(); diff --git a/reid/src/mir/typecheck/typerefs.rs b/reid/src/mir/typecheck/typerefs.rs index e7f3a51..1e7ca80 100644 --- a/reid/src/mir/typecheck/typerefs.rs +++ b/reid/src/mir/typecheck/typerefs.rs @@ -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) }