diff --git a/doc/manual/rl-next/deprecated-features.md b/doc/manual/rl-next/deprecated-features.md index 450bf6575..1dfbce122 100644 --- a/doc/manual/rl-next/deprecated-features.md +++ b/doc/manual/rl-next/deprecated-features.md @@ -1,7 +1,7 @@ --- synopsis: 'more deprecated features' issues: [] -cls: [2092, 2310] +cls: [2092, 2310, 2311] category: Breaking Changes credits: [piegames, commentator2.0] --- @@ -10,3 +10,4 @@ You can opt in into the old behavior with `--extra-deprecated-features` or any e - `broken-string-indentation` indented strings (those starting with `''`) might produce unintended results due to how the whitespace stripping is done. Those cases will now warn the user. - `broken-string-escape` "escaped" characters without a properly defined escape sequence evaluate to "themselves". This is in most cases unintended behaviour, both for writing regexes, and using legacy or uncommon escape sequences like `\f`. The user will now be warned, if those are present. +- `floating-without-zero` so far, one was able to declare a float using something like `.123`. This can cause confusion about accessing attributes. Floating point numbers must now always include the leading zero, i.e. `0.123` diff --git a/lix/libexpr/parser/grammar.hh b/lix/libexpr/parser/grammar.hh index 09eedb89e..37959fb4f 100644 --- a/lix/libexpr/parser/grammar.hh +++ b/lix/libexpr/parser/grammar.hh @@ -163,10 +163,14 @@ struct integer : seq< not_at<_extend_as_path> > {}; -struct floating : seq< +struct _floating { + struct no_leading_zero : seq, plus> {}; +}; +struct floating : _floating, seq< sor< seq, star, one<'.'>, star>, - seq>, one<'.'>, plus> + seq, one<'.'>, plus>, + _floating::no_leading_zero >, opt, opt>, plus>, not_at<_extend_as_path> diff --git a/lix/libexpr/parser/parser-impl1.inc.cc b/lix/libexpr/parser/parser-impl1.inc.cc index 796036f2a..1dae7d9ad 100644 --- a/lix/libexpr/parser/parser-impl1.inc.cc +++ b/lix/libexpr/parser/parser-impl1.inc.cc @@ -517,6 +517,21 @@ template<> struct BuildAST { } }; +template<> struct BuildAST { + static void apply(const auto & in, ExprState & s, State & ps) { + if (!ps.featureSettings.isEnabled(Dep::FloatingWithoutZero)) { + logWarning( + {.msg = HintFmt( + "Found floating point literal without leading zero. To fix this " + "warning, add a zero before the dot. Use %s to silence this warning", + "--extra-deprecated-feature floating-without-zero" + ), + .pos = ps.positions[ps.at(in)]} + ); + } + } +}; + template<> struct BuildAST { static void apply(const auto & in, ExprState & s, State & ps) { // copy the input into a temporary string so we can call stod. diff --git a/lix/libutil/deprecated-features/floating-without-zero.md b/lix/libutil/deprecated-features/floating-without-zero.md new file mode 100644 index 000000000..5f3509df4 --- /dev/null +++ b/lix/libutil/deprecated-features/floating-without-zero.md @@ -0,0 +1,14 @@ +--- +name: floating-without-zero +internalName: FloatingWithoutZero +timeline: + - date: 2026-01-30 + release: 2.95.0 + cls: [2311] + message: Introduced as warning. +--- +The short-hand notation for floating point numbers `.123` instead of `0.123` is deprecated. +Floating point literals are seldomly used, and saving one character adds little benefit. +This deprecation will free the syntax for possible future new language feature (See NixOS RFC 181). + +To fix this, add a zero before the dot. diff --git a/lix/libutil/meson.build b/lix/libutil/meson.build index 1b279592d..0fadb05cb 100644 --- a/lix/libutil/meson.build +++ b/lix/libutil/meson.build @@ -178,6 +178,7 @@ deprecated_feature_definitions = files( 'deprecated-features/broken-string-escape.md', 'deprecated-features/broken-string-indentation.md', 'deprecated-features/cr-line-endings.md', + 'deprecated-features/floating-without-zero.md', 'deprecated-features/nix-path-shadow.md', 'deprecated-features/nul-bytes.md', 'deprecated-features/rec-set-overrides.md', diff --git a/tests/functional2/lang/float/allowed-depr-syntax.out.exp b/tests/functional2/lang/float/allowed-depr-syntax.out.exp new file mode 100644 index 000000000..41426339f --- /dev/null +++ b/tests/functional2/lang/float/allowed-depr-syntax.out.exp @@ -0,0 +1 @@ +{ a = 0.1; } diff --git a/tests/functional2/lang/float/in-depr-syntax.nix b/tests/functional2/lang/float/in-depr-syntax.nix new file mode 100644 index 000000000..73b45e70d --- /dev/null +++ b/tests/functional2/lang/float/in-depr-syntax.nix @@ -0,0 +1,3 @@ +rec { + a = .1; +} diff --git a/tests/functional2/lang/float/test.toml b/tests/functional2/lang/float/test.toml new file mode 100644 index 000000000..35e875c7e --- /dev/null +++ b/tests/functional2/lang/float/test.toml @@ -0,0 +1,14 @@ +[[test]] +runner = "eval-okay" +in = "in.nix" + +[[test]] +name = "warn" +runner = "eval-okay" +in = "in-depr-syntax.nix" + +[[test]] +name = "allowed" +runner = "eval-okay" +in = "in-depr-syntax.nix" +flags = ["--extra-deprecated-features", "floating-without-zero"] diff --git a/tests/functional2/lang/float/warn-depr-syntax.err.exp b/tests/functional2/lang/float/warn-depr-syntax.err.exp new file mode 100644 index 000000000..d1b3d489c --- /dev/null +++ b/tests/functional2/lang/float/warn-depr-syntax.err.exp @@ -0,0 +1,6 @@ +warning: Found floating point literal without leading zero. To fix this warning, add a zero before the dot. Use --extra-deprecated-feature floating-without-zero to silence this warning + at /pwd/in.nix:2:9: + 1| rec { + 2| a = .1; + | ^ + 3| } diff --git a/tests/functional2/lang/float/warn-depr-syntax.out.exp b/tests/functional2/lang/float/warn-depr-syntax.out.exp new file mode 100644 index 000000000..41426339f --- /dev/null +++ b/tests/functional2/lang/float/warn-depr-syntax.out.exp @@ -0,0 +1 @@ +{ a = 0.1; }