libexpr: Warn on floating point literals without leading or trailing zero

Co-authored-by: Commentator2.0 <lix@crystal-cavern.systems>
Change-Id: I0b58531ad091b22dc59d5717f5d1c8c814b4d2ea
This commit is contained in:
piegames
2026-01-31 15:32:27 +01:00
co-authored by Commentator2.0
parent 56dee9186f
commit cbaa172775
10 changed files with 63 additions and 3 deletions
+2 -1
View File
@@ -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`
+6 -2
View File
@@ -163,10 +163,14 @@ struct integer : seq<
not_at<_extend_as_path>
> {};
struct floating : seq<
struct _floating {
struct no_leading_zero : seq<one<'.'>, plus<digit>> {};
};
struct floating : _floating, seq<
sor<
seq<range<'1', '9'>, star<digit>, one<'.'>, star<digit>>,
seq<opt<one<'0'>>, one<'.'>, plus<digit>>
seq<one<'0'>, one<'.'>, plus<digit>>,
_floating::no_leading_zero
>,
opt<one<'E', 'e'>, opt<one<'+', '-'>>, plus<digit>>,
not_at<_extend_as_path>
+15
View File
@@ -517,6 +517,21 @@ template<> struct BuildAST<grammar::v1::expr::int_> {
}
};
template<> struct BuildAST<grammar::v1::t::floating::no_leading_zero> {
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<grammar::v1::expr::float_> {
static void apply(const auto & in, ExprState & s, State & ps) {
// copy the input into a temporary string so we can call stod.
@@ -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.
+1
View File
@@ -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',
@@ -0,0 +1 @@
{ a = 0.1; }
@@ -0,0 +1,3 @@
rec {
a = .1;
}
+14
View File
@@ -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"]
@@ -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| }
@@ -0,0 +1 @@
{ a = 0.1; }