Fix bug in custom binops where their return types aren't inferred
This commit is contained in:
parent
0196fb53ed
commit
c316d94b75
@ -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
10
examples/testmod.reid
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
struct Otus {}
|
||||
|
||||
impl binop (lhs: Otus) + (rhs: u64) -> Otus {
|
||||
return lhs;
|
||||
}
|
||||
|
||||
pub fn make_otus() -> Otus {
|
||||
return Otus {};
|
||||
}
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user