parent
953057ef35
commit
51258923d7
|
@ -1058,8 +1058,9 @@ pub fn (mut t Table) resolve_generic_by_names(generic_type Type, generic_names [
|
||||||
// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
|
// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
|
||||||
pub fn (mut t Table) resolve_generic_by_types(generic_type Type, generic_types []Type, concrete_types []Type) ?Type {
|
pub fn (mut t Table) resolve_generic_by_types(generic_type Type, generic_types []Type, concrete_types []Type) ?Type {
|
||||||
mut sym := t.get_type_symbol(generic_type)
|
mut sym := t.get_type_symbol(generic_type)
|
||||||
if generic_type in generic_types {
|
gtype := generic_type.set_nr_muls(0) // resolve &T &&T
|
||||||
index := generic_types.index(generic_type)
|
if gtype in generic_types {
|
||||||
|
index := generic_types.index(gtype)
|
||||||
typ := concrete_types[index]
|
typ := concrete_types[index]
|
||||||
return typ.derive(generic_type).clear_flag(.generic)
|
return typ.derive(generic_type).clear_flag(.generic)
|
||||||
} else if sym.kind == .array {
|
} else if sym.kind == .array {
|
||||||
|
|
|
@ -508,6 +508,10 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
|
||||||
if arg.expr.is_auto_deref_var() {
|
if arg.expr.is_auto_deref_var() {
|
||||||
to_set = to_set.deref()
|
to_set = to_set.deref()
|
||||||
}
|
}
|
||||||
|
// resolve &T &&T ...
|
||||||
|
if param.typ.nr_muls() > 0 && to_set.nr_muls() > 0 {
|
||||||
|
to_set = to_set.set_nr_muls(0)
|
||||||
|
}
|
||||||
// If the parent fn param is a generic too
|
// If the parent fn param is a generic too
|
||||||
if to_set.has_flag(.generic) {
|
if to_set.has_flag(.generic) {
|
||||||
to_set = c.unwrap_generic(to_set)
|
to_set = c.unwrap_generic(to_set)
|
||||||
|
|
|
@ -844,7 +844,8 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
|
||||||
|
|
||||||
fn (mut p Parser) check_fn_mutable_arguments(typ ast.Type, pos token.Position) {
|
fn (mut p Parser) check_fn_mutable_arguments(typ ast.Type, pos token.Position) {
|
||||||
sym := p.table.get_type_symbol(typ)
|
sym := p.table.get_type_symbol(typ)
|
||||||
if sym.kind in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_, .sum_type] {
|
if sym.kind in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_,
|
||||||
|
.generic_struct_inst, .sum_type] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if typ.is_ptr() || typ.is_pointer() {
|
if typ.is_ptr() || typ.is_pointer() {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
struct MyStruct<T> {
|
||||||
|
mut:
|
||||||
|
pos int
|
||||||
|
buffer []&T
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut s MyStruct<T>) add<T>(e &T) bool {
|
||||||
|
s.buffer[0] = e
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(mut s MyStruct<i64>) {
|
||||||
|
s.add(&i64(123))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generics_call_with_reference_arg() {
|
||||||
|
mut s := MyStruct<i64>{
|
||||||
|
pos: 1
|
||||||
|
buffer: []&i64{len: 2}
|
||||||
|
}
|
||||||
|
fill(mut s)
|
||||||
|
println(s.pos)
|
||||||
|
assert s.pos == 1
|
||||||
|
println(s.buffer.len)
|
||||||
|
assert s.buffer.len == 2
|
||||||
|
}
|
Loading…
Reference in New Issue