I’ve been learning it off and on for a while now, and I’m quite happy to see the breaking
changes slow down.
As part of learning rust I’ve played around implementing things that would be
normally done in c or c++;
one of those is the old trick of hot-swapping code by reloading a shared library at runtime.

The rest of this post assumes that you have a pretty fair knowledge of rust.
If not, you should probably start with the rust book.

Project setup:

First we’ll set up a folder to develop from:
mkdir ./rust-hotswap && cd ./rust-hotswap
and a source dir:
mkdir ./src.

We use #[no_mangle] to prevent rust from mangling the function name, and extern "C" to export it in the C linkage style. We use io::stdout() to get a handle to stdout instead of using the println! macro because the macro causes an illegal instruction error on exit. I’m not sure exactly why this occurs but i’m sure it has to do with unsafely sharing the stdout handle. It’s probably a good idea to do it this way anyhow, but I might want to look into that later.

Now to actually load the library.

The first important thing to know is that rustc appends a versioning hash to libraries it produces.
We could possibly recreate this hash, or we could just look for a dynamic library next to the
executable. To do this we use std::os::self_exe_path to get the directory the executable is in,
then use it to create a search pattern for glob to find the dynamic library we built.

We have a small helper function get_dylib_path_pattern that appends a platform specific file extension using rust’s cfg conditional compilation and target_os.
After finding the library we can then use the (unstable!) std::dynamic_lib::DynamicLibrary api to load the library, and resolve the symbol for do_tick, which we can then call.

We’ll wrap up the loading and calling bits in a helper function.

Lastly we can throw in a println! and a keypress read between ticks to puase the program, and alert the user that it is now safe to modify the code.
This allows you to finally do the following:

1) Run: cargo run.
2) Edit src/lib.rs to write something else to stdout.
3) From another shell cargo build.
4) Hit enter in the first shell after cargo build completes.
5) The output this time should now match your modified code.

A real usecase for this would be EG game development, where the game is implemented as a small wrapper executable and the rest as methods in a dynamic library, you can pass in a struct full of globals to the library and between ticks reload the library with modified code. You might monitor the source for changes to the library, and rebuild and reload between ticks during development.
In anycase, it’s a cool trick.