#inline[always], i32/i64/f32/f64, trait vs macros

Suppose we have a bunch of geometry classes like:

Vec2(x: f32, y: f32), Vec3(x: f32, y: f32, z: f32), Rect2(left_bot: Vec2, right_top: Vec2), ...

and we want to make it generic over f32/f64/i32/i64.

One approach is to define:

pub trait CanBeDim : ... {
  pub fn add(&self, rhs: &CanBeDim) -> CanBeDim { ... }

impl CanBeDim for i32 { ... }
impl CanBeDim for f32 { ... }
impl CanBeDim for i64 { ... }
impl CanBeDim for f64 { ... }

However, if I am reading rust - Can #[inline] be used in both trait method declarations and implementations? - Stack Overflow correctly, we can not force trait functions to be #[inline(always)] ?

Does this mean, if I want to have these basic geometric primitives over a number of fundamental types and I want the ops to be #[inline(always)] then the only route is to go macro_rules! ?

I would put the attribute on the implementation and see. That Stack Overflow is ambiguous to me (and also a bit old), talking about methods with no body (the declaration maybe?) and trait objects.

(Run that playground as "ASM" to see the differences.)

That means methods like bar in

trait Foo {
    fn bar();
    fn baz() {}

as opposed to baz.

bar is the method with no body.