Skip to content

Commit 836524e

Browse files
authored
v.generics: improve the new generic stage, pass more tests (#26376)
1 parent 8bc4ab8 commit 836524e

File tree

3 files changed

+121
-7
lines changed

3 files changed

+121
-7
lines changed

vlib/v/comptime/comptime.v

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,13 @@ pub fn (mut c Comptime) is_true(expr ast.Expr) !bool {
154154
}
155155
// TODO do the other types
156156
} else if expr.right is ast.TypeNode {
157-
return expr.left.typ == expr.right.typ
157+
sym := c.table.sym(expr.right.typ)
158+
if sym.info is ast.Interface {
159+
return c.table.does_type_implement_interface(expr.left.typ,
160+
expr.right.typ)
161+
} else {
162+
return expr.left.typ == expr.right.typ
163+
}
158164
}
159165
} else if expr.left is ast.SelectorExpr {
160166
if expr.left.field_name == 'typ' && expr.left.expr is ast.Ident {
@@ -386,6 +392,14 @@ pub fn (mut c Comptime) expr(mut node ast.Expr) ast.Expr {
386392
}
387393
}
388394
ast.SelectorExpr {
395+
if c.pref.new_generic_solver && node.gkind_field == .name && node.field_name == 'name' {
396+
if mut node.expr is ast.Ident {
397+
return ast.Expr(ast.StringLiteral{
398+
val: node.expr.name
399+
pos: node.pos
400+
})
401+
}
402+
}
389403
node.expr = c.expr(mut node.expr)
390404
}
391405
ast.SizeOf {

vlib/v/gen/c/cgen.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8302,7 +8302,7 @@ return ${cast_shared_struct_str};
83028302
method_names := methods.map(it.name)
83038303
match st_sym.info {
83048304
ast.Struct, ast.Interface, ast.SumType {
8305-
if st_sym.info.parent_type.has_flag(.generic) {
8305+
if st_sym.info.parent_type.has_flag(.generic) && !g.pref.new_generic_solver {
83068306
parent_sym := g.table.sym(st_sym.info.parent_type)
83078307
for method in parent_sym.methods {
83088308
if method.name in methodidx {

vlib/v/generics/generics.v

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,34 @@ fn (mut g Generics) cc_type(typ ast.Type, is_prefix_struct bool) string {
382382
return styp
383383
}
384384

385+
pub fn (mut g Generics) method_concrete_name(old_name string, concrete_types []ast.Type, receiver_type ast.Type) string {
386+
mut name := old_name
387+
if receiver_type != 0 {
388+
info := g.table.sym(g.unwrap_generic(receiver_type)).info
389+
if info is ast.Struct {
390+
fn_conc_types := concrete_types[info.generic_types.len..] // concrete types without the generic types of the struct
391+
392+
if fn_conc_types.len > 0 {
393+
name += '_T'
394+
}
395+
for typ in fn_conc_types {
396+
name += '_' + strings.repeat_string('__ptr__', typ.nr_muls()) +
397+
g.styp(typ.set_nr_muls(0))
398+
}
399+
return name
400+
} else if info is ast.Interface {
401+
return name
402+
}
403+
}
404+
if concrete_types.len > 0 {
405+
name += '_T'
406+
}
407+
for typ in concrete_types {
408+
name += '_' + strings.repeat_string('__ptr__', typ.nr_muls()) + g.styp(typ.set_nr_muls(0))
409+
}
410+
return name
411+
}
412+
385413
pub fn (mut g Generics) concrete_name(old_name string, concrete_types []ast.Type) string {
386414
mut name := old_name
387415
if concrete_types.len > 0 {
@@ -409,12 +437,50 @@ pub fn (mut g Generics) generic_fn_decl(mut node ast.FnDecl) []ast.Stmt {
409437
...node
410438
}
411439
new_node = g.stmt(mut new_node) as ast.FnDecl
412-
solved_fns << ast.FnDecl{
440+
new_node = ast.FnDecl{
413441
...new_node
414-
name: g.concrete_name(new_node.name, concrete_types)
442+
name: if node.is_method {
443+
g.method_concrete_name(new_node.name, concrete_types, new_node.receiver.typ)
444+
} else {
445+
g.concrete_name(new_node.name, concrete_types)
446+
}
415447
ninstances: 0
416448
generic_names: []
417449
}
450+
if new_node.is_method {
451+
mut sym := g.table.sym(new_node.receiver.typ)
452+
func := ast.Fn{
453+
is_variadic: new_node.is_variadic
454+
is_c_variadic: new_node.is_c_variadic
455+
language: .v
456+
is_pub: new_node.is_pub
457+
is_deprecated: new_node.is_deprecated
458+
is_noreturn: new_node.is_noreturn
459+
is_unsafe: new_node.is_unsafe
460+
is_must_use: new_node.is_must_use
461+
is_keep_alive: new_node.is_keep_alive
462+
is_method: new_node.is_method
463+
is_static_type_method: new_node.is_static_type_method
464+
no_body: new_node.no_body
465+
is_file_translated: new_node.is_file_translated
466+
mod: new_node.mod
467+
file: new_node.file
468+
file_mode: new_node.file_mode
469+
pos: new_node.pos
470+
return_type_pos: new_node.return_type_pos
471+
return_type: new_node.return_type
472+
receiver_type: new_node.receiver.typ
473+
name: new_node.name
474+
params: new_node.params
475+
generic_names: []
476+
is_conditional: new_node.is_conditional
477+
ctdefine_idx: new_node.ctdefine_idx
478+
is_expand_simple_interpolation: new_node.is_expand_simple_interpolation
479+
}
480+
g.table.find_or_register_fn_type(func, false, true)
481+
sym.register_method(func)
482+
}
483+
solved_fns << new_node
418484
}
419485
g.cur_concrete_types = []
420486
return solved_fns
@@ -521,7 +587,11 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
521587
}
522588
return ast.Expr(ast.CallExpr{
523589
...node
524-
name: g.concrete_name(node.name, all_concrete_types)
590+
name: if node.is_method {
591+
g.method_concrete_name(node.name, all_concrete_types, node.receiver_type)
592+
} else {
593+
g.concrete_name(node.name, all_concrete_types)
594+
}
525595
left_type: g.unwrap_generic(node.left_type)
526596
receiver_type: g.unwrap_generic(node.receiver_type)
527597
return_type: g.unwrap_generic(node.return_type)
@@ -550,7 +620,11 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
550620
func.generic_names, node.concrete_types) or { it })
551621
}
552622
}
553-
node.name = g.concrete_name(node.name, node.concrete_types)
623+
node.name = if node.is_method {
624+
g.method_concrete_name(node.name, node.concrete_types, node.receiver_type)
625+
} else {
626+
g.concrete_name(node.name, node.concrete_types)
627+
}
554628
return ast.Expr(ast.CallExpr{
555629
...node
556630
concrete_types: []
@@ -700,6 +774,33 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
700774
})
701775
}
702776
}
777+
ast.EmptyScopeObject {
778+
if g.cur_concrete_types.len > 0 {
779+
mut typ := node.obj.typ
780+
mut name := node.name
781+
if typ == 0 {
782+
if g.cur_fn != unsafe { nil } {
783+
idx := g.cur_fn.generic_names.index(node.name)
784+
if idx != -1 {
785+
typ = g.cur_concrete_types[idx]
786+
name = g.table.type_str(typ)
787+
}
788+
}
789+
} else {
790+
typ = g.unwrap_generic(typ)
791+
name = g.table.type_str(typ)
792+
}
793+
return ast.Expr(ast.Ident{
794+
...node
795+
obj: ast.EmptyScopeObject{
796+
...node.obj
797+
typ: typ
798+
name: name
799+
}
800+
name: name
801+
})
802+
}
803+
}
703804
else {}
704805
}
705806
}
@@ -917,7 +1018,6 @@ pub fn (mut g Generics) expr(mut node ast.Expr) ast.Expr {
9171018
typ: g.unwrap_generic(node.typ)
9181019
name_type: g.unwrap_generic(node.name_type)
9191020
from_embed_types: node.from_embed_types.map(g.unwrap_generic(it))
920-
gkind_field: .unknown
9211021
})
9221022
}
9231023
node.expr = g.expr(mut node.expr)

0 commit comments

Comments
 (0)