Skip to content

Commit

Permalink
ast,parser,checker: fix identification of abstract vs real interface …
Browse files Browse the repository at this point in the history
…methods (interface with a str() method) (fix #23006) (#23238)
  • Loading branch information
felipensp authored Dec 22, 2024
1 parent 24eac4d commit 7af8faf
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
6 changes: 3 additions & 3 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -1722,8 +1722,8 @@ pub fn (t &TypeSymbol) has_method(name string) bool {
}

pub fn (t &TypeSymbol) has_method_with_generic_parent(name string) bool {
t.find_method_with_generic_parent(name) or { return false }
return true
m := t.find_method_with_generic_parent(name) or { return false }
return t.kind != .interface || !m.no_body
}

pub fn (t &TypeSymbol) find_method(name string) ?Fn {
Expand Down Expand Up @@ -1813,7 +1813,7 @@ pub fn (t &TypeSymbol) str_method_info() (bool, bool, int) {
mut expects_ptr := false
mut nr_args := 0
if sym_str_method := t.find_method_with_generic_parent('str') {
has_str_method = true
has_str_method = t.kind != .interface || !sym_str_method.no_body
nr_args = sym_str_method.params.len
if nr_args > 0 {
expects_ptr = sym_str_method.params[0].typ.is_ptr()
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -2544,7 +2544,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
c.fail_if_unreadable(node.left, left_type, 'receiver')
}
if left_sym.language != .js && (!left_sym.is_builtin() && method.mod != 'builtin')
&& method.language == .v && method.no_body {
&& method.language == .v && final_left_sym.kind != .interface && method.no_body {
c.error('cannot call a method that does not have a body', node.pos)
}
if node.concrete_types.len > 0 && method.generic_names.len > 0
Expand Down
1 change: 1 addition & 0 deletions vlib/v/parser/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
is_pub: true
is_method: true
receiver_type: typ
no_body: true
}
ts.register_method(tmethod)
info.methods << tmethod
Expand Down
25 changes: 25 additions & 0 deletions vlib/v/tests/interfaces/interface_arr_auto_str_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interface Interface {
str() string
}

struct Result[T] {
data []T
}

struct Foobar {
}

fn (f Foobar) str() string {
return 'foobar'
}

fn test_main() {
assert Result[Interface]{}.str() == 'Result[Interface]{
data: []
}'
assert Result[Foobar]{
data: [Foobar{}]
}.str() == 'Result[Foobar]{
data: [foobar]
}'
}

0 comments on commit 7af8faf

Please sign in to comment.