mirror of
https://github.com/NixOS/nix
synced 2025-07-07 18:31:49 +02:00
libexpr: deprecate the bogus "or"-as-variable
As a prelude to making "or" work like a normal variable, emit a warning any time the "fn or" production is used in a context that will change how it is parsed when that production is refactored. In detail: in the future, OR_KW will be moved to expr_simple, and the cursed ExprCall production that is currently part of the expr_select nonterminal will be generated "normally" in expr_app instead. Any productions that accept an expr_select will be affected, except for the expr_app nonterminal itself (because, while expr_app has a production accepting a bare expr_select, its other production will continue to accept "fn or" expressions). So all we need to do is emit an appropriate warning when an expr_simple representing a cursed ExprCall is accepted in one of those productions without first going through expr_app. As the warning message describes, users can suppress the warning by wrapping their problematic "fn or" expressions in parentheses. For example, "f g or" can be made future-proof by rewriting it as "f (g or)"; similarly "[ x y or ]" can be rewritten as "[ x (y or) ]", etc. The parentheses preserve the current grouping behavior, as in the future "f g or" will be parsed as "(f g) or", just like "f g anything-else" is grouped. (Mechanically, this suppresses the warning because the problem ExprCalls go through the "expr_app : expr_select" production, which resets the cursed status on the ExprCall.)
This commit is contained in:
parent
68ba6ff470
commit
da332d678e
6 changed files with 79 additions and 8 deletions
12
tests/functional/lang/eval-okay-deprecate-cursed-or.err.exp
Normal file
12
tests/functional/lang/eval-okay-deprecate-cursed-or.err.exp
Normal file
|
@ -0,0 +1,12 @@
|
|||
warning: at /pwd/lang/eval-okay-deprecate-cursed-or.nix:3:47: This expression uses `or` as an identifier in a way that will change in a future Nix release.
|
||||
Wrap this entire expression in parentheses to preserve its current meaning:
|
||||
((x: x) or)
|
||||
Give feedback at https://github.com/NixOS/nix/pull/11121
|
||||
warning: at /pwd/lang/eval-okay-deprecate-cursed-or.nix:4:39: This expression uses `or` as an identifier in a way that will change in a future Nix release.
|
||||
Wrap this entire expression in parentheses to preserve its current meaning:
|
||||
((x: x + 1) or)
|
||||
Give feedback at https://github.com/NixOS/nix/pull/11121
|
||||
warning: at /pwd/lang/eval-okay-deprecate-cursed-or.nix:5:44: This expression uses `or` as an identifier in a way that will change in a future Nix release.
|
||||
Wrap this entire expression in parentheses to preserve its current meaning:
|
||||
((x: x) or)
|
||||
Give feedback at https://github.com/NixOS/nix/pull/11121
|
1
tests/functional/lang/eval-okay-deprecate-cursed-or.exp
Normal file
1
tests/functional/lang/eval-okay-deprecate-cursed-or.exp
Normal file
|
@ -0,0 +1 @@
|
|||
0
|
11
tests/functional/lang/eval-okay-deprecate-cursed-or.nix
Normal file
11
tests/functional/lang/eval-okay-deprecate-cursed-or.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
let
|
||||
# These are cursed and should warn
|
||||
cursed0 = builtins.length (let or = 1; in [ (x: x) or ]);
|
||||
cursed1 = let or = 1; in (x: x * 2) (x: x + 1) or;
|
||||
cursed2 = let or = 1; in { a = 2; }.a or (x: x) or;
|
||||
|
||||
# These are uses of `or` as an identifier that are not cursed
|
||||
allowed0 = let or = (x: x); in map or [];
|
||||
allowed1 = let f = (x: x); or = f; in f (f or);
|
||||
in
|
||||
0
|
Loading…
Add table
Add a link
Reference in a new issue