Topics:

👻 PhantomData Example: RefWithFlag via @DanielPBank

Repo: https://github.com/danielbank/ref-with-flag

An interesting bit-level hacking example using 👻 PhantomData from the book Programming Rust by Jim Blandy and Jason Orendorff. The code takes advantage of the fact that many types have to be placed at even addresses in memory, so that the least significant bit (LSB) is always zero. If a type satisfies this constraint, we can utilize the LSB to store the value of a flag while still maintaining the information of the original memory address. When we set the RefWithFlag ptr_and_bit, we bitwise-and the flag with the LSB. When we get reference, we mask off the flag value. When we read the flag, we just return whether the LSB was 0 or 1.

In the example, PhantomData is necessary for Rust to know how to treat lifetimes in code that use RefWithFlag. Without it, the code won't compile:

// This won't compile
pub struct RefWithFlag<'a, T: 'a> {
  ptr_and_bit: usize
}

Rant: PhantomData is Silly

@mysteriouspants finds PhantomData kind of irritating. He wishes the language could just accept some template args that aren't shown in the implementation. PhantomData under the hood if you will.

Fundamentally I think that struct {} should be legal. Silly, but legal. Having to know that I need to add a magical zero-size type so every template parameter is used in the default constructor is just silly.

@NathanBrown had the observation that Rust was using PhantomData to work around what would otherwise be compiler emitted error of an unused T in struct {}.

The Rust RFC Book has a section on the motivation for requiring the use of PhantomData.

⛓️ New Array Features in Rust 2021 Nightly via @jacobrosenthal

Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=efa6fb4de4d30d4813a8790fefbb7bed

Jacob showed off some of the new features for arrays in Rust 2021 nightly. In no_std we dont have vec type, so well often use something like heapless::Vec which is backed by arrays. For example:

let e: heapless::Vec<i32, LEN> = A.iter().zip(B.iter()).map(|(a, b)| a + b).collect();

This works fine but you have to pass the two generics which is ugly and its not an array or vec type so you have to use it as slices or unsafe it into an array or vec. Vec::new() allocates some size like 20 for you under the hood, and then allocates more if you add a 21st item. To add something you call .push() which never fails.

However in no_std we dont have an allocator so we dont have vec. Eventually the Rust language team is basically going to merge something like heapless::Vec, a stack-based vec into the language. It would have methods like try_push instead of push because it could fail. In the mean time theyre merging more features for arrays.

The following examples work in nightly at the time of writing:

  • Create an array from a function with the const generic saying how many times to run it!
let a: [i32; 5] = core::array::from_fn(|n| n as i32 + 1);
println!("{:?}", a);
  • Arrays support a few iterator like functions like map?! even though theyre not an iterator
let b: [i32; 5] = a.map(|v| v + 1);
println!("{:?}", b);
  • Zip also works
let c = a.zip(b);
println!("{:?}", c);

Jacob wrote previously about Iterators in a training he gave at AI/ML Devfest.

👹 OS Development on a Raspberry Pi via @JesusGuzmanJr

Jesus is working throuugh Operating System development tutorials in Rust on the Raspberry Pi.

User Space, Microcontrollers, and Security

Although the Raspberry Pi is a microprocessor and not a microcontroller, the conversation come up about microcontrollers and their memory space. Microcontrollers don't have a user space, they are single user systems and there is no reason to protect your memory. WASM is very similar in that you don't have any permissions and you can't escape the sandbox. You can take a Cortex-M and use syscall traps to have multiple user-run programs on it at the same time. An example of that is Tock, an embedded operating system designed for running multiple concurrent, mutually distrustful applications on Cortex-M and RISC-V based embedded platforms (it just so happens to be written in Rust).

Other microcontroller links:

🦇 Deconstructing Floating Point Numbers via @NathanBrown

Repo: https://github.com/ngbrown/rust-in-action

Nathan is still working through the projects in the Rust in Action book by Tim McNamara. In the Chapter 5 project, he was deconstructing a float into its parts.

His crate you should know is fixed which provides fixed-point numbers. A fixed point number just means that there are a fixed number of digits after the decimal point.

🐉 Rust Shaders via @EtienneLaurin

Etienne is interested in shaders and was looking at Rlsl, short for Rust Like Shading Language. The project has been deprecated in favor of rust-gpu, a project from Embark Studios. Embark also made a Rust wrapper for SPIR-V tools which is used in rust-gpu. These projects were brought up previously at a Desert Rust meetup where we talked about game development in Rust.

Crates You Should Know

  • ghost: Define your own PhantomData
  • fixed: Fixed-point numbers