1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: add error for fn f() Struct { return &Struct{} } (#6019)

This commit is contained in:
Delyan Angelov 2020-07-29 22:40:43 +03:00 committed by GitHub
parent 81f8e910e6
commit 9c9533dad9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 44 additions and 18 deletions

View File

@ -30,5 +30,5 @@ pub fn do_work(){
} }
pub fn get_subscriber() eventbus.Subscriber { pub fn get_subscriber() eventbus.Subscriber {
return eb.subscriber return *eb.subscriber
} }

View File

@ -6,7 +6,7 @@ module math
// with the sign bit of f and the result in the same bit position. // with the sign bit of f and the result in the same bit position.
// f32_bits(f32_from_bits(x)) == x. // f32_bits(f32_from_bits(x)) == x.
pub fn f32_bits(f f32) u32 { pub fn f32_bits(f f32) u32 {
p := &u32(&f) p := *(&u32(&f))
return p return p
} }
@ -15,7 +15,7 @@ pub fn f32_bits(f f32) u32 {
// and the result in the same bit position. // and the result in the same bit position.
// f32_from_bits(f32_bits(x)) == x. // f32_from_bits(f32_bits(x)) == x.
pub fn f32_from_bits(b u32) f32 { pub fn f32_from_bits(b u32) f32 {
p := &f32(&b) p := *(&f32(&b))
return p return p
} }
@ -23,7 +23,7 @@ pub fn f32_from_bits(b u32) f32 {
// with the sign bit of f and the result in the same bit position, // with the sign bit of f and the result in the same bit position,
// and f64_bits(f64_from_bits(x)) == x. // and f64_bits(f64_from_bits(x)) == x.
pub fn f64_bits(f f64) u64 { pub fn f64_bits(f f64) u64 {
p := &u64(&f) p := *(&u64(&f))
return p return p
} }
@ -32,7 +32,7 @@ pub fn f64_bits(f f64) u64 {
// and the result in the same bit position. // and the result in the same bit position.
// f64_from_bits(f64_bits(x)) == x. // f64_from_bits(f64_bits(x)) == x.
pub fn f64_from_bits(b u64) f64 { pub fn f64_from_bits(b u64) f64 {
p := &f64(&b) p := *(&f64(&b))
return p return p
} }

View File

@ -72,7 +72,7 @@ fn calculate_state(seed_data []u32, mut state []u64) []u64 {
for j := 1; j < nn; j++ { for j := 1; j < nn; j++ {
state[j] = u64(6364136223846793005) * (state[j - 1] ^ (state[j - 1] >> 62)) + u64(j) state[j] = u64(6364136223846793005) * (state[j - 1] ^ (state[j - 1] >> 62)) + u64(j)
} }
return state return *state
} }
// seed() - Set the seed, needs only two u32s in little endian format as [lower, higher] // seed() - Set the seed, needs only two u32s in little endian format as [lower, higher]

View File

@ -165,7 +165,7 @@ pub mut:
pub fn (mut desc C.sg_shader_stage_desc) set_image(index int, name string) C.sg_shader_stage_desc { pub fn (mut desc C.sg_shader_stage_desc) set_image(index int, name string) C.sg_shader_stage_desc {
desc.images[index].name = name.str desc.images[index].name = name.str
desc.images[index].@type = ._2d desc.images[index].@type = ._2d
return desc return *desc
} }

View File

@ -164,7 +164,7 @@ fn process_in_thread(mut pool PoolProcessor, task_id int) {
pub fn (pool &PoolProcessor) get_string_item(idx int) string { pub fn (pool &PoolProcessor) get_string_item(idx int) string {
// return *(&string(pool.items[idx])) // return *(&string(pool.items[idx]))
// TODO: the below is a hack, remove it when v2 casting works again // TODO: the below is a hack, remove it when v2 casting works again
return &string( pool.items[idx] ) return *(&string( pool.items[idx] ))
} }
// get_int_item - called by the worker callback. // get_int_item - called by the worker callback.

View File

@ -400,7 +400,7 @@ pub mut:
pub fn (i &Ident) var_info() IdentVar { pub fn (i &Ident) var_info() IdentVar {
match i.info as info { match i.info as info {
IdentVar { IdentVar {
return info return *info
} }
else { else {
// return IdentVar{} // return IdentVar{}

View File

@ -1515,6 +1515,11 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument', c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
pos) pos)
} }
if got_typ.is_ptr() && !exp_type.is_ptr() {
pos := return_stmt.exprs[i].position()
c.error('fn `$c.cur_fn.name` expects you to return a non reference type `${c.table.type_to_str(exp_type)}`, but you are returning `${c.table.type_to_str(got_typ)}` instead',
pos)
}
} }
} }
@ -1905,7 +1910,7 @@ fn const_int_value(cfield ast.ConstField) ?int {
fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral { fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral {
match cfield.expr { match cfield.expr {
ast.IntegerLiteral { return it } ast.IntegerLiteral { return *it }
else {} else {}
} }
return none return none

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/return_ref_as_no_ref_bug.v:11:9: error: fn `return_not_reference` expects you to return a non reference type `BugStruct`, but you are returning `&BugStruct` instead
9 |
10 | fn return_not_reference() BugStruct{
11 | return &BugStruct {
| ^
12 | id: 1
13 | }

View File

@ -0,0 +1,14 @@
struct BugStruct {
id int
}
fn main() {
x := return_not_reference()
println(x.id)
}
fn return_not_reference() BugStruct{
return &BugStruct {
id: 1
}
}

View File

@ -431,7 +431,7 @@ fn (mut d Doc) generate() ?Doc {
d.time_generated = time.now() d.time_generated = time.now()
d.contents.sort_by_name() d.contents.sort_by_name()
d.contents.sort_by_category() d.contents.sort_by_category()
return d return *d
} }
pub fn generate(input_path string, pub_only, with_comments bool) ?Doc { pub fn generate(input_path string, pub_only, with_comments bool) ?Doc {

View File

@ -362,7 +362,7 @@ pub fn (t &TypeSymbol) str() string {
[inline] [inline]
pub fn (t &TypeSymbol) enum_info() Enum { pub fn (t &TypeSymbol) enum_info() Enum {
match t.info { match t.info {
Enum { return it } Enum { return *it }
else { panic('TypeSymbol.enum_info(): no enum info for type: $t.name') } else { panic('TypeSymbol.enum_info(): no enum info for type: $t.name') }
} }
} }
@ -370,7 +370,7 @@ pub fn (t &TypeSymbol) enum_info() Enum {
[inline] [inline]
pub fn (t &TypeSymbol) mr_info() MultiReturn { pub fn (t &TypeSymbol) mr_info() MultiReturn {
match t.info { match t.info {
MultiReturn { return it } MultiReturn { return *it }
else { panic('TypeSymbol.mr_info(): no multi return info for type: $t.name') } else { panic('TypeSymbol.mr_info(): no multi return info for type: $t.name') }
} }
} }
@ -378,7 +378,7 @@ pub fn (t &TypeSymbol) mr_info() MultiReturn {
[inline] [inline]
pub fn (t &TypeSymbol) array_info() Array { pub fn (t &TypeSymbol) array_info() Array {
match t.info { match t.info {
Array { return it } Array { return *it }
else { panic('TypeSymbol.array_info(): no array info for type: $t.name') } else { panic('TypeSymbol.array_info(): no array info for type: $t.name') }
} }
} }
@ -386,7 +386,7 @@ pub fn (t &TypeSymbol) array_info() Array {
[inline] [inline]
pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed { pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
match t.info { match t.info {
ArrayFixed { return it } ArrayFixed { return *it }
else { panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name') } else { panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name') }
} }
} }
@ -394,7 +394,7 @@ pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
[inline] [inline]
pub fn (t &TypeSymbol) map_info() Map { pub fn (t &TypeSymbol) map_info() Map {
match t.info { match t.info {
Map { return it } Map { return *it }
else { panic('TypeSymbol.map_info(): no map info for type: $t.name') } else { panic('TypeSymbol.map_info(): no map info for type: $t.name') }
} }
} }
@ -402,7 +402,7 @@ pub fn (t &TypeSymbol) map_info() Map {
[inline] [inline]
pub fn (t &TypeSymbol) struct_info() Struct { pub fn (t &TypeSymbol) struct_info() Struct {
match t.info { match t.info {
Struct { return it } Struct { return *it }
else { panic('TypeSymbol.struct_info(): no struct info for type: $t.name') } else { panic('TypeSymbol.struct_info(): no struct info for type: $t.name') }
} }
} }

View File

@ -70,7 +70,7 @@ fn mut_arg<T>(mut x T) {
fn mut_arg2<T>(mut x T) T { fn mut_arg2<T>(mut x T) T {
println(x.name) // = 'foo' println(x.name) // = 'foo'
return x return *x
} }
fn test_create() { fn test_create() {