Recently I was involved in quite a few std related PRs and ideas that turned out to be difficult to implement because of backwards compatibility. For example, my own "impl
IntoIterator for arrays" and this impl
Add<char> for String> one (btw I agree with closing it). It feels like only few (if any) people were really aware that those future changes would be hard or impossible to do when designing the current API.
So I thought about creating some kind of list with examples of backwards compatibility footguns for people designing an API. This can be used by everyone but would mainly be useful for high-stakes APIs like libstd.
Any opinions? Is there something like this already? If not and you think it could be useful, I would take a stab at writing a list soon.
@Lukas Kalbertodt would it be possible to just add tests to libstd to cover those cases ?
(I think that documenting backward-compat footguns is something worth doing, but ideally we would do so in such a way that backward-incompatible changes break libstd test suite)
@gnzlbg Interesting idea. So those can't be simple unit tests, right? I think writing automated tests for this is really really hard. But surely worth investigating.
We have run-pass, run-fail, compile-pass, and compile-fail tests in rustc.
So if we have a pattern that should compile and pass some assert succesfully, you add a run-pass test, and if the pattern should not compile, you add a compile-fail test.
Right now most of these are all in the src/test directory, and I would be fine with adding libstd tests there if that simplifies things, e.g., for compile-fail tests at least.
If this becomes a common thing it shouldn't be too hard to set up compile-fail tests for libstd or liballoc themselves in their directories.
no we really don't need separate directories
like, these tests can just go in
I think I didn't properly explain myself. I am talking about general patterns. Like take the
Add<char> for String problem. The root problem here is that when resolving a trait method call and there is only one implementation, the compiler tries eagerly to coerce the argument expression into the expected type. Type inference is also working in that case. So adding a second impl means that those eager coercion and type inferences are not made anymore. This can lead to breakage. Just check the link above for more information.
We can of course add specific tests for
String, but I am talking about the general pattern here. The problem was that we weren't aware of that problem when designing the
Add impls for
String, so we couldn't have added a test either. So we would need a lint that checks all types/impls of the public API for these kinds of problems. And that's not a simple test.
But maybe I should just start creating the list, as we can discuss more properly then ^_^
@Lukas Kalbertodt This is the kind of thing we started the libs forge docs for :slight_smile: