v.checker: add checks for `.free()` methods

pull/11430/head
Delyan Angelov 2021-09-09 09:15:21 +03:00
parent 72089c4feb
commit 4faa0f8487
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
6 changed files with 68 additions and 12 deletions

View File

@ -234,7 +234,7 @@ pub fn (mut a array) delete_last() {
}
[unsafe]
pub fn (a array) free() {
pub fn (a &array) free() {
}
// todo: once (a []byte) will work rewrite this

View File

@ -140,7 +140,7 @@ pub fn (s string) find_between(start string, end string) string {
}
// unnecessary in the JS backend, implemented for api parity.
pub fn (s string) free() {}
pub fn (s &string) free() {}
pub fn (s string) hash() int {
mut h := u32(0)

View File

@ -94,8 +94,8 @@ pub:
id u32
}
pub fn (p C.sg_pipeline) free() {
C.sg_destroy_pipeline(p)
pub fn (mut p C.sg_pipeline) free() {
C.sg_destroy_pipeline(*p)
}
pub struct C.sg_bindings {
@ -276,8 +276,8 @@ pub:
id u32
}
pub fn (s C.sg_shader) free() {
C.sg_destroy_shader(s)
pub fn (mut s C.sg_shader) free() {
C.sg_destroy_shader(*s)
}
pub struct C.sg_pass_desc {
@ -306,8 +306,8 @@ pub struct C.sg_pass {
id u32
}
pub fn (p C.sg_pass) free() {
C.sg_destroy_pass(p)
pub fn (mut p C.sg_pass) free() {
C.sg_destroy_pass(*p)
}
pub struct C.sg_buffer_desc {
@ -334,8 +334,8 @@ pub struct C.sg_buffer {
id u32
}
pub fn (b C.sg_buffer) free() {
C.sg_destroy_buffer(b)
pub fn (mut b C.sg_buffer) free() {
C.sg_destroy_buffer(*b)
}
pub struct DepthLayers {
@ -392,8 +392,8 @@ pub:
id u32
}
pub fn (i C.sg_image) free() {
C.sg_destroy_image(i)
pub fn (mut i C.sg_image) free() {
C.sg_destroy_image(*i)
}
pub const sg_cubeface_num = 6

View File

@ -8147,6 +8147,19 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
node.pos)
}
}
if node.name == 'free' {
if node.return_type != ast.void_type {
c.error('`.free()` methods should not have a return type', node.return_type_pos)
}
if !node.receiver.typ.is_ptr() {
tname := sym.name.after_char(`.`)
c.error('`.free()` methods should be defined on either a `(mut x &$tname)`, or a `(x &$tname)` receiver',
node.receiver_pos)
}
if node.params.len != 1 {
c.error('`.free()` methods should have 0 arguments', node.pos)
}
}
}
// needed for proper error reporting during vweb route checking
if node.method_idx < sym.methods.len {

View File

@ -0,0 +1,21 @@
vlib/v/checker/tests/free_method_errors.vv:3:5: error: `.free()` methods should be defined on either a `(mut x &Error1)`, or a `(x &Error1)` receiver
1 | struct Error1 {}
2 |
3 | fn (a Error1) free() {}
| ~~~~~~~~
4 |
5 | struct Error2 {}
vlib/v/checker/tests/free_method_errors.vv:7:23: error: `.free()` methods should not have a return type
5 | struct Error2 {}
6 |
7 | fn (a &Error2) free() f64 {}
| ~~~
8 |
9 | struct Error3 {}
vlib/v/checker/tests/free_method_errors.vv:11:1: error: `.free()` methods should have 0 arguments
9 | struct Error3 {}
10 |
11 | fn (a &Error3) free(x int) {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
12 |
13 | struct Ok {}

View File

@ -0,0 +1,22 @@
struct Error1 {}
fn (a Error1) free() {}
struct Error2 {}
fn (a &Error2) free() f64 {}
struct Error3 {}
fn (a &Error3) free(x int) {}
struct Ok {}
fn (a &Ok) free() {}
fn main() {
dump(Error1{})
dump(Error2{})
dump(Error3{})
dump(Ok{})
}