From 3ffc951cf555dc4818309a507ccb9d0da4de748f Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 14 Apr 2026 12:48:00 +0300 Subject: [PATCH] revert: deprecated_after attribute change (fixes #19138) - incomplete, breaks time/format.v --- doc/docs.md | 18 ++-- vlib/gx/color.v | 81 ++++++++++------ vlib/gx/image.v | 6 +- vlib/gx/text.c.v | 3 +- vlib/gx/text.js.v | 9 +- vlib/gx/text.v | 3 +- vlib/io/string_reader/string_reader.v | 3 +- vlib/v/checker/tests/deprecations.out | 94 +++++++++---------- vlib/v/checker/tests/deprecations.vv | 19 ++-- .../module_with_deprecated_structs/module.v | 10 +- .../tests/modules/deprecated_consts.out | 2 +- .../tests/modules/deprecated_consts/consts.v | 3 +- .../modules/deprecated_module/www/ttt/ttt.v | 3 +- .../v/fmt/tests/attribute_call_syntax_keep.vv | 2 +- vlib/v/fmt/tests/attrs_keep.vv | 3 +- vlib/v/parser/attribute.v | 66 +++---------- vlib/v/parser/tests/attribute_call_syntax.vv | 2 +- .../deprecated_after_without_deprecated.out | 23 ++++- .../tests/deprecated_call_without_after.out | 5 - .../tests/deprecated_call_without_after.vv | 8 -- .../comptime_attribute_call_syntax_test.v | 7 +- vlib/v/util/diff/diff.v | 22 +++-- vlib/x/crypto/chacha20/chacha.v | 3 +- vlib/x/json2/custom.v | 3 +- vlib/x/json2/decoder2/stub.v | 6 +- vlib/x/json2/decoder_deprecated.v | 3 +- vlib/x/json2/encoder.v | 6 +- vlib/x/json2/json2.v | 3 +- 28 files changed, 220 insertions(+), 196 deletions(-) delete mode 100644 vlib/v/parser/tests/deprecated_call_without_after.out delete mode 100644 vlib/v/parser/tests/deprecated_call_without_after.vv diff --git a/doc/docs.md b/doc/docs.md index f1f1ae6f8..ea531602c 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -6253,7 +6253,7 @@ module abc pub struct Xyz { pub mut: a int - d int @[deprecated(msg: 'use Xyz.a instead', after: '2999-03-01')] + d int @[deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01'] // the tags above, will produce a notice, since the deprecation date is in the far future } ``` @@ -6276,9 +6276,6 @@ Different V projects and maintainers may reasonably choose different deprecation Depending on the type and impact of the change, you may want to consult with them first, before deprecating a function. -When a deprecation has a date, keep the message and `after` date together in a single -`@[deprecated(...)]` attribute. `deprecated_after` is not a separate attribute anymore. - ```v nofmt // Calling this function will result in a deprecation warning @@ -6289,6 +6286,10 @@ fn old_function() {} @[deprecated: 'use new_function() instead'] fn legacy_function() {} +// Equivalent call-style syntax: +@[deprecated('use new_function() instead')] +fn legacy_function_call_style() {} + // You can also specify a date, after which the function will be // considered deprecated. Before that date, calls to the function // will be compiler notices - you will see them, but the compilation @@ -6298,12 +6299,13 @@ fn legacy_function() {} // 6 months after the deprecation date, calls will be hard // compiler errors. -@[deprecated('use new_function2() instead', '2021-05-27')] +@[deprecated: 'use new_function2() instead'] +@[deprecated_after: '2021-05-27'] fn legacy_function2() {} -// Equivalent named-argument form: -@[deprecated(msg: 'use new_function3() instead', after: '2021-05-27')] -fn legacy_function3() {} +// Equivalent call-style syntax: +@[deprecated(msg: 'use new_function2() instead', after: '2021-05-27')] +fn legacy_function2_call_style() {} ``` ```v globals diff --git a/vlib/gx/color.v b/vlib/gx/color.v index 22082bb74..0c647c0f4 100644 --- a/vlib/gx/color.v +++ b/vlib/gx/color.v @@ -1,4 +1,5 @@ -@[deprecated(msg: 'module gx is deprecated, use `import gg` instead', after: '2026-01-24')] +@[deprecated: 'module gx is deprecated, use `import gg` instead'] +@[deprecated_after: '2026-01-24'] module gx import gg @@ -7,93 +8,119 @@ import gg pub type Color = gg.Color -@[deprecated(msg: 'use gg.black instead', after: '2026-01-24')] +@[deprecated: 'use gg.black instead'] +@[deprecated_after: '2026-01-24'] pub const black = gg.black -@[deprecated(msg: 'use gg.gray instead', after: '2026-01-24')] +@[deprecated: 'use gg.gray instead'] +@[deprecated_after: '2026-01-24'] pub const gray = gg.gray -@[deprecated(msg: 'use gg.white instead', after: '2026-01-24')] +@[deprecated: 'use gg.white instead'] +@[deprecated_after: '2026-01-24'] pub const white = gg.white -@[deprecated(msg: 'use gg.red instead', after: '2026-01-24')] +@[deprecated: 'use gg.red instead'] +@[deprecated_after: '2026-01-24'] pub const red = gg.red -@[deprecated(msg: 'use gg.green instead', after: '2026-01-24')] +@[deprecated: 'use gg.green instead'] +@[deprecated_after: '2026-01-24'] pub const green = gg.green -@[deprecated(msg: 'use gg.blue instead', after: '2026-01-24')] +@[deprecated: 'use gg.blue instead'] +@[deprecated_after: '2026-01-24'] pub const blue = gg.blue -@[deprecated(msg: 'use gg.yellow instead', after: '2026-01-24')] +@[deprecated: 'use gg.yellow instead'] +@[deprecated_after: '2026-01-24'] pub const yellow = gg.yellow -@[deprecated(msg: 'use gg.magenta instead', after: '2026-01-24')] +@[deprecated: 'use gg.magenta instead'] +@[deprecated_after: '2026-01-24'] pub const magenta = gg.magenta -@[deprecated(msg: 'use gg.cyan instead', after: '2026-01-24')] +@[deprecated: 'use gg.cyan instead'] +@[deprecated_after: '2026-01-24'] pub const cyan = gg.cyan -@[deprecated(msg: 'use gg.orange instead', after: '2026-01-24')] +@[deprecated: 'use gg.orange instead'] +@[deprecated_after: '2026-01-24'] pub const orange = gg.orange -@[deprecated(msg: 'use gg.purple instead', after: '2026-01-24')] +@[deprecated: 'use gg.purple instead'] +@[deprecated_after: '2026-01-24'] pub const purple = gg.purple -@[deprecated(msg: 'use gg.indigo instead', after: '2026-01-24')] +@[deprecated: 'use gg.indigo instead'] +@[deprecated_after: '2026-01-24'] pub const indigo = gg.indigo -@[deprecated(msg: 'use gg.pink instead', after: '2026-01-24')] +@[deprecated: 'use gg.pink instead'] +@[deprecated_after: '2026-01-24'] pub const pink = gg.pink -@[deprecated(msg: 'use gg.violet instead', after: '2026-01-24')] +@[deprecated: 'use gg.violet instead'] +@[deprecated_after: '2026-01-24'] pub const violet = gg.violet -@[deprecated(msg: 'use gg.dark_blue instead', after: '2026-01-24')] +@[deprecated: 'use gg.dark_blue instead'] +@[deprecated_after: '2026-01-24'] pub const dark_blue = gg.dark_blue -@[deprecated(msg: 'use gg.dark_gray instead', after: '2026-01-24')] +@[deprecated: 'use gg.dark_gray instead'] +@[deprecated_after: '2026-01-24'] pub const dark_gray = gg.dark_gray -@[deprecated(msg: 'use gg.dark_green instead', after: '2026-01-24')] +@[deprecated: 'use gg.dark_green instead'] +@[deprecated_after: '2026-01-24'] pub const dark_green = gg.dark_green -@[deprecated(msg: 'use gg.dark_red instead', after: '2026-01-24')] +@[deprecated: 'use gg.dark_red instead'] +@[deprecated_after: '2026-01-24'] pub const dark_red = gg.dark_red -@[deprecated(msg: 'use gg.light_blue instead', after: '2026-01-24')] +@[deprecated: 'use gg.light_blue instead'] +@[deprecated_after: '2026-01-24'] pub const light_blue = gg.light_blue -@[deprecated(msg: 'use gg.light_gray instead', after: '2026-01-24')] +@[deprecated: 'use gg.light_gray instead'] +@[deprecated_after: '2026-01-24'] pub const light_gray = gg.light_gray -@[deprecated(msg: 'use gg.light_green instead', after: '2026-01-24')] +@[deprecated: 'use gg.light_green instead'] +@[deprecated_after: '2026-01-24'] pub const light_green = gg.light_green -@[deprecated(msg: 'use gg.light_red instead', after: '2026-01-24')] +@[deprecated: 'use gg.light_red instead'] +@[deprecated_after: '2026-01-24'] pub const light_red = gg.light_red // hex takes in a 32 bit integer and splits it into 4 byte values -@[deprecated(msg: 'use gg.hex instead', after: '2026-01-24')] +@[deprecated: 'use gg.hex instead'] +@[deprecated_after: '2026-01-24'] pub fn hex(color i32) Color { return gg.hex(color) } // rgb builds a Color instance from given r, g, b values -@[deprecated(msg: 'use gg.rgb instead', after: '2026-01-24')] +@[deprecated: 'use gg.rgb instead'] +@[deprecated_after: '2026-01-24'] pub fn rgb(r u8, g u8, b u8) Color { return gg.rgb(r, g, b) } // rgba builds a Color instance from given r, g, b, a values -@[deprecated(msg: 'use gg.rgba instead', after: '2026-01-24')] +@[deprecated: 'use gg.rgba instead'] +@[deprecated_after: '2026-01-24'] pub fn rgba(r u8, g u8, b u8, a u8) Color { return gg.rgba(r, g, b, a) } // color_from_string returns a Color, corresponding to the given string // or black Color if string is not found in lookup table, or a hex color if starting with # -@[deprecated(msg: 'use gg.color_from_string instead', after: '2026-01-24')] +@[deprecated: 'use gg.color_from_string instead'] +@[deprecated_after: '2026-01-24'] pub fn color_from_string(s string) Color { return gg.color_from_string(s) } diff --git a/vlib/gx/image.v b/vlib/gx/image.v index 416241053..1644ba0f6 100644 --- a/vlib/gx/image.v +++ b/vlib/gx/image.v @@ -1,7 +1,9 @@ -@[deprecated(msg: 'module gx is deprecated, use `import gg` instead', after: '2026-01-24')] +@[deprecated: 'module gx is deprecated, use `import gg` instead'] +@[deprecated_after: '2026-01-24'] module gx -@[deprecated(msg: 'use gg.Image', after: '2026-01-24')] +@[deprecated: 'use gg.Image'] +@[deprecated_after: '2026-01-24'] pub struct Image { mut: obj voidptr diff --git a/vlib/gx/text.c.v b/vlib/gx/text.c.v index d89c656fc..abaa67b9a 100644 --- a/vlib/gx/text.c.v +++ b/vlib/gx/text.c.v @@ -1,4 +1,5 @@ -@[deprecated(msg: 'module gx is deprecated, use import gg instead', after: '2026-01-24')] +@[deprecated: 'module gx is deprecated, use import gg instead'] +@[deprecated_after: '2026-01-24'] module gx import fontstash as _ diff --git a/vlib/gx/text.js.v b/vlib/gx/text.js.v index 282db9149..3ab9665ee 100644 --- a/vlib/gx/text.js.v +++ b/vlib/gx/text.js.v @@ -1,14 +1,17 @@ -@[deprecated(msg: 'module gx is deprecated, use import gg instead', after: '2026-01-24')] +@[deprecated: 'module gx is deprecated, use import gg instead'] +@[deprecated_after: '2026-01-24'] module gx -@[deprecated(msg: 'use gg.HorizontalAlign instead', after: '2026-01-24')] +@[deprecated: 'use gg.HorizontalAlign instead'] +@[deprecated_after: '2026-01-24'] pub enum HorizontalAlign { left center right } -@[deprecated(msg: 'use gg.VerticalAlign instead', after: '2026-01-24')] +@[deprecated: 'use gg.VerticalAlign instead'] +@[deprecated_after: '2026-01-24'] pub enum VerticalAlign { top middle diff --git a/vlib/gx/text.v b/vlib/gx/text.v index 75181f0ff..d9b03b227 100644 --- a/vlib/gx/text.v +++ b/vlib/gx/text.v @@ -1,4 +1,5 @@ -@[deprecated(msg: 'module gx is deprecated, use `import gg` instead', after: '2026-01-24')] +@[deprecated: 'module gx is deprecated, use `import gg` instead'] +@[deprecated_after: '2026-01-24'] module gx import gg diff --git a/vlib/io/string_reader/string_reader.v b/vlib/io/string_reader/string_reader.v index 3091648cc..edfce10b1 100644 --- a/vlib/io/string_reader/string_reader.v +++ b/vlib/io/string_reader/string_reader.v @@ -1,4 +1,5 @@ -@[deprecated(msg: 'If you use it, create a local module named `string_reader`, and copy https://github.com/vlang/v/blob/f24d49259db5d2d7211e79bcf6b6f507d22847f3/vlib/io/string_reader/string_reader.v there.', after: '2026-01-06')] +@[deprecated: 'If you use it, create a local module named `string_reader`, and copy https://github.com/vlang/v/blob/f24d49259db5d2d7211e79bcf6b6f507d22847f3/vlib/io/string_reader/string_reader.v there.'] +@[deprecated_after: '2026-01-06'] module string_reader import io diff --git a/vlib/v/checker/tests/deprecations.out b/vlib/v/checker/tests/deprecations.out index 24cb8ab06..cb8a51dc1 100644 --- a/vlib/v/checker/tests/deprecations.out +++ b/vlib/v/checker/tests/deprecations.out @@ -1,55 +1,55 @@ -vlib/v/checker/tests/deprecations.vv:55:2: notice: function `future` will be deprecated after 3000-12-30, and will become an error after 3001-06-28; custom message 4 - 53 | - 54 | fn main() { - 55 | future() +vlib/v/checker/tests/deprecations.vv:60:2: notice: function `future` will be deprecated after 3000-12-30, and will become an error after 3001-06-28; custom message 4 + 58 | + 59 | fn main() { + 60 | future() | ~~~~~~~~ - 56 | past() - 57 | simply_deprecated() -vlib/v/checker/tests/deprecations.vv:62:4: notice: method `Abc.future` will be deprecated after 3000-11-01, and will become an error after 3001-04-30; custom message 1 - 60 | // - 61 | a := Abc{} - 62 | a.future() + 61 | past() + 62 | simply_deprecated() +vlib/v/checker/tests/deprecations.vv:67:4: notice: method `Abc.future` will be deprecated after 3000-11-01, and will become an error after 3001-04-30; custom message 1 + 65 | // + 66 | a := Abc{} + 67 | a.future() | ~~~~~~~~ - 63 | a.past() - 64 | a.simply_deprecated() -vlib/v/checker/tests/deprecations.vv:57:2: warning: function `simply_deprecated` has been deprecated; custom message 7 - 55 | future() - 56 | past() - 57 | simply_deprecated() + 68 | a.past() + 69 | a.simply_deprecated() +vlib/v/checker/tests/deprecations.vv:62:2: warning: function `simply_deprecated` has been deprecated; custom message 7 + 60 | future() + 61 | past() + 62 | simply_deprecated() | ~~~~~~~~~~~~~~~~~~~ - 58 | just_deprecated() - 59 | ancient() -vlib/v/checker/tests/deprecations.vv:58:2: warning: function `just_deprecated` has been deprecated - 56 | past() - 57 | simply_deprecated() - 58 | just_deprecated() + 63 | just_deprecated() + 64 | ancient() +vlib/v/checker/tests/deprecations.vv:63:2: warning: function `just_deprecated` has been deprecated + 61 | past() + 62 | simply_deprecated() + 63 | just_deprecated() | ~~~~~~~~~~~~~~~~~ - 59 | ancient() - 60 | // -vlib/v/checker/tests/deprecations.vv:64:4: warning: method `Abc.simply_deprecated` has been deprecated; custom message 3 - 62 | a.future() - 63 | a.past() - 64 | a.simply_deprecated() + 64 | ancient() + 65 | // +vlib/v/checker/tests/deprecations.vv:69:4: warning: method `Abc.simply_deprecated` has been deprecated; custom message 3 + 67 | a.future() + 68 | a.past() + 69 | a.simply_deprecated() | ~~~~~~~~~~~~~~~~~~~ - 65 | } -vlib/v/checker/tests/deprecations.vv:56:2: error: function `past` has been deprecated since 2021-03-01; custom message 5 - 54 | fn main() { - 55 | future() - 56 | past() + 70 | } +vlib/v/checker/tests/deprecations.vv:61:2: error: function `past` has been deprecated since 2021-03-01; custom message 5 + 59 | fn main() { + 60 | future() + 61 | past() | ~~~~~~ - 57 | simply_deprecated() - 58 | just_deprecated() -vlib/v/checker/tests/deprecations.vv:59:2: error: function `ancient` has been deprecated since 1990-03-01; custom message 6 - 57 | simply_deprecated() - 58 | just_deprecated() - 59 | ancient() + 62 | simply_deprecated() + 63 | just_deprecated() +vlib/v/checker/tests/deprecations.vv:64:2: error: function `ancient` has been deprecated since 1990-03-01; custom message 6 + 62 | simply_deprecated() + 63 | just_deprecated() + 64 | ancient() | ~~~~~~~~~ - 60 | // - 61 | a := Abc{} -vlib/v/checker/tests/deprecations.vv:63:4: error: method `Abc.past` has been deprecated since 2021-03-01; custom message 2 - 61 | a := Abc{} - 62 | a.future() - 63 | a.past() + 65 | // + 66 | a := Abc{} +vlib/v/checker/tests/deprecations.vv:68:4: error: method `Abc.past` has been deprecated since 2021-03-01; custom message 2 + 66 | a := Abc{} + 67 | a.future() + 68 | a.past() | ~~~~~~ - 64 | a.simply_deprecated() - 65 | } + 69 | a.simply_deprecated() + 70 | } diff --git a/vlib/v/checker/tests/deprecations.vv b/vlib/v/checker/tests/deprecations.vv index 760fd025f..00e54b7ba 100644 --- a/vlib/v/checker/tests/deprecations.vv +++ b/vlib/v/checker/tests/deprecations.vv @@ -1,4 +1,4 @@ -// methods using scheduled deprecations: +// methods using [deprecated_after]: struct Abc { x int } @@ -7,13 +7,15 @@ fn (a Abc) str() string { return 'Abc { x: ${a.x} }' } -@[deprecated(msg: 'custom message 1', after: '3000-11-01')] +@[deprecated: 'custom message 1'] +@[deprecated_after: '3000-11-01'] fn (a Abc) future() { dump(@METHOD) dump(a) } -@[deprecated(msg: 'custom message 2', after: '2021-03-01')] +@[deprecated: 'custom message 2'] +@[deprecated_after: '2021-03-01'] fn (a Abc) past() { dump(@METHOD) dump(a) @@ -25,18 +27,21 @@ fn (a Abc) simply_deprecated() { dump(a) } -// functions using scheduled deprecations: -@[deprecated(msg: 'custom message 4', after: '3000-12-30')] +// functions using [deprecated_after]: +@[deprecated: 'custom message 4'] +@[deprecated_after: '3000-12-30'] fn future() { dump(@FN) } -@[deprecated(msg: 'custom message 5', after: '2021-03-01')] +@[deprecated: 'custom message 5'] +@[deprecated_after: '2021-03-01'] fn past() { dump(@FN) } -@[deprecated(msg: 'custom message 6', after: '1990-03-01')] +@[deprecated: 'custom message 6'] +@[deprecated_after: '1990-03-01'] fn ancient() { dump(@FN) } diff --git a/vlib/v/checker/tests/module_with_deprecated_structs/module.v b/vlib/v/checker/tests/module_with_deprecated_structs/module.v index c96a3eecb..117aed038 100644 --- a/vlib/v/checker/tests/module_with_deprecated_structs/module.v +++ b/vlib/v/checker/tests/module_with_deprecated_structs/module.v @@ -4,14 +4,16 @@ pub struct Xyz { pub mut: a int b int @[deprecated] - c int @[deprecated(msg: 'c use Xyz.a instead', after: '2021-03-01')] - d int @[deprecated(msg: 'd use Xyz.a instead', after: '2999-03-01')] + c int @[deprecated: 'c use Xyz.a instead'; deprecated_after: '2021-03-01'] + d int @[deprecated: 'd use Xyz.a instead'; deprecated_after: '2999-03-01'] } -@[deprecated(msg: 'use New instead', after: '2021-03-01')] +@[deprecated: 'use New instead'] +@[deprecated_after: '2021-03-01'] pub struct Old {} -@[deprecated(msg: 'use Future instead', after: '2999-03-01')] +@[deprecated: 'use Future instead'] +@[deprecated_after: '2999-03-01'] pub struct Present {} fn some_internal_function() { diff --git a/vlib/v/checker/tests/modules/deprecated_consts.out b/vlib/v/checker/tests/modules/deprecated_consts.out index d0debc237..236cd6407 100644 --- a/vlib/v/checker/tests/modules/deprecated_consts.out +++ b/vlib/v/checker/tests/modules/deprecated_consts.out @@ -2,4 +2,4 @@ vlib/v/checker/tests/modules/deprecated_consts/consts.v:1:1: error: project must 1 | module deprecated_consts | ^ 2 | - 3 | @[deprecated(msg: 'use built-in constant min_i8 instead', after: '2023-12-31')] + 3 | @[deprecated: 'use built-in constant min_i8 instead'] diff --git a/vlib/v/checker/tests/modules/deprecated_consts/consts.v b/vlib/v/checker/tests/modules/deprecated_consts/consts.v index d0db1d49e..5fecce986 100644 --- a/vlib/v/checker/tests/modules/deprecated_consts/consts.v +++ b/vlib/v/checker/tests/modules/deprecated_consts/consts.v @@ -1,4 +1,5 @@ module deprecated_consts -@[deprecated(msg: 'use built-in constant min_i8 instead', after: '2023-12-31')] +@[deprecated: 'use built-in constant min_i8 instead'] +@[deprecated_after: '2023-12-31'] pub const a_deprecated_const = i8(-128) diff --git a/vlib/v/checker/tests/modules/deprecated_module/www/ttt/ttt.v b/vlib/v/checker/tests/modules/deprecated_module/www/ttt/ttt.v index 1ee675dca..2cce10f5f 100644 --- a/vlib/v/checker/tests/modules/deprecated_module/www/ttt/ttt.v +++ b/vlib/v/checker/tests/modules/deprecated_module/www/ttt/ttt.v @@ -1,4 +1,5 @@ -@[deprecated(msg: 'use xxx.yyy', after: '2999-01-01')] +@[deprecated: 'use xxx.yyy'] +@[deprecated_after: '2999-01-01'] module ttt pub fn f() int { diff --git a/vlib/v/fmt/tests/attribute_call_syntax_keep.vv b/vlib/v/fmt/tests/attribute_call_syntax_keep.vv index c18ade462..291bfacf7 100644 --- a/vlib/v/fmt/tests/attribute_call_syntax_keep.vv +++ b/vlib/v/fmt/tests/attribute_call_syntax_keep.vv @@ -1,7 +1,7 @@ @[unsafe()] fn allow_unsafe_parentheses() {} -@[deprecated('use new_fn instead', '2999-10-09')] +@[deprecated('use new_fn instead')] fn old_positional() {} @[deprecated(msg: 'use new_fn instead', after: '2999-10-10')] diff --git a/vlib/v/fmt/tests/attrs_keep.vv b/vlib/v/fmt/tests/attrs_keep.vv index 322c20808..d027a8538 100644 --- a/vlib/v/fmt/tests/attrs_keep.vv +++ b/vlib/v/fmt/tests/attrs_keep.vv @@ -31,5 +31,6 @@ enum Example { value1_again = 1 } -@[deprecated(msg: 'use Example instead', after: '2040-01-24')] +@[deprecated: 'use Example instead'] +@[deprecated_after: '2040-01-24'] pub type Alias = Example diff --git a/vlib/v/parser/attribute.v b/vlib/v/parser/attribute.v index c50d6b0be..88ec98ea4 100644 --- a/vlib/v/parser/attribute.v +++ b/vlib/v/parser/attribute.v @@ -95,12 +95,8 @@ fn (mut p Parser) parse_attr_call(name string, is_at bool, apos token.Pos) []ast base_call_arg_idx = call_arg_idx has_base_arg = true } else { - mut attr_name := '${name}_${positional_arg_idx}' - if name == 'deprecated' && positional_arg_idx == 1 { - attr_name = 'deprecated_after' - } attrs << ast.Attr{ - name: attr_name + name: '${name}_${positional_arg_idx}' has_arg: true arg: arg kind: kind @@ -310,57 +306,23 @@ fn (mut p Parser) attributes() { } fn (mut p Parser) check_deprecated_attributes() { - mut deprecated_call_attr := ast.Attr{} - mut deprecated_after_attr := ast.Attr{} - mut has_deprecated_call_attr := false - mut has_deprecated_after_attr := false + mut deprecated := false + mut deprecated_after := false + mut deprecated_after_pos := token.Pos{} for attr in p.attrs { - if attr.call_name == 'deprecated' { - match attr.name { - 'deprecated' { - deprecated_call_attr = attr - has_deprecated_call_attr = true - } - 'deprecated_after' {} - else { - if attr.call_arg_name.len > 0 { - p.error_with_pos('unknown `${attr.call_arg_name}` argument for `@[deprecated(...)]` attribute', - attr.pos) - } else { - p.error_with_pos('`@[deprecated(...)]` accepts only a deprecation message and an `after` date', - attr.pos) - } - return - } + match attr.name { + 'deprecated' { + deprecated = true } - } - if attr.name == 'deprecated_after' { - if attr.call_name != 'deprecated' { - p.error_with_pos('`@[deprecated_after]` has been removed, use `@[deprecated(..., after: ...)]` instead', - attr.pos) - return + 'deprecated_after' { + deprecated_after = true + deprecated_after_pos = attr.pos } - deprecated_after_attr = attr - has_deprecated_after_attr = true + else {} } } - if has_deprecated_call_attr { - if !deprecated_call_attr.has_arg { - p.error_with_pos('`@[deprecated(...)]` requires a deprecation message', deprecated_call_attr.pos) - return - } - if deprecated_call_attr.kind != .string { - p.error_with_pos('`@[deprecated(...)]` requires a string deprecation message', - deprecated_call_attr.pos) - return - } - if !has_deprecated_after_attr { - p.error_with_pos('`@[deprecated(...)]` requires an `after` date', deprecated_call_attr.pos) - return - } - if deprecated_after_attr.kind != .string { - p.error_with_pos('`@[deprecated(...)]` requires a string `after` date', deprecated_after_attr.pos) - return - } + if deprecated_after && !deprecated { + p.warn_with_pos('@[deprecated_after] is only valid, in the presence of a `@[deprecated]` attribute', + deprecated_after_pos) } } diff --git a/vlib/v/parser/tests/attribute_call_syntax.vv b/vlib/v/parser/tests/attribute_call_syntax.vv index 4129affa2..98c1dc8b3 100644 --- a/vlib/v/parser/tests/attribute_call_syntax.vv +++ b/vlib/v/parser/tests/attribute_call_syntax.vv @@ -2,7 +2,7 @@ @[unsafe()] fn allow_unsafe_parentheses() {} -@[deprecated('use new_fn instead', '2999-10-09')] +@[deprecated('use new_fn instead')] fn old_positional() {} @[deprecated(msg: 'use new_fn instead', after: '2999-10-10')] diff --git a/vlib/v/parser/tests/deprecated_after_without_deprecated.out b/vlib/v/parser/tests/deprecated_after_without_deprecated.out index b8ac127d7..2c1c178b8 100644 --- a/vlib/v/parser/tests/deprecated_after_without_deprecated.out +++ b/vlib/v/parser/tests/deprecated_after_without_deprecated.out @@ -1,5 +1,26 @@ -vlib/v/parser/tests/deprecated_after_without_deprecated.vv:1:1: error: `@[deprecated_after]` has been removed, use `@[deprecated(..., after: ...)]` instead +vlib/v/parser/tests/deprecated_after_without_deprecated.vv:1:1: warning: @[deprecated_after] is only valid, in the presence of a `@[deprecated]` attribute 1 | @[deprecated_after: '2025-10-10'] | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | fn my_fn() { 3 | } +vlib/v/parser/tests/deprecated_after_without_deprecated.vv:5:1: warning: @[deprecated_after] is only valid, in the presence of a `@[deprecated]` attribute + 3 | } + 4 | + 5 | @[deprecated_after: '2025-10-10'] + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 6 | const my_const = 123 + 7 | +vlib/v/parser/tests/deprecated_after_without_deprecated.vv:8:1: warning: @[deprecated_after] is only valid, in the presence of a `@[deprecated]` attribute + 6 | const my_const = 123 + 7 | + 8 | @[deprecated_after: '2025-10-10'] + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 9 | type MyType = u8 + 10 | +vlib/v/parser/tests/deprecated_after_without_deprecated.vv:11:1: warning: @[deprecated_after] is only valid, in the presence of a `@[deprecated]` attribute + 9 | type MyType = u8 + 10 | + 11 | @[deprecated_after: '2025-10-10'] + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 12 | interface MyInterface { + 13 | x int diff --git a/vlib/v/parser/tests/deprecated_call_without_after.out b/vlib/v/parser/tests/deprecated_call_without_after.out deleted file mode 100644 index ea4c0703d..000000000 --- a/vlib/v/parser/tests/deprecated_call_without_after.out +++ /dev/null @@ -1,5 +0,0 @@ -vlib/v/parser/tests/deprecated_call_without_after.vv:1:1: error: `@[deprecated(...)]` requires an `after` date - 1 | @[deprecated('use new_fn instead')] - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 2 | fn old_positional() {} - 3 | diff --git a/vlib/v/parser/tests/deprecated_call_without_after.vv b/vlib/v/parser/tests/deprecated_call_without_after.vv deleted file mode 100644 index 0b3062905..000000000 --- a/vlib/v/parser/tests/deprecated_call_without_after.vv +++ /dev/null @@ -1,8 +0,0 @@ -@[deprecated('use new_fn instead')] -fn old_positional() {} - -@[deprecated(msg: 'use newer_fn instead')] -fn old_named() {} - -@[deprecated(after: '2999-10-10')] -fn old_after_only() {} diff --git a/vlib/v/tests/comptime/comptime_attribute_call_syntax_test.v b/vlib/v/tests/comptime/comptime_attribute_call_syntax_test.v index 18f5708bd..53c3fc90a 100644 --- a/vlib/v/tests/comptime/comptime_attribute_call_syntax_test.v +++ b/vlib/v/tests/comptime/comptime_attribute_call_syntax_test.v @@ -1,5 +1,5 @@ // vfmt off -@[deprecated('use NewPositional instead', '2999-01-01')] +@[deprecated('use NewPositional instead')] struct OldPositional {} @[deprecated(msg: 'use NewNamed instead', after: '2999-01-01')] @@ -14,17 +14,12 @@ struct CustomNamed {} fn test_attribute_call_syntax_positional_and_named_args() { mut positional_msg := '' - mut positional_after := '' $for attr in OldPositional.attributes { if attr.name == 'deprecated' { positional_msg = attr.arg } - if attr.name == 'deprecated_after' { - positional_after = attr.arg - } } assert positional_msg == 'use NewPositional instead' - assert positional_after == '2999-01-01' mut named_msg := '' mut named_after := '' diff --git a/vlib/v/util/diff/diff.v b/vlib/v/util/diff/diff.v index f44db576b..7af32c5d1 100644 --- a/vlib/v/util/diff/diff.v +++ b/vlib/v/util/diff/diff.v @@ -43,43 +43,47 @@ pub enum DiffTool { @[params] pub struct CompareOptions { pub: - tool DiffTool @[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] + tool DiffTool @[deprecated: 'use compare_files or compare_text'; deprecated_after: '2025-12-31'] // Custom args used with the diff command. - args string @[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] + args string @[deprecated: 'use compare_files or compare_text'; deprecated_after: '2025-12-31'] // Sets the environment variable whose value can overwrite a diff command passed to a compare function. // It also enables the use of commands that are not in the list of known diff tools. // Set it to `none` to disable it. - env_overwrite_var ?string = 'VDIFF_CMD' @[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] + env_overwrite_var ?string = 'VDIFF_CMD' @[deprecated: 'use compare_files or compare_text'; deprecated_after: '2025-12-31'] } @[params] pub struct CompareTextOptions { CompareOptions pub: - base_name string = 'base' @[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] - target_name string = 'target' @[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] + base_name string = 'base' @[deprecated: 'use compare_files or compare_text'; deprecated_after: '2025-12-31'] + target_name string = 'target' @[deprecated: 'use compare_files or compare_text'; deprecated_after: '2025-12-31'] } // Allows public checking for the available tools and prevents repeated searches // when using compare functions with automatic diff tool detection. -@[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] +@[deprecated: 'use compare_files or compare_text'] +@[deprecated_after: '2025-12-31'] pub fn available_tools() []DiffTool { return [] } -@[deprecated(msg: 'use compare_files or compare_text', after: '2025-12-31')] +@[deprecated: 'use compare_files or compare_text'] +@[deprecated_after: '2025-12-31'] pub fn find_working_diff_command() !string { return error('deprecated') } // color_compare_files returns a colored diff between two files. -@[deprecated(msg: 'use compare_files instead', after: '2025-12-31')] +@[deprecated: 'use compare_files instead'] +@[deprecated_after: '2025-12-31'] pub fn color_compare_files(_ string, path1 string, path2 string) string { return compare_files(path1, path2) or { '' } } // color_compare_strings returns a colored diff between two strings. -@[deprecated(msg: 'use compare_text instead', after: '2025-12-31')] +@[deprecated: 'use compare_text instead'] +@[deprecated_after: '2025-12-31'] pub fn color_compare_strings(_ string, _ string, expected string, found string) string { return compare_text(expected, found) or { '' } } diff --git a/vlib/x/crypto/chacha20/chacha.v b/vlib/x/crypto/chacha20/chacha.v index dd41f4a57..c1cddd46a 100644 --- a/vlib/x/crypto/chacha20/chacha.v +++ b/vlib/x/crypto/chacha20/chacha.v @@ -189,7 +189,8 @@ pub fn (mut c Cipher) free() { // reset quickly sets all Cipher's fields to default value. // This method will be deprecated. -@[deprecated(msg: 'do not use .reset() at all, create a new Cipher instead', after: '2025-11-30')] +@[deprecated: 'do not use .reset() at all, create a new Cipher instead'] +@[deprecated_after: '2025-11-30'] @[unsafe] pub fn (mut c Cipher) reset() { c.Stream.reset() diff --git a/vlib/x/json2/custom.v b/vlib/x/json2/custom.v index fe4e39bd6..0396cc08f 100644 --- a/vlib/x/json2/custom.v +++ b/vlib/x/json2/custom.v @@ -8,7 +8,8 @@ pub interface JsonEncoder { // Encodable is an interface, that allows custom implementations for encoding structs to their string based JSON representations. -@[deprecated(msg: 'use `to_json` to implement `JsonEncoder` instead', after: '2025-10-30')] +@[deprecated: 'use `to_json` to implement `JsonEncoder` instead'] +@[deprecated_after: '2025-10-30'] pub interface Encodable { json_str() string } diff --git a/vlib/x/json2/decoder2/stub.v b/vlib/x/json2/decoder2/stub.v index 5547d0379..1b1d90734 100644 --- a/vlib/x/json2/decoder2/stub.v +++ b/vlib/x/json2/decoder2/stub.v @@ -3,13 +3,15 @@ module decoder2 import x.json2 // decode decodes a JSON string into a specified type. -@[deprecated(msg: '`decode` has been moved to `x.json2`, use `decode` from `x.json2` instead', after: '2025-10-12')] +@[deprecated: '`decode` has been moved to `x.json2`, use `decode` from `x.json2` instead'] +@[deprecated_after: '2025-10-12'] pub fn decode[T](val string) !T { return json2.decode[T](val)! } // decode_array decodes a JSON string into a specified type. This is the same as decode. -@[deprecated(msg: '`decode_array` has been moved to `x.json2`, use `decode` from `x.json2` instead', after: '2025-03-18')] +@[deprecated: '`decode_array` has been moved to `x.json2`, use `decode` from `x.json2` instead'] +@[deprecated_after: '2025-03-18'] pub fn decode_array[T](src string) !T { return json2.decode[T](src)! } diff --git a/vlib/x/json2/decoder_deprecated.v b/vlib/x/json2/decoder_deprecated.v index 5d74b1ba2..46e0ff386 100644 --- a/vlib/x/json2/decoder_deprecated.v +++ b/vlib/x/json2/decoder_deprecated.v @@ -1,7 +1,8 @@ module json2 // Decodes a JSON string into an `Any` type. Returns an option. -@[deprecated(msg: 'use `decode[json2.Any]` instead', after: '2025-10-10')] +@[deprecated: 'use `decode[json2.Any]` instead'] +@[deprecated_after: '2025-10-10'] pub fn raw_decode(src string) !Any { return decode[Any](src) } diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index 630ae7889..2f7299df4 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -4,7 +4,8 @@ module json2 // encode_pretty ... -@[deprecated(msg: 'use `encode(..., prettify: true)` instead', after: '2025-10-30')] +@[deprecated: 'use `encode(..., prettify: true)` instead'] +@[deprecated_after: '2025-10-30'] pub fn encode_pretty[T](typed_data T) string { return encode(typed_data, prettify: true) } @@ -35,7 +36,8 @@ pub fn (f Any) json_str() string { } // prettify_json_str returns the pretty-formatted JSON string representation of the `Any` type. -@[deprecated(msg: 'use `encode(Any(...), prettify: true)` instead', after: '2025-10-30')] +@[deprecated: 'use `encode(Any(...), prettify: true)` instead'] +@[deprecated_after: '2025-10-30'] pub fn (f Any) prettify_json_str() string { return encode(f, prettify: true) } diff --git a/vlib/x/json2/json2.v b/vlib/x/json2/json2.v index e6f9405e4..251033b7e 100644 --- a/vlib/x/json2/json2.v +++ b/vlib/x/json2/json2.v @@ -238,7 +238,8 @@ pub fn (f Any) bool() bool { } // arr uses `Any` as an array. -@[deprecated(msg: 'use as_array() instead', after: '2026-03-27')] +@[deprecated: 'use as_array() instead'] +@[deprecated_after: '2026-03-27'] pub fn (f Any) arr() []Any { return f.as_array() } -- 2.39.5