Another idiomatic pattern is using shadowing to transform something using itself as input:
let x = Foo::new().stuff()?; let x = Bar::new(x).other_stuff()?;
So with the math example and what the poster above said about type changing, most rust code I write is something like:
let x: plain_int = 7
let x: added_int = add(x, 3);
let x: divided_int = divide(x, 2);
where the function signatures would be fn add(foo: plain_int, int); fn divide(bar: added_int, int);
and this can't be reordered without triggering a compiler error.