diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 81b5ae872b..a61606fe8d 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5843,7 +5843,7 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool { } pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type { - typ := c.expr(node.expr) + typ := c.unwrap_generic(c.expr(node.expr)) typ_sym := c.table.get_type_symbol(typ) is_non_void_pointer := (typ.is_ptr() || typ.is_pointer()) && typ_sym.kind != .voidptr if !c.inside_unsafe && is_non_void_pointer && !node.expr.is_auto_deref_var() { diff --git a/vlib/v/tests/generics_test.v b/vlib/v/tests/generics_test.v index dc28b214d2..49951f75ef 100644 --- a/vlib/v/tests/generics_test.v +++ b/vlib/v/tests/generics_test.v @@ -33,6 +33,49 @@ fn test_infix_expr() { assert plus('a', 'b') == 'ab' } +fn plus_one(a T) T { + mut b := a + b++ + return b +} + +fn minus_one(a T) T { + mut b := a + b-- + return b +} + +fn test_postfix_expr() { + assert plus_one(-1) == 0 + assert plus_one(byte(0)) == 1 + assert plus_one(u16(1)) == 2 + assert plus_one(u32(2)) == 3 + assert plus_one(u64(3)) == 4 + assert plus_one(i8(-10)) == -9 + assert plus_one(i16(-9)) == -8 + assert plus_one(int(-8)) == -7 + assert plus_one(i64(-7)) == -6 + assert minus_one(0) == -1 + assert minus_one(byte(1)) == 0 + assert minus_one(u16(2)) == 1 + assert minus_one(u32(3)) == 2 + assert minus_one(u64(4)) == 3 + assert minus_one(i8(-8)) == -9 + assert minus_one(i16(-7)) == -8 + assert minus_one(int(-6)) == -7 + assert minus_one(i64(-5)) == -6 + // the point is to see if it compiles, more than if the result + // is correct, so 1e-6 isn't necessarily the right value to do this + // but it's not important + delta := 1e-6 + assert plus_one(1.1) - 2.1 < delta + assert plus_one(f32(2.2)) - 3.2 < delta + assert plus_one(f64(3.3)) - 4.3 < delta + assert minus_one(1.1) - 0.1 < delta + assert minus_one(f32(2.2)) - 1.2 < delta + assert minus_one(f64(3.3)) - 2.3 < delta +} + fn sum(l []T) T { mut r := T(0) for e in l {