9daa5f9177
- This PR should fix/close: - #11266 - #12893 - #13736 - #13748 - #14170 - It doesn't fix #13736 though unfortunately. The issue there is at a different level to this fix (I think probably in the lexing somewhere, which I haven't touched). # The Problem The linked issues have many examples of the problem and the related confusion it causes, but I'll give some more examples here for illustration. It boils down to the following: This doesn't type check (good): ```nu def foo []: string -> int { false } ``` This does (bad): ```nu def foo [] : string -> int { false } ``` Because the parser is completely ignoring all the characters. This also compiles in 0.100.0: ```nu def blue [] Da ba Dee da Ba da { false } ``` And this also means commands which have a completely fine type, but an extra space before `:`, lose that type information and end up as `any -> any`, e.g. ```nu def foo [] : int -> int {$in + 3} ``` ```bash $ foo --help Input/output types: ╭───┬───────┬────────╮ │ # │ input │ output │ ├───┼───────┼────────┤ │ 0 │ any │ any │ ╰───┴───────┴────────╯ ``` # The Fix Special thank you to @texastoland whose draft PR (#12358) I referenced heavily while making this fix. That PR seeks to fix the invalid parsing by disallowing whitespace between `[]` and `:` in declarations, e.g. `def foo [] : int -> any {}` This PR instead allows the whitespace while properly parsing the type signature. I think this is the better choice for a few reasons: - The parsing is still straightforward and the information is all there anyway, - It's more consistent with type annotations in other places, e.g. `do {|nums : list<int>| $nums | describe} [ 1 2 3 ]` from the [Type Signatures doc page](https://www.nushell.sh/lang-guide/chapters/types/type_signatures.html) - It's more consistent with the new nu parser, which allows `let x : bool = false` (current nu doesn't, but this PR doesn't change that) - It will be less disruptive and should only break code where the types are actually wrong (if your types were correct, but you had a space before the `:`, those declarations will still compile and now have more type information vs. throwing an error in all cases and requiring spaces to be deleted) - It's the more intuitive syntax for most functional programmers like myself (haskell/lean/coq/agda and many more either allow or require whitespace for type annotations) I don't use Rust a lot, so I tried to keep most things the same and the rest I wrote as if it was Haskell (if you squint a bit). Code review/suggestions very welcome. I added all the tests I could think of and `toolkit check pr` gives it the all-clear. # User-Facing Changes This PR meets part of the goal of #13849, but doesn't do anything about parsing signatures twice and doesn't do much to improve error messages, it just enforces the existing errors and error messages. This will no doubt be a breaking change, mostly because the code is already broken and users don't realise yet (one of my personal scripts stopped compiling after this fix because I thought `def foo [] -> string {}` was valid syntax). It shouldn't break any type-correct code though. |
||
---|---|---|
.. | ||
src | ||
std | ||
tests | ||
Cargo.toml | ||
CONTRIBUTING.md | ||
LICENSE | ||
README.md | ||
testing.nu |
Welcome to the standard library of `nushell`!
The standard library is a pure-nushell
collection of custom commands which
provide interactive utilities and building blocks for users writing casual scripts or complex applications.
To see what's here:
> use std
> scope commands | select name description | where name =~ "std "
#┬───────────name────────────┬───────────────────description───────────────────
0│std assert │Universal assert command
1│std assert equal │Assert $left == $right
2│std assert error │Assert that executing the code generates an error
3│std assert greater │Assert $left > $right
4│std assert greater or equal│Assert $left >= $right
... ...
─┴───────────────────────────┴─────────────────────────────────────────────────
🧰 Using the standard library in the REPL or in scripts
All commands in the standard library must be "imported" into the running environment
(the interactive read-execute-print-loop (REPL) or a .nu
script) using the
use
command.
You can choose to import the whole module, but then must refer to individual commands with a std
prefix, e.g:
use std
std log debug "Running now"
std assert (1 == 2)
Or you can enumerate the specific commands you want to import and invoke them without the std
prefix.
use std ["log debug" assert]
log debug "Running again"
assert (2 == 1)
This is probably the form of import you'll want to add to your env.nu
for interactive use.
✏️ contribute to the standard library
You're invited to contribute to the standard library! See CONTRIBUTING.md for details