diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fd74e50ab1..f38e54d483 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4071,8 +4071,11 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { ret_type = expr_type stmt.typ = ret_type } else if node.is_expr && ret_type != expr_type { - sym := c.table.get_type_symbol(ret_type) - c.error('return type mismatch, it should be `$sym.name`', stmt.expr.position()) + if !c.check_types(ret_type, expr_type) { + ret_sym := c.table.get_type_symbol(ret_type) + c.error('return type mismatch, it should be `$ret_sym.name`', + stmt.expr.position()) + } } } else { diff --git a/vlib/v/tests/match_expression_with_fn_names_in_branches_test.v b/vlib/v/tests/match_expression_with_fn_names_in_branches_test.v new file mode 100644 index 0000000000..8994995a4c --- /dev/null +++ b/vlib/v/tests/match_expression_with_fn_names_in_branches_test.v @@ -0,0 +1,63 @@ +import math + +const tau = 2 * math.pi + +struct Note { +mut: + freq f32 + vol f32 + step int + paused bool +} + +enum WaveKind { + sine + sawtooth +} + +struct Config { + wave_kind WaveKind +} + +fn sawtooth(note &Note, time f32, amp f32) f32 { + t := time * note.freq + f := t - int(t) + return f32(2 * (f - 0.5)) * (amp / 2) +} + +fn sine(note &Note, time f32, amp f32) f32 { + return math.sinf(tau * time * note.freq) * amp +} + +pub fn new_context(cfg Config) fn (&Note, f32, f32) f32 { + // Note, that here `sine` and `sawtooth`, + // are different functions, but they do have + // a compatible signature, so `next_fn` can + // become either one of them: + next_fn := match cfg.wave_kind { + .sine { sine } + .sawtooth { sawtooth } + } + return next_fn +} + +fn test_match_expression_returning_fns() { + note := &Note{ + freq: 432 + vol: 80 + step: 3 + paused: false + } + + x := new_context(wave_kind: .sawtooth) + assert '$x' == 'fn (Note, f32, f32) f32' + assert math.abs(x(note, 0, 0.5) + 0.25) < 0.001 + assert math.abs(x(note, 0.4, 0.5) - 0.15) < 0.001 + assert math.abs(x(note, 0.7, 0.5) + 0.05) < 0.001 + + y := new_context(wave_kind: .sine) + assert '$y' == 'fn (Note, f32, f32) f32' + assert math.abs(y(note, 0, 0.5)) - 0.475 < 0.0001 + assert math.abs(y(note, 0.4, 0.5)) - 0.4755 < 0.0001 + assert math.abs(y(note, 0.7, 0.5)) - 0.2939 < 0.0001 +}