checker: check generic struct init without type parameter (#13404)
parent
356ccf247f
commit
4be3c92640
|
@ -46,7 +46,7 @@ pub fn (list DoublyLinkedList<T>) last() ?T {
|
|||
|
||||
// push_back adds an element to the end of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
|
||||
mut new_node := &DoublyListNode{
|
||||
mut new_node := &DoublyListNode<T>{
|
||||
data: item
|
||||
}
|
||||
if list.is_empty() {
|
||||
|
@ -63,7 +63,7 @@ pub fn (mut list DoublyLinkedList<T>) push_back(item T) {
|
|||
|
||||
// push_front adds an element to the beginning of the linked list
|
||||
pub fn (mut list DoublyLinkedList<T>) push_front(item T) {
|
||||
mut new_node := &DoublyListNode{
|
||||
mut new_node := &DoublyListNode<T>{
|
||||
data: item
|
||||
}
|
||||
if list.is_empty() {
|
||||
|
@ -149,7 +149,7 @@ fn (mut list DoublyLinkedList<T>) insert_back(idx int, item T) {
|
|||
// |next|---->|next|
|
||||
// |prev|<----|prev|
|
||||
// ------ ------
|
||||
new := &DoublyListNode{
|
||||
new := &DoublyListNode<T>{
|
||||
data: item
|
||||
next: node
|
||||
prev: prev
|
||||
|
@ -176,7 +176,7 @@ fn (mut list DoublyLinkedList<T>) insert_front(idx int, item T) {
|
|||
// |next|---->|next|
|
||||
// |prev|<----|prev|
|
||||
// ------ ------
|
||||
new := &DoublyListNode{
|
||||
new := &DoublyListNode<T>{
|
||||
data: item
|
||||
next: next
|
||||
prev: node
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn (list LinkedList<T>) index(idx int) ?T {
|
|||
|
||||
// push adds an element to the end of the linked list
|
||||
pub fn (mut list LinkedList<T>) push(item T) {
|
||||
new_node := &ListNode{
|
||||
new_node := &ListNode<T>{
|
||||
data: item
|
||||
}
|
||||
if list.head == 0 {
|
||||
|
@ -124,7 +124,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
|||
|
||||
if idx == 0 {
|
||||
// first node case
|
||||
list.head = &ListNode{
|
||||
list.head = &ListNode<T>{
|
||||
data: item
|
||||
next: node
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ pub fn (mut list LinkedList<T>) insert(idx int, item T) ? {
|
|||
for i := 0; i < idx - 1; i++ {
|
||||
node = node.next
|
||||
}
|
||||
node.next = &ListNode{
|
||||
node.next = &ListNode<T>{
|
||||
data: item
|
||||
next: node.next
|
||||
}
|
||||
|
|
|
@ -400,6 +400,7 @@ pub:
|
|||
pos token.Pos
|
||||
name_pos token.Pos
|
||||
is_short bool
|
||||
is_short_syntax bool
|
||||
pub mut:
|
||||
unresolved bool
|
||||
pre_comments []Comment
|
||||
|
|
|
@ -131,9 +131,14 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
struct_sym := c.table.sym(node.typ)
|
||||
if struct_sym.info is ast.Struct {
|
||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||
&& c.table.cur_concrete_types.len == 0 {
|
||||
&& !node.is_short_syntax {
|
||||
if c.table.cur_concrete_types.len == 0 {
|
||||
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
|
||||
node.pos)
|
||||
} else if node.generic_types.len == 0 {
|
||||
c.error('generic struct init must specify type parameter, e.g. Foo<T>',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
if node.generic_types.len > 0 && struct_sym.info.generic_types != node.generic_types {
|
||||
c.table.replace_generic_type(node.typ, node.generic_types)
|
||||
|
|
|
@ -12,10 +12,4 @@ 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 |
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn create_generic_t<T>() Generic<T> {
|
||||
g := Generic{
|
||||
g := Generic<T>{
|
||||
ch: chan T{}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,3 +5,10 @@ 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:14:7: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
12 |
|
||||
13 | pub fn new_channel_struct<T>() GenericChannelStruct {
|
||||
14 | d := GenericChannelStruct{
|
||||
| ~~~~~~~~~~~~~~~~~~~~~
|
||||
15 | ch: chan T{}
|
||||
16 | }
|
||||
|
|
|
@ -12,3 +12,45 @@ vlib/v/checker/tests/generics_struct_init_err.vv:67:8: error: generic struct ini
|
|||
| ~~~~~~~~~~~~~~
|
||||
68 | assert ret == -6
|
||||
69 | }
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:22:7: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
20 |
|
||||
21 | fn holder_call_1<T>(func T, a int) int {
|
||||
22 | h := FnHolder1{func}
|
||||
| ~~~~~~~~~~~~~~~
|
||||
23 | return h.call(a)
|
||||
24 | }
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:27:7: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
25 |
|
||||
26 | fn holder_call_2<T>(func T, a int) int {
|
||||
27 | h := FnHolder2{func}
|
||||
| ~~~~~~~~~~~~~~~
|
||||
28 | return h.call(a)
|
||||
29 | }
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:33:7: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
31 | fn holder_call_11<T>(func T, a int) int {
|
||||
32 | f := func
|
||||
33 | h := FnHolder1{f}
|
||||
| ~~~~~~~~~~~~
|
||||
34 | return h.call(a)
|
||||
35 | }
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:39:7: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
37 | fn holder_call_21<T>(func T, a int) int {
|
||||
38 | f := func
|
||||
39 | h := FnHolder2{f}
|
||||
| ~~~~~~~~~~~~
|
||||
40 | return h.call(a)
|
||||
41 | }
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:44:9: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
42 |
|
||||
43 | fn holder_call_12<T>(func T, a int) int {
|
||||
44 | return FnHolder1{func}.call(a)
|
||||
| ~~~~~~~~~~~~~~~
|
||||
45 | }
|
||||
46 |
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:48:9: error: generic struct init must specify type parameter, e.g. Foo<T>
|
||||
46 |
|
||||
47 | fn holder_call_22<T>(func T, a int) int {
|
||||
48 | return FnHolder2{func}.call(a)
|
||||
| ~~~~~~~~~~~~~~~
|
||||
49 | }
|
||||
50 |
|
||||
|
|
|
@ -426,6 +426,7 @@ fn (mut p Parser) struct_init(typ_str string, short_syntax bool) ast.StructInit
|
|||
name_pos: first_pos
|
||||
pos: first_pos.extend(if short_syntax { p.tok.pos() } else { p.prev_tok.pos() })
|
||||
is_short: no_keys
|
||||
is_short_syntax: short_syntax
|
||||
pre_comments: pre_comments
|
||||
generic_types: p.struct_init_generic_types
|
||||
}
|
||||
|
|
|
@ -19,33 +19,33 @@ fn (self FnHolder2<T>) call(a int) int {
|
|||
}
|
||||
|
||||
fn holder_call_1<T>(func T, a int) int {
|
||||
h := FnHolder1{func}
|
||||
h := FnHolder1<T>{func}
|
||||
return h.call(a)
|
||||
}
|
||||
|
||||
fn holder_call_2<T>(func T, a int) int {
|
||||
h := FnHolder2{func}
|
||||
h := FnHolder2<T>{func}
|
||||
return h.call(a)
|
||||
}
|
||||
|
||||
fn holder_call_11<T>(func T, a int) int {
|
||||
f := func
|
||||
h := FnHolder1{f}
|
||||
h := FnHolder1<T>{f}
|
||||
return h.call(a)
|
||||
}
|
||||
|
||||
fn holder_call_21<T>(func T, a int) int {
|
||||
f := func
|
||||
h := FnHolder2{f}
|
||||
h := FnHolder2<T>{f}
|
||||
return h.call(a)
|
||||
}
|
||||
|
||||
fn holder_call_12<T>(func T, a int) int {
|
||||
return FnHolder1{func}.call(a)
|
||||
return FnHolder1<T>{func}.call(a)
|
||||
}
|
||||
|
||||
fn holder_call_22<T>(func T, a int) int {
|
||||
return FnHolder2{func}.call(a)
|
||||
return FnHolder2<T>{func}.call(a)
|
||||
}
|
||||
|
||||
fn test_generic_struct_with_anon_fn_parameter() {
|
||||
|
|
Loading…
Reference in New Issue