The Types track left you with a generic Point<T> you couldn't do much with — you can't add or print a bare T. Traits are the answer. A trait defines shared behavior that many types can implement, and it's how Rust does polymorphism.
What a trait is
A trait is a set of method signatures a type promises to provide. If you've used interfaces in Java or C#, the shape is familiar — but Rust's traits go further, with default methods, generic bounds, and associated types. You declare one with trait Name { ... }, listing the methods implementors must supply.
Implementing a trait
impl TraitName for TypeName { ... } says 'this type provides this behavior.' One type can implement many traits; one trait can be implemented by many types. That many-to-many web is how Rust composes behavior without inheritance hierarchies.
The coherence rule
One guardrail: you can implement a trait for a type only if you own the trait or the type — the 'orphan rule.' It prevents two crates from implementing the same trait for the same type in conflicting ways. It's why you sometimes wrap a foreign type in your own struct (the newtype pattern) to implement a foreign trait on it.