mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
@@ -272,6 +272,27 @@ fn (mut c Checker) resolve_generic_interface(typ ast.Type, interface_type ast.Ty
|
|||||||
ret_typ = ret_typ.clear_flag(.optional)
|
ret_typ = ret_typ.clear_flag(.optional)
|
||||||
}
|
}
|
||||||
inferred_type = ret_typ
|
inferred_type = ret_typ
|
||||||
|
} else if imret_sym.info is ast.SumType && mret_sym.info is ast.SumType {
|
||||||
|
im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name)
|
||||||
|
if gt_name in im_generic_names
|
||||||
|
&& imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len {
|
||||||
|
idx := im_generic_names.index(gt_name)
|
||||||
|
inferred_type = mret_sym.info.concrete_types[idx]
|
||||||
|
}
|
||||||
|
} else if imret_sym.info is ast.Interface && mret_sym.info is ast.Interface {
|
||||||
|
im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name)
|
||||||
|
if gt_name in im_generic_names
|
||||||
|
&& imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len {
|
||||||
|
idx := im_generic_names.index(gt_name)
|
||||||
|
inferred_type = mret_sym.info.concrete_types[idx]
|
||||||
|
}
|
||||||
|
} else if imret_sym.info is ast.Struct && mret_sym.info is ast.Struct {
|
||||||
|
im_generic_names := imret_sym.info.generic_types.map(c.table.sym(it).name)
|
||||||
|
if gt_name in im_generic_names
|
||||||
|
&& imret_sym.info.generic_types.len == mret_sym.info.concrete_types.len {
|
||||||
|
idx := im_generic_names.index(gt_name)
|
||||||
|
inferred_type = mret_sym.info.concrete_types[idx]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, iparam in imethod.params {
|
for i, iparam in imethod.params {
|
||||||
|
81
vlib/v/tests/generics_interface_with_generic_sumtype_test.v
Normal file
81
vlib/v/tests/generics_interface_with_generic_sumtype_test.v
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// optional.v
|
||||||
|
struct NonValue {}
|
||||||
|
|
||||||
|
pub type Optional<T> = NonValue | T
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) is_some<T>() bool {
|
||||||
|
return self is T
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) is_none<T>() bool {
|
||||||
|
return !self.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) expect<T>(msg string) T {
|
||||||
|
if self.is_some() {
|
||||||
|
return self as T
|
||||||
|
} else {
|
||||||
|
panic(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) unwrap<T>() T {
|
||||||
|
return self.expect('unwrap on a none value')
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) unwrap_or<T>(default T) T {
|
||||||
|
if self.is_some() {
|
||||||
|
return self as T
|
||||||
|
} else {
|
||||||
|
return default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Optional<T>) unwrap_or_else<T>(else_fn fn () T) T {
|
||||||
|
if self.is_some() {
|
||||||
|
return self as T
|
||||||
|
} else {
|
||||||
|
return else_fn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn some<T>(value T) Optional<T> {
|
||||||
|
return Optional<T>(value as T)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn null<T>() Optional<T> {
|
||||||
|
return Optional<T>(NonValue{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// iter.v
|
||||||
|
pub interface Iterator<T> {
|
||||||
|
mut:
|
||||||
|
next() Optional<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self Iterator<T>) count<T>() int {
|
||||||
|
mut count := 0
|
||||||
|
for self.next().is_some() {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EmptyIter<T> {
|
||||||
|
value NonValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut self EmptyIter<T>) next<T>() Optional<T> {
|
||||||
|
return Optional<T>(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// iter_test.v
|
||||||
|
fn test_generics_interface_with_generic_sumtype() {
|
||||||
|
mut iter1 := EmptyIter<u32>{}
|
||||||
|
println(iter1)
|
||||||
|
assert iter1.next().is_none()
|
||||||
|
|
||||||
|
mut iter2 := Iterator<u32>(iter1)
|
||||||
|
println(iter2)
|
||||||
|
assert iter2.count() == 0
|
||||||
|
}
|
Reference in New Issue
Block a user