diff --git a/vlib/math/stats/stats.v b/vlib/math/stats/stats.v index 6462a743ce..98d970d2eb 100644 --- a/vlib/math/stats/stats.v +++ b/vlib/math/stats/stats.v @@ -67,14 +67,14 @@ pub fn harmonic_mean[T](data []T) T { for v in data { sum += f64(1.0) / v } - return f64(data.len / sum) + return f64(f64(data.len) / sum) } $else { // use f32 for f32/int/... mut sum := f32(0) for v in data { sum += f32(1.0) / f32(v) } - return T(data.len / sum) + return T(f32(data.len) / sum) } } diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 36c447abc8..93a5f8dc52 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -1189,8 +1189,8 @@ fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) { || g.file.is_translated) if needs_cast { typ_str := if node.left_ct_expr { - g.styp(g.type_resolver.get_type_or_default(node.left, node.promoted_type)) - } else if node.right_ct_expr { + g.styp(g.type_resolver.get_type_or_default(node.left, node.left_type)) + } else if node.left !in [ast.Ident, ast.CastExpr] && node.right_ct_expr { g.styp(g.type_resolver.get_type_or_default(node.right, node.promoted_type)) } else { g.styp(node.promoted_type) diff --git a/vlib/v/tests/generics/generic_selector_len_test.v b/vlib/v/tests/generics/generic_selector_len_test.v new file mode 100644 index 0000000000..6934d38d82 --- /dev/null +++ b/vlib/v/tests/generics/generic_selector_len_test.v @@ -0,0 +1,17 @@ +struct Foo[T] { + len T +} + +fn t[T](val T) string { + a := val.len + val.len + println(a) + return a.str() +} + +fn test_main() { + assert t(Foo[string]{ len: 'hello' }) == 'hellohello' + assert t(Foo[int]{ len: 123 }) == '246' + assert t([1, 2, 3]) == '6' + assert t([1.2, 2.2, 3.3]) == '6' + assert t(['', '', '']) == '6' +} diff --git a/vlib/v/type_resolver/comptime_resolver.v b/vlib/v/type_resolver/comptime_resolver.v index 8d4012a33f..7e06e0f2eb 100644 --- a/vlib/v/type_resolver/comptime_resolver.v +++ b/vlib/v/type_resolver/comptime_resolver.v @@ -47,7 +47,7 @@ pub fn (t &ResolverInfo) is_comptime(node ast.Expr) bool { } } ast.SelectorExpr { - return node.expr is ast.Ident && node.expr.ct_expr && node.field_name != 'len' + return node.expr is ast.Ident && node.expr.ct_expr } ast.InfixExpr { return node.left_ct_expr || node.right_ct_expr @@ -83,6 +83,8 @@ pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind { return t.get_ct_type_var(node.left) } else if node is ast.ParExpr { return t.get_ct_type_var(node.expr) + } else if node is ast.SelectorExpr { + return t.get_ct_type_var(node.expr) } return .no_comptime }