mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
f36e46bfde
commit
212b4fa089
@ -62,16 +62,28 @@ pub fn (node &FnDecl) stringify(t &Table, cur_mod string, m2a map[string]string)
|
||||
if name in ['+', '-', '*', '/', '%', '<', '>', '==', '!=', '>=', '<='] {
|
||||
f.write_string(' ')
|
||||
}
|
||||
mut add_para_types := true
|
||||
if node.generic_names.len > 0 {
|
||||
f.write_string('<')
|
||||
for i, gname in node.generic_names {
|
||||
is_last := i == node.generic_names.len - 1
|
||||
f.write_string(gname)
|
||||
if !is_last {
|
||||
f.write_string(', ')
|
||||
if node.is_method {
|
||||
sym := t.get_type_symbol(node.params[0].typ)
|
||||
if sym.info is Struct {
|
||||
generic_names := sym.info.generic_types.map(t.get_type_symbol(it).name)
|
||||
if generic_names == node.generic_names {
|
||||
add_para_types = false
|
||||
}
|
||||
}
|
||||
}
|
||||
f.write_string('>')
|
||||
if add_para_types {
|
||||
f.write_string('<')
|
||||
for i, gname in node.generic_names {
|
||||
is_last := i == node.generic_names.len - 1
|
||||
f.write_string(gname)
|
||||
if !is_last {
|
||||
f.write_string(', ')
|
||||
}
|
||||
}
|
||||
f.write_string('>')
|
||||
}
|
||||
}
|
||||
f.write_string('(')
|
||||
for i, arg in node.params {
|
||||
|
@ -273,12 +273,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
}
|
||||
}
|
||||
// <T>
|
||||
generic_names := p.parse_generic_names()
|
||||
// check generic receiver method has no generic names
|
||||
if is_method && rec.typ.has_flag(.generic) && generic_names.len == 0
|
||||
&& p.table.get_type_symbol(rec.typ).kind != .any {
|
||||
p.error_with_pos('generic receiver method `$name` should add generic names, e.g. $name<T>',
|
||||
name_pos)
|
||||
mut generic_names := p.parse_generic_names()
|
||||
// generic names can be infer with receiver's generic names
|
||||
if is_method && rec.typ.has_flag(.generic) && generic_names.len == 0 {
|
||||
sym := p.table.get_type_symbol(rec.typ)
|
||||
if sym.info is ast.Struct {
|
||||
generic_names = sym.info.generic_types.map(p.table.get_type_symbol(it).name)
|
||||
}
|
||||
}
|
||||
// Args
|
||||
args2, are_args_type_only, is_variadic := p.fn_args()
|
||||
|
@ -1,7 +0,0 @@
|
||||
vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.vv:6:20: error: generic receiver method `poll` should add generic names, e.g. poll<T>
|
||||
4 | }
|
||||
5 |
|
||||
6 | fn (q Queue<A, B>) poll() A {
|
||||
| ~~~~
|
||||
7 | return q.buffer[0]
|
||||
8 | }
|
@ -1,13 +0,0 @@
|
||||
struct Queue<A, B>{
|
||||
buffer []A
|
||||
size B
|
||||
}
|
||||
|
||||
fn (q Queue<A, B>) poll() A {
|
||||
return q.buffer[0]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
q := Queue<string, int>{}
|
||||
println(q)
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.vv:5:17: error: generic receiver method `poll` should add generic names, e.g. poll<T>
|
||||
3 | }
|
||||
4 |
|
||||
5 | fn (q Queue<T>) poll() T {
|
||||
| ~~~~
|
||||
6 | return q.buffer[0]
|
||||
7 | }
|
@ -1,12 +0,0 @@
|
||||
struct Queue<T>{
|
||||
buffer []T
|
||||
}
|
||||
|
||||
fn (q Queue<T>) poll() T {
|
||||
return q.buffer[0]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
q := Queue<int>{}
|
||||
println(q)
|
||||
}
|
@ -4,7 +4,7 @@ mut:
|
||||
buffer []&T
|
||||
}
|
||||
|
||||
fn (mut s MyStruct<T>) add<T>(e &T) bool {
|
||||
fn (mut s MyStruct<T>) add(e &T) bool {
|
||||
s.buffer[0] = e
|
||||
return true
|
||||
}
|
||||
|
13
vlib/v/tests/generics_method_on_receiver_types_test.v
Normal file
13
vlib/v/tests/generics_method_on_receiver_types_test.v
Normal file
@ -0,0 +1,13 @@
|
||||
struct Abc<T> {
|
||||
value T
|
||||
}
|
||||
|
||||
fn (s Abc<T>) get_value() T {
|
||||
return s.value
|
||||
}
|
||||
|
||||
fn test_generics_method_on_receiver_types() {
|
||||
s := Abc<string>{'hello'}
|
||||
println(s.get_value())
|
||||
assert s.get_value() == 'hello'
|
||||
}
|
@ -18,7 +18,7 @@ fn group_new<T>(val ...T) Group<T> {
|
||||
return g
|
||||
}
|
||||
|
||||
fn (mut it Group<T>) next<T>() ?T {
|
||||
fn (mut it Group<T>) next() ?T {
|
||||
if it.index >= it.len {
|
||||
return none
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ struct Num<T> {
|
||||
num T
|
||||
}
|
||||
|
||||
fn (num Num<T>) is_autom<T>() bool {
|
||||
fn (num Num<T>) is_autom() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ struct Foo<A, B> {
|
||||
b B
|
||||
}
|
||||
|
||||
fn (num Foo<A, B>) get_foo1<A, B>() (A, B) {
|
||||
fn (num Foo<A, B>) get_foo1() (A, B) {
|
||||
return num.a, num.b
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user