v.checker: fix multi insts of generics fn with generic struct (#11161)

pull/11155/head^2
yuyi 2021-08-13 03:58:02 +08:00 committed by GitHub
parent 576664e31f
commit 579aa7b1b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 45 additions and 28 deletions

View File

@ -960,7 +960,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
unwrapped_struct_type := c.unwrap_generic_type(node.typ, c.table.cur_fn.generic_names,
c.table.cur_concrete_types)
c.ensure_type_exists(unwrapped_struct_type, node.pos) or {}
type_sym := c.table.get_type_symbol(unwrapped_struct_type)
type_sym := c.table.get_type_symbol(node.typ)
if !c.inside_unsafe && type_sym.kind == .sum_type {
c.note('direct sum type init (`x := SumType{}`) will be removed soon', node.pos)
}
@ -1091,7 +1091,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
if is_embed {
expected_type = embed_type
c.expected_type = expected_type
expr_type = c.unwrap_generic(c.expr(field.expr))
expr_type = c.expr(field.expr)
expr_type_sym := c.table.get_type_symbol(expr_type)
if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
c.check_expected(expr_type, embed_type) or {
@ -1106,7 +1106,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
field_type_sym := c.table.get_type_symbol(field_info.typ)
expected_type = field_info.typ
c.expected_type = expected_type
expr_type = c.unwrap_generic(c.expr(field.expr))
expr_type = c.expr(field.expr)
if !field_info.typ.has_flag(.optional) {
expr_type = c.check_expr_opt_call(field.expr, expr_type)
}
@ -1228,7 +1228,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
c.error('expression is not an lvalue', node.update_expr.position())
}
}
return unwrapped_struct_type
return node.typ
}
fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {

View File

@ -12,3 +12,10 @@ vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:32:1: error: g
| ~~~~~~~~~~~~~~
33 | println("hi")
34 | }
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:23:9: error: cannot use `Generic` as type `Generic<Concrete>` in return argument
21 | go g_worker(g)
22 |
23 | return g
| ^
24 | }
25 |

View File

@ -5,9 +5,3 @@ vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv:13:32: error: retu
| ~~~~~~~~~~~~~~~~~~~~
14 | d := GenericChannelStruct{
15 | ch: chan T{}
vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv:17:9: error: cannot use `GenericChannelStruct<Simple>` as type `GenericChannelStruct` in return argument
15 | ch: chan T{}
16 | }
17 | return d
| ^
18 | }

View File

@ -16,7 +16,7 @@ fn main() {
}
pub fn new_channel_struct<T>() GenericChannelStruct<T> {
d := GenericChannelStruct{
d := GenericChannelStruct<T>{
ch: chan T{}
}

View File

@ -3,7 +3,7 @@ struct Test<T> {
}
fn get_test<T>(v T) Test<T> {
return Test{
return Test<T>{
v: v
}
}

View File

@ -6,7 +6,7 @@ mut:
}
pub fn new_some<T>(value T) Optional<T> {
return Optional{
return Optional<T>{
value: value
some: true
}
@ -40,7 +40,7 @@ pub struct Foo {
}
pub fn (f Foo) new_some<T>(value T) Optional<T> {
return Optional{
return Optional<T>{
value: value
some: true
}
@ -77,7 +77,7 @@ mut:
}
pub fn iter<T>(arr []T) ArrayIterator<T> {
return ArrayIterator{
return ArrayIterator<T>{
data: arr
index: 11
}
@ -114,7 +114,7 @@ pub fn (mut i Iterator<T>) next<T>() ?T {
}
pub fn iter_data<T>(data []T) Iterator<T> {
return Iterator{
return Iterator<T>{
data: data
}
}

View File

@ -7,7 +7,7 @@ mut:
}
pub fn new_some<T, B>(value T, b B) Optional<T> {
return Optional{
return Optional<T>{
value: value
some: true
typ: typeof(b).name
@ -54,7 +54,7 @@ pub struct Foo {
}
pub fn (f Foo) new_some<T, B>(value T, b B) Optional<T> {
return Optional{
return Optional<T>{
value: value
some: true
typ: typeof(b).name

View File

@ -5,7 +5,7 @@ mut:
}
fn new_foo<A, B>(a A, b B) Foo<A, B> {
return Foo{
return Foo<A,B>{
a: a
b: b
}

View File

@ -5,7 +5,7 @@ mut:
}
fn make_node<T>(val []T) Node<T> {
return Node{
return Node<T>{
val: val[0]
next: 0
}

View File

@ -3,7 +3,7 @@ struct Foo<T> {
}
fn new_foo<T>(len int) &Foo<T> {
return &Foo{
return &Foo<T>{
data: []T{len: len}
}
}

View File

@ -10,7 +10,7 @@ fn group_new<T>(val ...T) Group<T> {
for i in val {
arr << i
}
mut g := Group{
mut g := Group<T>{
len: val.len
val: arr
}

View File

@ -13,11 +13,11 @@ mut:
fn create<T>(arr []T) &List<T> {
assert arr.len > 0
mut n := &ListNode{
mut n := &ListNode<T>{
val: arr[0]
next: 0
}
mut l := &List{
mut l := &List<T>{
first: n
last: n
count: 1
@ -26,7 +26,23 @@ fn create<T>(arr []T) &List<T> {
}
fn test_generics_with_generic_structs_init() {
n := create([1, 2, 3])
println(n)
assert n.count == 1
list1 := create([1, 2, 3])
println(list1)
assert list1.count == 1
assert list1.first.val == 1
list2 := create(['a', 'b', 'c'])
println(list2)
assert list2.count == 1
assert list2.first.val == 'a'
list3 := create([1.1, 2.2, 3.3])
println(list3)
assert list3.count == 1
assert list3.first.val == 1.1
list4 := create([true, false, true])
println(list4)
assert list4.count == 1
assert list4.first.val == true
}

View File

@ -17,7 +17,7 @@ fn init_singlylinkedlist<T>(nodes ...Node<T>) SinglyLinkedList<T> {
current_node.next = &nodes[i + 1]
}
return SinglyLinkedList{&nodes[0]}
return SinglyLinkedList<T>{&nodes[0]}
}
fn test_generic_with_variadic_generic_args() {