top | item 32799969

(no title)

jefftime | 3 years ago

Do you have an example where adding a function to the std library broke existing code? I wasn't aware this was possible

discuss

order

jmillikin|3 years ago

The canonical example is when a library has extended a standard trait -- adding a new trait method can cause errors due to ambiguity.

Say you had the following code:

  mod rs_std {
      pub trait StdGreetings {
          fn hello(&self) { println!("Hello!"); }
      }
  }

  use rs_std::StdGreetings;

  trait MyGreetings: rs_std::StdGreetings {
      fn good_morning(&self) { println!("Good morning!"); }
  }

  struct MyGreeter;

  impl StdGreetings for MyGreeter {}
  impl MyGreetings for MyGreeter {}

  fn main() {
      let g = MyGreeter{};
      g.hello();
      g.good_morning();
  }
This is totally valid, it'll compile, and it's not an unreasonable use case to want to extend standard traits like `io::Write`.

The problem is that a newer version of the standard library might have this:

  pub trait StdGreetings {
      fn hello(&self) { println!("Hello!"); }
      
      fn good_morning(&self) { println!("Good morning!"); }
  }
And now that existing code will fail to compile.

The Rust team's answer to this is "crater runs", where they build the current versions of all packages on crates.io with the new compiler to predict the ecosystem impact of a potential change.

physPop|3 years ago

> The Rust team's answer to this is "crater runs", where they build the current versions of all packages on crates.io with the new compiler to predict the ecosystem impact of a potential change.

Wow! I never knew this. What a fantastic use case for good, automatic, CI.

umanwizard|3 years ago

It is possible. If you implement a trait with a function “foo” on some stdlib type, then “foo” is added to the type’s inherent impl, the inherent function will now be called instead of the one in your trait when doing x.foo()