Skip to content

Commit

Permalink
fix: error on if without else when type mismatch
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Feb 5, 2025
1 parent e476f95 commit eaa65ff
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 18 deletions.
38 changes: 20 additions & 18 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ impl<'context> Elaborator<'context> {
target_type: Option<&Type>,
) -> (HirExpression, Type) {
let expr_span = if_expr.condition.span;
let consequence_span = if_expr.consequence.span;
let (condition, cond_type) = self.elaborate_expression(if_expr.condition);
let (consequence, mut ret_type) =
self.elaborate_expression_with_target_type(if_expr.consequence, target_type);
Expand All @@ -924,29 +925,30 @@ impl<'context> Elaborator<'context> {
expr_span,
});

let alternative = if_expr.alternative.map(|alternative| {
let expr_span = alternative.span;
let (alternative, else_type, error_span) = if let Some(alternative) = if_expr.alternative {
let (else_, else_type) =
self.elaborate_expression_with_target_type(alternative, target_type);
(Some(else_), else_type, expr_span)
} else {
(None, Type::Unit, consequence_span)
};

self.unify(&ret_type, &else_type, || {
let err = TypeCheckError::TypeMismatch {
expected_typ: ret_type.to_string(),
expr_typ: else_type.to_string(),
expr_span,
};
self.unify(&ret_type, &else_type, || {
let err = TypeCheckError::TypeMismatch {
expected_typ: ret_type.to_string(),
expr_typ: else_type.to_string(),
expr_span: error_span,
};

let context = if ret_type == Type::Unit {
"Are you missing a semicolon at the end of your 'else' branch?"
} else if else_type == Type::Unit {
"Are you missing a semicolon at the end of the first block of this 'if'?"
} else {
"Expected the types of both if branches to be equal"
};
let context = if ret_type == Type::Unit {
"Are you missing a semicolon at the end of your 'else' branch?"
} else if else_type == Type::Unit {
"Are you missing a semicolon at the end of the first block of this 'if'?"
} else {
"Expected the types of both if branches to be equal"
};

err.add_context(context)
});
else_
err.add_context(context)
});

if alternative.is_none() {
Expand Down
18 changes: 18 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4347,3 +4347,21 @@ fn call_function_alias_type() {
"#;
assert_no_errors(src);
}

#[test]
fn errors_on_if_without_else_type_mismatch() {
let src = r#"
fn main() {
if true {
1
}
}
"#;
let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);

let CompilationError::TypeError(TypeCheckError::Context { err, .. }) = &errors[0].0 else {
panic!("Expected a Context error");
};
assert!(matches!(**err, TypeCheckError::TypeMismatch { .. }));
}

0 comments on commit eaa65ff

Please sign in to comment.