mirror of
https://github.com/vlang/v.git
synced 2025-09-17 19:36:35 -04:00
parent
6025893768
commit
83742f99d3
@ -85,7 +85,8 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
|
||||
c.error('no known default format for type `${c.table.get_type_name(ftyp)}`',
|
||||
node.fmt_poss[i])
|
||||
}
|
||||
} else if c.comptime.is_comptime(expr) && c.comptime.get_type(expr) != ast.void_type {
|
||||
} else if c.comptime.is_comptime(expr)
|
||||
&& c.comptime.get_type_or_default(expr, ast.void_type) != ast.void_type {
|
||||
// still `_` placeholder for comptime variable without specifier
|
||||
node.need_fmts[i] = false
|
||||
} else {
|
||||
|
@ -61,6 +61,15 @@ pub fn (mut ct ComptimeInfo) is_comptime(node ast.Expr) bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
return node.expr is ast.Ident && node.expr.ct_expr
|
||||
}
|
||||
ast.InfixExpr {
|
||||
return ct.is_comptime(node.left) || ct.is_comptime(node.right)
|
||||
}
|
||||
ast.ParExpr {
|
||||
return ct.is_comptime(node.expr)
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
@ -120,6 +129,26 @@ pub fn (mut ct ComptimeInfo) get_type_or_default(node ast.Expr, default_typ ast.
|
||||
return if ctyp != ast.void_type { ctyp } else { default_typ }
|
||||
}
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
if node.expr is ast.Ident && node.expr.ct_expr {
|
||||
struct_typ := ct.resolver.unwrap_generic(ct.get_type(node.expr))
|
||||
struct_sym := ct.table.final_sym(struct_typ)
|
||||
// Struct[T] can have field with generic type
|
||||
if struct_sym.info is ast.Struct && struct_sym.info.generic_types.len > 0 {
|
||||
if field := ct.table.find_field(struct_sym, node.field_name) {
|
||||
return field.typ
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.ParExpr {
|
||||
return ct.get_type_or_default(node.expr, default_typ)
|
||||
}
|
||||
ast.InfixExpr {
|
||||
if node.op in [.plus, .minus, .mul, .div, .mod] {
|
||||
return ct.get_type_or_default(node.left, default_typ)
|
||||
}
|
||||
}
|
||||
else {
|
||||
return default_typ
|
||||
}
|
||||
|
@ -925,8 +925,8 @@ fn (mut g Gen) gen_interface_is_op(node ast.InfixExpr) {
|
||||
// infix_expr_arithmetic_op generates code for `+`, `-`, `*`, `/`, and `%`
|
||||
// It handles operator overloading when necessary
|
||||
fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
|
||||
left := g.unwrap(node.left_type)
|
||||
right := g.unwrap(node.right_type)
|
||||
left := g.unwrap(g.comptime.get_type_or_default(node.left, node.left_type))
|
||||
right := g.unwrap(g.comptime.get_type_or_default(node.right, node.right_type))
|
||||
if left.sym.info is ast.Struct && left.sym.info.generic_types.len > 0 {
|
||||
mut method_name := left.sym.cname + '_' + util.replace_op(node.op.str())
|
||||
method_name = g.generic_fn_name(left.sym.info.concrete_types, method_name)
|
||||
@ -1188,7 +1188,11 @@ fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) {
|
||||
&& node.op in [.plus, .minus, .mul, .div, .mod] && !(g.pref.translated
|
||||
|| g.file.is_translated)
|
||||
if needs_cast {
|
||||
typ_str := g.styp(node.promoted_type)
|
||||
typ_str := if g.comptime.is_comptime(node.left) {
|
||||
g.styp(g.comptime.get_type_or_default(node.left, node.promoted_type))
|
||||
} else {
|
||||
g.styp(node.promoted_type)
|
||||
}
|
||||
g.write('(${typ_str})(')
|
||||
}
|
||||
if node.left_type.is_ptr() && node.left.is_auto_deref_var() && !node.right_type.is_pointer() {
|
||||
|
@ -241,7 +241,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||
mut fmts := node_.fmts.clone()
|
||||
for i, mut expr in node_.exprs {
|
||||
if g.comptime.is_comptime(expr) {
|
||||
ctyp := g.comptime.get_type(expr)
|
||||
ctyp := g.comptime.get_type_or_default(expr, node_.expr_types[i])
|
||||
if ctyp != ast.void_type {
|
||||
node_.expr_types[i] = ctyp
|
||||
if node_.fmts[i] == `_` {
|
||||
|
@ -512,7 +512,7 @@ run them via `v file.v` instead',
|
||||
pos: param.pos
|
||||
is_used: is_pub || no_body || (is_method && k == 0) || p.builtin_mod
|
||||
is_arg: true
|
||||
ct_type_var: if (!is_method || k > 0) && param.typ.has_flag(.generic)
|
||||
ct_type_var: if (!is_method || k >= 0) && param.typ.has_flag(.generic)
|
||||
&& !param.typ.has_flag(.variadic) {
|
||||
.generic_param
|
||||
} else {
|
||||
|
12
vlib/v/tests/generics/generic_selector_type_test.v
Normal file
12
vlib/v/tests/generics/generic_selector_type_test.v
Normal file
@ -0,0 +1,12 @@
|
||||
import math.vec
|
||||
|
||||
type UnusedType = vec.Vec3[f32]
|
||||
|
||||
fn (n UnusedType) unused_function() f32 {
|
||||
return n.mul_scalar(2).magnitude()
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
assert vec.Vec3[f32]{0.5, 0.5, 0.5}.magnitude() == f32(0.8660254)
|
||||
assert vec.Vec3[f32]{1.5, 1.5, 1.5}.magnitude() == f32(2.598076)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user