File tree Expand file tree Collapse file tree 4 files changed +48
-3
lines changed Expand file tree Collapse file tree 4 files changed +48
-3
lines changed Original file line number Diff line number Diff line change @@ -5310,11 +5310,14 @@ fn (mut c Checker) fail_if_stack_struct_action_outside_unsafe(mut ident ast.Iden
5310
5310
}
5311
5311
if obj.is_stack_obj && ! c.inside_unsafe {
5312
5312
sym := c.table.sym (obj.typ.set_nr_muls (0 ))
5313
- if ! sym.is_heap () && ! c.pref.translated && ! c.file.is_translated {
5314
- suggestion := if sym.kind == .struct {
5313
+ is_heap := sym.is_heap ()
5314
+ if (! is_heap || ! obj.typ.is_ptr ()) && ! c.pref.translated && ! c.file.is_translated {
5315
+ suggestion := if ! is_heap && sym.kind == .struct {
5315
5316
'declaring `${sym.name} ` as `@[heap]`'
5316
- } else {
5317
+ } else if ! is_heap {
5317
5318
'wrapping the `${sym.name} ` object in a `struct` declared as `@[heap]`'
5319
+ } else { // e.g. var from `for a in heap_object {`
5320
+ 'declaring `${ident.name} ` mutable'
5318
5321
}
5319
5322
c.error ('`${ident.name} ` cannot be ${failed_action} outside `unsafe` blocks as it might refer to an object stored on stack. Consider ${suggestion} .' ,
5320
5323
ident.pos)
Original file line number Diff line number Diff line change @@ -292,6 +292,11 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
292
292
mut r_expr := & node.exprs[expr_idxs[i]]
293
293
if mut r_expr is ast.Ident {
294
294
c.fail_if_stack_struct_action_outside_unsafe (mut r_expr, 'returned' )
295
+ } else if mut r_expr is ast.PrefixExpr && r_expr.op == .amp {
296
+ // &var
297
+ if mut r_expr.right is ast.Ident {
298
+ c.fail_if_stack_struct_action_outside_unsafe (mut r_expr.right, 'returned' )
299
+ }
295
300
}
296
301
}
297
302
}
Original file line number Diff line number Diff line change
1
+ vlib/v/checker/tests/return_stack_var_err.vv:26:12: error: `s` cannot be returned outside `unsafe` blocks as it might refer to an object stored on stack. Consider declaring `s` mutable.
2
+ 24 | for s in students {
3
+ 25 | if s.name == 'Amy' {
4
+ 26 | return &s
5
+ | ^
6
+ 27 | }
7
+ 28 | }
Original file line number Diff line number Diff line change
1
+ module main
2
+
3
+ @[heap]
4
+ struct Student {
5
+ name string
6
+ age int
7
+ }
8
+
9
+ fn main() {
10
+ mut students := []Student{}
11
+ students << Student{
12
+ name: 'Mike'
13
+ age: 16
14
+ }
15
+ students << Student{
16
+ name: 'Amy'
17
+ age: 15
18
+ }
19
+
20
+ _ := get_amy(students) or { unsafe { nil } }
21
+ }
22
+
23
+ fn get_amy(students []Student) ?&Student {
24
+ for s in students {
25
+ if s.name == 'Amy' {
26
+ return &s
27
+ }
28
+ }
29
+ return none
30
+ }
You can’t perform that action at this time.
0 commit comments