diff --git a/src/modules/function/ret.rs b/src/modules/function/ret.rs index a6418adf..333ad47f 100644 --- a/src/modules/function/ret.rs +++ b/src/modules/function/ret.rs @@ -37,16 +37,9 @@ impl SyntaxModule for Return { syntax(meta, &mut self.expr)?; let ret_type = meta.context.fun_ret_type.as_ref(); let expr_type = &self.expr.get_type(); - // Unpacking Failable types - let (ret_type, expr_type) = match (ret_type, expr_type) { - types @ (Some(Type::Failable(_)), Type::Failable(_)) => types, - (Some(Type::Failable(ret_type)), expr_type) => (Some(ret_type.as_ref()), expr_type), - (Some(ret_type), Type::Failable(expr_type)) => (Some(ret_type), expr_type.as_ref()), - types => types - }; match ret_type { Some(ret_type) => { - if ret_type != expr_type { + if ret_type != expr_type && !expr_type.is_subset(ret_type) { return error!(meta, tok => { message: "Return type does not match function return type", comment: format!("Given type: {}, expected type: {}", expr_type, ret_type) diff --git a/src/modules/types.rs b/src/modules/types.rs index d12a2ee9..f12ee0a1 100644 --- a/src/modules/types.rs +++ b/src/modules/types.rs @@ -20,6 +20,7 @@ impl Type { (Type::Array(l), Type::Array(r)) => { **l != Type::Generic && **r == Type::Generic } + (l, Type::Failable(r)) => !matches!(l, Type::Failable(_)) && *l == **r, _ => false } } @@ -156,4 +157,27 @@ mod tests { assert!(!a.is_subset(&a)); } + + #[test] + fn non_failable_is_a_subset_of_failable() { + let a = Type::Text; + let b = Type::Failable(Box::new(Type::Text)); + + assert!(a.is_subset(&b)); + } + + #[test] + fn failable_is_not_a_subset_of_non_failable() { + let a = Type::Text; + let b = Type::Failable(Box::new(Type::Text)); + + assert!(!b.is_subset(&a)); + } + + #[test] + fn failable_is_not_a_subset_of_itself() { + let a = Type::Failable(Box::new(Type::Text)); + + assert!(!a.is_subset(&a)); + } }