The title suggested something very different to me though. Often, “kinds of polymorphism” means some selection from parametric polymorphism, subtype polymorphism, and ad hoc polymorphism. Of those, Rust has two: parametric and subtype. Parametric polymorphism is provided with Rust’s “generics” feature with trait bounds; subtype polymorphism arises with lifetime “outlives”-bounds, which form a subtyping relationship where longer bounds are subtypes of shorter bounds.
I’ve also been down this rabbithole, here are some thoughts :) https://github.com/jlricon/rust-impl-struct
You could have .into_enum() be part of the trait. That way you don’t have to worry about non-first-class implementations.