pub fn unify<'b>(&mut self, a: &'b ParsedType, b: &'b ParsedType) -> Vec<(usize, ParsedType)> {
        let mut ret = vec![];
        match (a, b) {
            // TODO: Care about generic args
            (ParsedType::Var { id: ref a_id, .. }, ParsedType::Var { id: ref b_id, .. }) => {
                // @TYPEDEF: TODO: When typedefs come around be smarter here
                if *a_id == *b_id {
                    // Do nothing no unification
                } else {
                    // TODO: Coercian for example int => bool
                    // Type error!
                    warn!("Type Error: Can't unify {:?} and {:?}", a_id, b_id);
                }
            }
            (ParsedType::Fresh { id: ref a_id }, ParsedType::Fresh { id: ref b_id }) => {
                if *a_id != *b_id {
                    ret.push((*a_id, ParsedType::Fresh { id: *b_id }));
                } else {
                    // already unified
                }
            }
            (ParsedType::Fresh { ref id }, ref other)
            | (ref other, ParsedType::Fresh { ref id }) => {
                if self.occurs(*id, other) {
                    // error
                    warn!("Occurs check failed, infinite type in {}", id);
                } else {
                    // id := other
                    ret.push((*id, (*other).clone()));
                }
            }
            (ParsedType::Pointer(ref a), ParsedType::Pointer(ref b)) => ret = self.unify(a, b),
            (
                ParsedType::Func {
                    args: ref a_args,
                    ret: ref a_ret,
                    ..
                },
                ParsedType::Func {
                    args: ref b_args,
                    ret: ref b_ret,
                    ..
                },
            ) => {
                if a_args.len() != b_args.len() {
                    warn!("Types counts don't match up");
                } else {
                    for i in 0..a_args.len() {
                        ret.extend(self.unify(&a_args[i], &b_args[i]));
                    }
                    ret.extend(self.unify(a_ret, b_ret));
                }
            }
            // Missing arrays, TODO:
            // Because eh array unification is hard
            // (it's not just pointers)
            _ => {
                warn!("No unification of {:?} and {:?}", a, b);
            }
        }
        ret
    }
/// Perform unification of a and b
/// The result should be a substitution that can be performed
/// giving the result that a := b
///
/// If the types can't be unified it logs an error and continues
Perform unification of a and b
The result should be a substitution that can be performed
giving the result that a := b

If the types can't be unified it logs an error and continues
Perform unification of a and b The result should be a substitution that can be performed giving the result that a : = b If the types can ' t be unified it logs an error and continues
pub fn unify<'b>(&mut self, a: &'b ParsedType, b: &'b ParsedType) -> Vec<(usize, ParsedType)> {
        let mut ret = vec![];
        match (a, b) {
            // TODO: Care about generic args
            (ParsedType::Var { id: ref a_id, .. }, ParsedType::Var { id: ref b_id, .. }) => {
                // @TYPEDEF: TODO: When typedefs come around be smarter here
                if *a_id == *b_id {
                    // Do nothing no unification
                } else {
                    // TODO: Coercian for example int => bool
                    // Type error!
                    warn!("Type Error: Can't unify {:?} and {:?}", a_id, b_id);
                }
            }
            (ParsedType::Fresh { id: ref a_id }, ParsedType::Fresh { id: ref b_id }) => {
                if *a_id != *b_id {
                    ret.push((*a_id, ParsedType::Fresh { id: *b_id }));
                } else {
                    // already unified
                }
            }
            (ParsedType::Fresh { ref id }, ref other)
            | (ref other, ParsedType::Fresh { ref id }) => {
                if self.occurs(*id, other) {
                    // error
                    warn!("Occurs check failed, infinite type in {}", id);
                } else {
                    // id := other
                    ret.push((*id, (*other).clone()));
                }
            }
            (ParsedType::Pointer(ref a), ParsedType::Pointer(ref b)) => ret = self.unify(a, b),
            (
                ParsedType::Func {
                    args: ref a_args,
                    ret: ref a_ret,
                    ..
                },
                ParsedType::Func {
                    args: ref b_args,
                    ret: ref b_ret,
                    ..
                },
            ) => {
                if a_args.len() != b_args.len() {
                    warn!("Types counts don't match up");
                } else {
                    for i in 0..a_args.len() {
                        ret.extend(self.unify(&a_args[i], &b_args[i]));
                    }
                    ret.extend(self.unify(a_ret, b_ret));
                }
            }
            // Missing arrays, TODO:
            // Because eh array unification is hard
            // (it's not just pointers)
            _ => {
                warn!("No unification of {:?} and {:?}", a, b);
            }
        }
        ret
    }
pub fn unify < ' b > ( & mut self , a : & ' b ParsedType , b : & ' b ParsedType ) -> Vec < ( usize , ParsedType ) > { let mut ret = vec ! [ ] ; match ( a , b ) { // TODO: Care about generic args ( ParsedType :: Var { id : ref a_id , .. } , ParsedType :: Var { id : ref b_id , .. } ) => { // @TYPEDEF: TODO: When typedefs come around be smarter here if * a_id == * b_id { // Do nothing no unification } else { // TODO: Coercian for example int => bool // Type error! warn ! ( " " a_id b_id ) ; } } ( ParsedType :: Fresh { id : ref a_id } , ParsedType :: Fresh { id : ref b_id } ) => { if * a_id != * b_id { ret . push ( ( * a_id , ParsedType :: Fresh { id : * b_id } ) ) ; } else { // already unified } } ( ParsedType :: Fresh { ref id } , ref other ) | ( ref other , ParsedType :: Fresh { ref id } ) => { if self . occurs ( * id , other ) { // error warn ! ( " " id ) ; } else { // id := other ret . push ( ( * id , ( * other ) . clone ( ) ) ) ; } } ( ParsedType :: Pointer ( ref a ) , ParsedType :: Pointer ( ref b ) ) => ret = self . unify ( a , b ) , ( ParsedType :: Func { args : ref a_args , ret : ref a_ret , .. } , ParsedType :: Func { args : ref b_args , ret : ref b_ret , .. } , ) => { if a_args . len ( ) != b_args . len ( ) { warn ! ( " " ) ; } else { for i in 0 .. a_args . len ( ) { ret . extend ( self . unify ( & a_args [ i ] , & b_args [ i ] ) ) ; } ret . extend ( self . unify ( a_ret , b_ret ) ) ; } } // Missing arrays, TODO: // Because eh array unification is hard // (it's not just pointers) _ => { warn ! ( " " a b ) ; } } ret }
Perform unification of a and b
The result should be a substitution that can be performed
giving the result that a := b
Perform unification of a and b The result should be a substitution that can be performed giving the result that a : = b
&mut self
a
&'b ParsedType
b
&'b ParsedType