Status
borrow-core is young and still changing, but you can write real programs in it today. This page says what works, what you are likely to trip over, and what is coming. It is the one place the book lists what isn’t built yet.
What works today
- Ownership and borrows:
immandmutborrows,&xand&mut x, borrow blocks,let mut(Ownership and borrows) - Functions and closures, reusable and one-shot (Functions as values)
- Numbers:
i32,i64,u8,f32,f64; integer division by zero raises an error you can handle (Numbers, Division) - Records and variants with
match(Records and variants) - Recursive data: lists and trees, folds, and types that hold a
Vec, an array or a map of themselves (Data and generics) - Recursion, with deep recursion on the heap (Recursion)
- Arrays, views and slices: split, swap, sort (Arrays)
- Vectors, buffers and UTF-8 strings (Buffers and strings)
- Generics: generic functions and types (Generic functions)
polyfamilies: operators, equality, hashing and order at your own types (polyfamilies)- Hash maps and sets (Maps and sets)
- Loops: counted
forwithbreak,continueandelse;whileandloop; bounded runs withdiv_fuel(Iteration) - Generators and
|>pipelines (Generators) - Effects and handlers, with effects inferred (Effects and handlers)
- Errors as
raiseand handlers, no?needed (Errors) - I/O: standard input, output and error, the clock and the command-line arguments (Input and output)
- Async tasks:
spawn,resume,cancel, logged and scoped tasks, and a task that borrows its own data acrossawait(Async tasks) - Two targets: WebAssembly (
bcc run) and native code through LLVM (bcc run --native), with the same I/O on both (Getting started) - Safety proved in Lean: a program that compiles can’t use memory after freeing it, free it twice or leak it (Safety guarantees)
Things you’ll run into
Types and syntax
- The unit type is spelled
1, not()(#148). - No unary minus,
+=, or bitwise and shift operators: write0 - x,x = x + 1,host[and32](a, b),host[shl64](n, 3)(#583). - No indexing sugar such as
v[i](#143). total,leaf,nodeandswapare reserved, so they can’t be names of variables or functions.==doesn’t compare twobools; useiformatch.- An
iforborrowblock can’t be a call’s argument: bind it withletfirst.
Borrows
&mut r.fielddoesn’t parse: take the record apart, borrow the field, and build it again.&xand&mut xmust be the whole call of aletor statement: writelet n = len(&v); f(n), notf(len(&v))(#510).- A heap cell can’t be lent with
&cto a function that does I/O or performs an answering (fn) operation; lend it with a block instead,borrow imm c { r -> show(r) }. A function that mayraisetakes&clike any other. - A borrow can’t be lent on with
&mut m; pass it and hand it back instead (Borrow blocks). - Two borrow blocks can’t be nested over two different owners; inside a block, lend the second
owner to a call with
&dinstead. - A
forover a view of a buffer or string must be in a function that takes the view, not directly inside theborrowblock (a view of an array works either way).
Data
- A text view can be used only once, so a word can’t be looked up in a map and then inserted as a key.
- Folds (
fold_imm,fold_own,fold_reuse) don’t walk a type that holds aVecof itself; write the recursion, as in Collections of recursive data.
Loops, generators and effects
- The body of a
whileorloopcan’t perform an operation that a handler in the program serves: noraise, no division by a variable, and no operation of your own effects. The platform’s I/O works. Use a countedfor, or do it after the loop (#522). - A generator can’t use a capability, such as standard output, across a
yield. The body of aforover a library adapter (map,filter,take, …), or over a generator that calls another generator directly, can’t do I/O: collect the values in the loop and print after it. - A callback stored with its effects, rather than called, isn’t supported yet (#161).
- An effect can’t mix answering (
fn) and control (ctl) operations, and an operation can’t answer with a borrow into its handler’s state. - An error can’t carry an owned value yet (#215).
- A reusable closure that keeps state between calls (Rust’s
FnMut) has no surface syntax yet; a handler with state does the same job (Effects and handlers).
I/O and async
- A program can’t set its exit status.
- Async is cooperative and single-threaded, with no event loop over real I/O, platform timers or wakers yet (#52).
- A task can hold a
mutborrow of its own cell acrossawait, and a task ofspawn_ina borrow lent from outside its scheduler. Other borrows held across anawaitor ayieldare not implemented yet (Async tasks). Two tasks can’t share one output stream.
Performance
- Some programs are still slower than their Rust versions (#213).
On the roadmap
- Modules and packages (#63)
- Traits, or bounds on type parameters, and derived cases (#489)
- Operator sugar: unary minus, compound assignment, bitwise and shifts (#583)
- Files, environment variables and randomness; networking (#597)
- Threads and parallelism (#212)
- Interior mutability (#119)
- Unsafe code and a C FFI (#79)
- Panics and backtraces (#192)
- Libraries: JSON (#65), regular expressions (#225)
- Sized types (#72)