Implementing a trait for multiple types at once

Solution 1:

The only way to implement a trait once for many concrete types is to implement a trait for all types already implementing another trait.

For example, you can implement a marker trait Xed and then:

impl<T> Double for T
where
    T: Xed,
{
    fn double(&self) {
        /* ... */
    }
}

However, Rust has principled generics. The only thing that you know about T in the previous implementation is that T implements the Xed trait, and therefore the only associated types/functions you can use are those coming from Xed.

A trait cannot expose a field/attribute, only associated types, constants and functions, so Xed would need a getter for x (which need not be called x).

If you wish to rely on syntactic (and not semantic) properties of the code, then use macros.

Solution 2:

Creating a macro also solves your problem:

struct A {
    x: u32,
}

struct B {
    x: u32,
}

trait T {
    fn double(&self) -> u32;
}

macro_rules! impl_T {
    (for $($t:ty),+) => {
        $(impl T for $t {
            fn double(&self) -> u32 {
                self.x * 2
            }
        })*
    }
}

impl_T!(for A, B);

fn main() {}

Solution 3:

Using the duplicate attribute macro you can do the following:

use duplicate::duplicate;
#[duplicate(name; [A]; [B])]
impl T for name {
    fn double(&self) -> u32 {
        self.x * 2
    }
}

This will expand to two identical implementations for the two structs. I know you said you didn't want to use macros, but I interpret that as meaning you don't want to roll your own macro, so I think this is a good compromise.

You could also use duplicate to avoid repeating your struct definitions:

use duplicate::duplicate;
#[duplicate(name; [A]; [B])]
struct name {
    x: u32,
}

Or go all-out if you for some reason need two identical structs with identical implements (at this point we should begin questioning why we need 2 structs at all :D):

use duplicate::duplicate;
#[duplicate(
     mod_name struct_name; 
     [a]      [A]; 
     [b]      [B];
)]
mod mod_name {
    pub struct name {
        x: u32,
    }
    impl T for name {
        fn double(&self) -> u32 {
            self.x * 2
        }
    }
}
mod a;
mod b;
pub use self::{a::*, b::*};