mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
@@ -1212,7 +1212,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||||||
}
|
}
|
||||||
exp_arg_sym := c.table.sym(exp_arg_typ)
|
exp_arg_sym := c.table.sym(exp_arg_typ)
|
||||||
c.expected_type = exp_arg_typ
|
c.expected_type = exp_arg_typ
|
||||||
got_arg_typ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
|
mut got_arg_typ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
|
||||||
node.args[i].typ = got_arg_typ
|
node.args[i].typ = got_arg_typ
|
||||||
if no_type_promotion {
|
if no_type_promotion {
|
||||||
if got_arg_typ != exp_arg_typ {
|
if got_arg_typ != exp_arg_typ {
|
||||||
@@ -1243,10 +1243,29 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if exp_arg_typ.has_flag(.generic) {
|
if exp_arg_typ.has_flag(.generic) {
|
||||||
continue
|
if concrete_types.len == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names,
|
||||||
|
concrete_types)
|
||||||
|
{
|
||||||
|
exp_arg_typ = exp_utyp
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if got_arg_typ.has_flag(.generic) {
|
||||||
|
if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names,
|
||||||
|
concrete_types)
|
||||||
|
{
|
||||||
|
got_arg_typ = got_utyp
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.check_expected_call_arg(got_arg_typ, c.unwrap_generic(exp_arg_typ), node.language,
|
c.check_expected_call_arg(got_arg_typ, exp_arg_typ, node.language, arg) or {
|
||||||
arg) or {
|
|
||||||
// str method, allow type with str method if fn arg is string
|
// str method, allow type with str method if fn arg is string
|
||||||
// Passing an int or a string array produces a c error here
|
// Passing an int or a string array produces a c error here
|
||||||
// Deleting this condition results in propper V error messages
|
// Deleting this condition results in propper V error messages
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
vlib/v/checker/tests/generics_method_called_arg_mismatch.vv:3:15: error: cannot use `Foo` as `Bar` in argument 1 to `Obj.set`
|
||||||
|
1 | fn main() {
|
||||||
|
2 | mut obj := Obj{}
|
||||||
|
3 | obj.set<Bar>(Foo{})
|
||||||
|
| ~~~~~
|
||||||
|
4 | }
|
||||||
|
5 |
|
||||||
14
vlib/v/checker/tests/generics_method_called_arg_mismatch.vv
Normal file
14
vlib/v/checker/tests/generics_method_called_arg_mismatch.vv
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
fn main() {
|
||||||
|
mut obj := Obj{}
|
||||||
|
obj.set<Bar>(Foo{})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo {}
|
||||||
|
|
||||||
|
struct Bar {
|
||||||
|
Foo
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Obj {}
|
||||||
|
|
||||||
|
fn (mut o Obj) set<T>(val T) {}
|
||||||
@@ -15,7 +15,7 @@ fn (ng NestedGeneric) nested_test<T>(mut app T) {
|
|||||||
|
|
||||||
fn method_test<T>(mut app T) int {
|
fn method_test<T>(mut app T) int {
|
||||||
ng := NestedGeneric{}
|
ng := NestedGeneric{}
|
||||||
ng.nested_test<T>(app)
|
ng.nested_test<T>(mut app)
|
||||||
return 22
|
return 22
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user