diff --git a/doc/docs.md b/doc/docs.md index 15206d20ba..2959b6bd9f 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -3866,8 +3866,9 @@ fn old_function() { fn inlined_function() { } -// The following struct can only be used as a reference (`&Window`) and allocated on the heap. -[ref_only] +// The following struct must be allocated on the heap. Therefore, it can only be used as a +// reference (`&Window`) or inside another reference (`&OuterStruct{ Window{...} }`). +[heap] struct Window { } diff --git a/vlib/net/html/tag.v b/vlib/net/html/tag.v index 89917a562d..e5630a7d6d 100644 --- a/vlib/net/html/tag.v +++ b/vlib/net/html/tag.v @@ -8,7 +8,7 @@ enum CloseTagType { } // Tag holds the information of an HTML tag. -[ref_only] +[heap] pub struct Tag { pub mut: name string diff --git a/vlib/os/process.v b/vlib/os/process.v index 9bef54a85c..2284656ea4 100644 --- a/vlib/os/process.v +++ b/vlib/os/process.v @@ -13,7 +13,7 @@ pub enum ProcessState { aborted } -[ref_only] +[heap] pub struct Process { pub: filename string // the process's command file path diff --git a/vlib/sync/sync_default.c.v b/vlib/sync/sync_default.c.v index b86703a355..244d8dd367 100644 --- a/vlib/sync/sync_default.c.v +++ b/vlib/sync/sync_default.c.v @@ -28,12 +28,12 @@ fn C.sem_timedwait(voidptr, voidptr) int fn C.sem_destroy(voidptr) int // [init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function. -[ref_only] +[heap] pub struct Mutex { mutex C.pthread_mutex_t } -[ref_only] +[heap] pub struct RwMutex { mutex C.pthread_rwlock_t } @@ -42,7 +42,7 @@ struct RwMutexAttr { attr C.pthread_rwlockattr_t } -[ref_only] +[heap] struct Semaphore { sem C.sem_t } diff --git a/vlib/sync/sync_macos.c.v b/vlib/sync/sync_macos.c.v index bd9fc7669c..c62b133a85 100644 --- a/vlib/sync/sync_macos.c.v +++ b/vlib/sync/sync_macos.c.v @@ -31,12 +31,12 @@ fn C.pthread_cond_timedwait(voidptr, voidptr, voidptr) int fn C.pthread_cond_destroy(voidptr) int // [init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function. -[ref_only] +[heap] pub struct Mutex { mutex C.pthread_mutex_t } -[ref_only] +[heap] pub struct RwMutex { mutex C.pthread_rwlock_t } @@ -51,7 +51,7 @@ struct CondAttr { /* MacOSX has no unnamed semaphores and no `timed_wait()` at all so we emulate the behaviour with other devices */ -[ref_only] +[heap] struct Semaphore { mtx C.pthread_mutex_t cond C.pthread_cond_t diff --git a/vlib/sync/sync_windows.c.v b/vlib/sync/sync_windows.c.v index 4bd9f302b6..115d1b805c 100644 --- a/vlib/sync/sync_windows.c.v +++ b/vlib/sync/sync_windows.c.v @@ -22,19 +22,19 @@ type SHANDLE = voidptr //[init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function. // `SRWLOCK` is much more performant that `Mutex` on Windows, so use that in both cases since we don't want to share with other processes -[ref_only] +[heap] pub struct Mutex { mut: mx C.SRWLOCK // mutex handle } -[ref_only] +[heap] pub struct RwMutex { mut: mx C.SRWLOCK // mutex handle } -[ref_only] +[heap] struct Semaphore { mtx C.SRWLOCK cond C.CONDITION_VARIABLE diff --git a/vlib/sync/waitgroup.v b/vlib/sync/waitgroup.v index 041ca787f5..d9d4aca668 100644 --- a/vlib/sync/waitgroup.v +++ b/vlib/sync/waitgroup.v @@ -18,7 +18,7 @@ fn C.atomic_fetch_add_u32(voidptr, u32) u32 // `wg.done()` when finished // // [init_with=new_waitgroup] // TODO: implement support for init_with struct attribute, and disallow WaitGroup{} from outside the sync.new_waitgroup() function. -[ref_only] +[heap] struct WaitGroup { mut: task_count u32 // current task count - reading/writing should be atomic diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3966e887a3..619610769b 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -399,8 +399,8 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { c.error('`$embed_sym.name` is not a struct', embed.pos) } else { info := embed_sym.info as table.Struct - if info.is_ref_only && !embed.typ.is_ptr() { - struct_sym.info.is_ref_only = true + if info.is_heap && !embed.typ.is_ptr() { + struct_sym.info.is_heap = true } } } @@ -443,8 +443,8 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { } if sym.kind == .struct_ { info := sym.info as table.Struct - if info.is_ref_only && !field.typ.is_ptr() { - struct_sym.info.is_ref_only = true + if info.is_heap && !field.typ.is_ptr() { + struct_sym.info.is_heap = true } } if sym.kind == .map { @@ -543,7 +543,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { c.error('struct `$type_sym.name` is declared with a `[noinit]` attribute, so ' + 'it cannot be initialized with `$type_sym.name{}`', struct_init.pos) } - if info.is_ref_only && !c.inside_ref_lit && !c.inside_unsafe && !struct_init.typ.is_ptr() { + if info.is_heap && !c.inside_ref_lit && !c.inside_unsafe && !struct_init.typ.is_ptr() { c.error('`$type_sym.name` type can only be used as a reference `&$type_sym.name` or inside a `struct` reference', struct_init.pos) } diff --git a/vlib/v/checker/tests/ref_only_struct.out b/vlib/v/checker/tests/heap_struct.out similarity index 51% rename from vlib/v/checker/tests/ref_only_struct.out rename to vlib/v/checker/tests/heap_struct.out index b9ac13b0f9..183cc015a0 100644 --- a/vlib/v/checker/tests/ref_only_struct.out +++ b/vlib/v/checker/tests/heap_struct.out @@ -1,32 +1,32 @@ -vlib/v/checker/tests/ref_only_struct.vv:18:7: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference +vlib/v/checker/tests/heap_struct.vv:18:7: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference 16 | 17 | fn main() { 18 | a := Abc{ n: 3 } | ~~~~~~~~~~~ 19 | b := St{ 20 | Abc{ n: 7 } -vlib/v/checker/tests/ref_only_struct.vv:19:7: error: `St` type can only be used as a reference `&St` or inside a `struct` reference +vlib/v/checker/tests/heap_struct.vv:19:7: error: `St` type can only be used as a reference `&St` or inside a `struct` reference 17 | fn main() { 18 | a := Abc{ n: 3 } 19 | b := St{ | ~~~ 20 | Abc{ n: 7 } 21 | } -vlib/v/checker/tests/ref_only_struct.vv:20:3: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference +vlib/v/checker/tests/heap_struct.vv:20:3: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference 18 | a := Abc{ n: 3 } 19 | b := St{ 20 | Abc{ n: 7 } | ~~~~~~~~~~~ 21 | } 22 | x := Qwe{ -vlib/v/checker/tests/ref_only_struct.vv:22:7: error: `Qwe` type can only be used as a reference `&Qwe` or inside a `struct` reference +vlib/v/checker/tests/heap_struct.vv:22:7: error: `Qwe` type can only be used as a reference `&Qwe` or inside a `struct` reference 20 | Abc{ n: 7 } 21 | } 22 | x := Qwe{ | ~~~~ 23 | f: 12.25 24 | a: Abc{ n: 23 } -vlib/v/checker/tests/ref_only_struct.vv:24:6: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference +vlib/v/checker/tests/heap_struct.vv:24:6: error: `Abc` type can only be used as a reference `&Abc` or inside a `struct` reference 22 | x := Qwe{ 23 | f: 12.25 24 | a: Abc{ n: 23 } diff --git a/vlib/v/checker/tests/ref_only_struct.vv b/vlib/v/checker/tests/heap_struct.vv similarity index 95% rename from vlib/v/checker/tests/ref_only_struct.vv rename to vlib/v/checker/tests/heap_struct.vv index 0978474d19..c870c60ca1 100644 --- a/vlib/v/checker/tests/ref_only_struct.vv +++ b/vlib/v/checker/tests/heap_struct.vv @@ -1,4 +1,4 @@ -[ref_only] +[heap] struct Abc { mut: n int diff --git a/vlib/v/fmt/tests/fntype_alias_keep.vv b/vlib/v/fmt/tests/fntype_alias_keep.vv index 57c582c7a4..8e530a70fb 100644 --- a/vlib/v/fmt/tests/fntype_alias_keep.vv +++ b/vlib/v/fmt/tests/fntype_alias_keep.vv @@ -14,7 +14,7 @@ pub type ScrollFn = fn (e ScrollEvent, func voidptr) pub type MouseMoveFn = fn (e MouseMoveEvent, func voidptr) -[ref_only] +[heap] pub struct Window { pub mut: ui &UI = voidptr(0) diff --git a/vlib/v/fmt/tests/struct_no_extra_attr_keep.vv b/vlib/v/fmt/tests/struct_no_extra_attr_keep.vv index f1aab1d628..8278308cd0 100644 --- a/vlib/v/fmt/tests/struct_no_extra_attr_keep.vv +++ b/vlib/v/fmt/tests/struct_no_extra_attr_keep.vv @@ -8,7 +8,7 @@ struct Bar { y int } -[ref_only] +[heap] struct Baz { x string y int diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ff144c6b6a..b0e5b96c18 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -877,11 +877,14 @@ fn (mut p Parser) parse_attr() table.Attr { } else { name = p.check_name() if name == 'unsafe_fn' { - p.error_with_pos('please use `[unsafe]` instead', p.tok.position()) + p.error_with_pos('[unsafe_fn] is obsolete, use `[unsafe]` instead', apos.extend(p.tok.position())) return table.Attr{} } else if name == 'trusted_fn' { - p.error_with_pos('please use `[trusted]` instead', p.tok.position()) + p.error_with_pos('[trusted_fn] is obsolete, use `[trusted]` instead', apos.extend(p.tok.position())) return table.Attr{} + } else if name == 'ref_only' { + p.warn_with_pos('[ref_only] is deprecated, use [heap] instead', apos.extend(p.tok.position())) + name = 'heap' } if p.tok.kind == .colon { p.next() diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index e9b761d77e..ae27b96d65 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -295,7 +295,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { fields: fields is_typedef: attrs.contains('typedef') is_union: is_union - is_ref_only: attrs.contains('ref_only') + is_heap: attrs.contains('heap') generic_types: generic_types attrs: attrs } diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 27ee7d959d..f23593ce4c 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -48,7 +48,7 @@ const ( 'cflags', 'path'] ) -[ref_only] +[heap] pub struct Preferences { pub mut: os OS // the OS to compile for diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 136e093225..205923e1ea 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -643,7 +643,7 @@ pub mut: fields []Field is_typedef bool // C. [typedef] is_union bool - is_ref_only bool + is_heap bool generic_types []Type } diff --git a/vlib/v/tests/ref_struct_test.v b/vlib/v/tests/ref_struct_test.v index c98656ef45..771586bd5f 100644 --- a/vlib/v/tests/ref_struct_test.v +++ b/vlib/v/tests/ref_struct_test.v @@ -1,4 +1,4 @@ -[ref_only] +[heap] struct Abc { mut: n int diff --git a/vlib/v/util/timers.v b/vlib/v/util/timers.v index 3fe0e5bb18..64f3e43cec 100644 --- a/vlib/v/util/timers.v +++ b/vlib/v/util/timers.v @@ -5,7 +5,7 @@ module util import time -[ref_only] +[heap] pub struct Timers { pub mut: swatches map[string]time.StopWatch diff --git a/vlib/v/vmod/vmod.v b/vlib/v/vmod/vmod.v index bec9c9c9fd..6f29a255a6 100644 --- a/vlib/v/vmod/vmod.v +++ b/vlib/v/vmod/vmod.v @@ -30,7 +30,7 @@ pub: vmod_folder string } -[ref_only] +[heap] pub struct ModFileCacher { mut: cache map[string]ModFileAndFolder diff --git a/vlib/vweb/sse/sse.v b/vlib/vweb/sse/sse.v index f0fe1ffbf3..c75e2d1f63 100644 --- a/vlib/vweb/sse/sse.v +++ b/vlib/vweb/sse/sse.v @@ -20,7 +20,7 @@ import strings // > Each field is represented by the field name, followed by a colon, followed by the text // > data for that field's value. -[ref_only] +[heap] pub struct SSEConnection { pub mut: headers map[string]string