checker: fix generics return generic struct (#9663)
parent
1bcc45f914
commit
cf64001474
|
@ -1446,6 +1446,8 @@ fn (mut c Checker) check_return_generics_struct(return_type ast.Type, mut call_e
|
||||||
}
|
}
|
||||||
mut info := rts.info
|
mut info := rts.info
|
||||||
info.generic_types = []
|
info.generic_types = []
|
||||||
|
info.concrete_types = generic_types.clone()
|
||||||
|
info.parent_type = return_type
|
||||||
info.fields = fields
|
info.fields = fields
|
||||||
stru_idx := c.table.register_type_symbol(ast.TypeSymbol{
|
stru_idx := c.table.register_type_symbol(ast.TypeSymbol{
|
||||||
kind: .struct_
|
kind: .struct_
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
pub struct Optional<T> {
|
pub struct Optional<T> {
|
||||||
mut:
|
mut:
|
||||||
value T
|
value T
|
||||||
some bool
|
some bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_some<T>(value T) Optional<T> {
|
pub fn new_some<T>(value T) Optional<T> {
|
||||||
return {value: value, some: true}
|
return {
|
||||||
|
value: value
|
||||||
|
some: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn some<T>(opt Optional<T>) bool {
|
pub fn some<T>(opt Optional<T>) bool {
|
||||||
|
@ -36,19 +39,22 @@ pub struct Foo {
|
||||||
foo int
|
foo int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f Foo)new_some<T>(value T) Optional<T> {
|
pub fn (f Foo) new_some<T>(value T) Optional<T> {
|
||||||
return {value: value, some: true}
|
return {
|
||||||
|
value: value
|
||||||
|
some: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f Foo)some<T>(opt Optional<T>) bool {
|
pub fn (f Foo) some<T>(opt Optional<T>) bool {
|
||||||
return opt.some
|
return opt.some
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f Foo)get<T>(opt Optional<T>) T {
|
pub fn (f Foo) get<T>(opt Optional<T>) T {
|
||||||
return opt.value
|
return opt.value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f Foo)set<T>(mut opt Optional<T>, value T) {
|
pub fn (f Foo) set<T>(mut opt Optional<T>, value T) {
|
||||||
opt.value = value
|
opt.value = value
|
||||||
opt.some = true
|
opt.some = true
|
||||||
}
|
}
|
||||||
|
@ -71,11 +77,14 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter<T>(arr []T) ArrayIterator<T> {
|
pub fn iter<T>(arr []T) ArrayIterator<T> {
|
||||||
return ArrayIterator{data: arr, index: 11}
|
return ArrayIterator{
|
||||||
|
data: arr
|
||||||
|
index: 11
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_generics_with_generics_struct_string() {
|
fn test_generics_with_generics_struct_string() {
|
||||||
data := ['foo' 'bar']
|
data := ['foo', 'bar']
|
||||||
it := iter<string>(data)
|
it := iter<string>(data)
|
||||||
println(it)
|
println(it)
|
||||||
ret := '$it'
|
ret := '$it'
|
||||||
|
@ -86,7 +95,7 @@ fn test_generics_with_generics_struct_string() {
|
||||||
|
|
||||||
fn test_generics_struct_insts_to_concrete() {
|
fn test_generics_struct_insts_to_concrete() {
|
||||||
ai := ArrayIterator<int>{
|
ai := ArrayIterator<int>{
|
||||||
data: [11, 22],
|
data: [11, 22]
|
||||||
index: 22
|
index: 22
|
||||||
}
|
}
|
||||||
println(ai)
|
println(ai)
|
||||||
|
@ -95,3 +104,23 @@ fn test_generics_struct_insts_to_concrete() {
|
||||||
assert ret.contains('data: [11, 22]')
|
assert ret.contains('data: [11, 22]')
|
||||||
assert ret.contains('index: 22')
|
assert ret.contains('index: 22')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Iterator<T> {
|
||||||
|
data []T
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut i Iterator<T>) next<T>() ?T {
|
||||||
|
return i.data[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_data<T>(data []T) Iterator<T> {
|
||||||
|
return Iterator{
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generics_return_generic_struct_from_fn() {
|
||||||
|
mut it := iter_data<int>([1, 2, 3])
|
||||||
|
println(it.next())
|
||||||
|
assert '$it.next()' == 'Option(1)'
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue