How can you create nominal typing for primitives without struct wrappering?

Short answer based on Shepmaster's excellent answer to a related question: You can't. You have to make a struct and define converters to/from that new struct and the underlying type it supports (the converters won't go two steps, so two types compatible with f32 won't convert to each other directly).

For example:

struct Latitude(f32);

impl Latitude {
    fn from_value(v: f32) -> Result<Latitude, ()> {
        if v >= -90.0 && v <= 90.0 {
            Ok(Latitude(v))
        } else {
            Err(())
        }
    }

    fn value(&self) -> f32 {
        self.0
    }
}

It might seem like pointless boilerplate, but in this case, it does provide the added advantage of ensuring the values are sane, where a latitude above 90 degrees is nonsensical, and should rightly be rejected on construction.