Skip to content

Instantly share code, notes, and snippets.

@asaaki
Forked from rust-play/playground.rs
Last active July 16, 2023 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asaaki/3ca25e6ba39f4753e0a44ea5ec229822 to your computer and use it in GitHub Desktop.
Save asaaki/3ca25e6ba39f4753e0a44ea5ec229822 to your computer and use it in GitHub Desktop.
[rust] How to avoid leaking trait bounds (to avoid such changes to be breaking changes)
// https://rust-lang.github.io/api-guidelines/future-proofing.html
/*
The following traits should never be used in bounds on data structures:
* Clone
*/
#[derive(Clone, Debug)]
pub struct Item(i32);
// not good:
#[derive(Clone, Debug)]
pub struct LeakyContainer<T: Clone> {
pub items: Vec<T>,
}
impl<T: Clone> LeakyContainer<T> {
pub fn new(items: &[T]) -> Self {
Self {
// .to_vec requires T to be Clone;
// this trait bound then starts leaking to the outside
items: items.to_vec(),
}
}
}
// good:
#[derive(Clone, Debug)]
pub struct SolidContainer<T> {
pub items: Vec<T>,
}
impl<T> SolidContainer<T> {
pub fn new<I: Into<Vec<T>>>(items: I) -> Self {
Self {
items: items.into(),
}
}
}
fn main() {
let items = [Item(1), Item(2), Item(3)];
let leaky = LeakyContainer::new(&items[..]);
let solid = SolidContainer::new(&items[..]);
println!("{leaky:?}\n{solid:?}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment