APIs don't just depend on function signatures #134818
Labels
A-crate-compat
Area: Impacting SemVer compatibility of crates in the ecosystem
C-bug
Category: This is a bug.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
T-lang
Relevant to the language team, which will review and decide on the PR/issue.
Normally Rust has the really nice property that I can focus on getting each function to compile in isolation, without worries that
refactoring the body of a function will break backwards compatibility. However, I recently stumbled across a bizarre circumstance
where that isolation appears to be violated. After spending a day pruning it down to a small-ish reproducible example:
I find the way Rust handles this code to be problematic in a couple of ways:
First, the error message is nonsensical:
This could be an acceptable error message if it were pointing to code in
downcast
, but it's pointing to code indoes_not_compile
which doesn't even (directly) useAsyncFrom
. This really threw me for a loop, especially because I encountered it while working on a large codebase.Second, I was surprised to discover that the body of
get_thing
influences whether the code compiles, not just the signature ofget_thing
. Inliningdowncast
intoget_thing
appears to resolve the compile error without changing code indoes_not_compile
. Alternatively, adjusting the body ofdoes_not_compile
to avoid callingdoes_compile
fixes the compile error. So, the compile only fails due to the interaction between two different function bodies... which feels very un-Rusty to me.After seeking help in the community discord, one 🐸, two 🐸, tree 🐸 explained that combining closures with existential types allows you to violate the usual Rust philosophy that only function signatures matter. I feel like this is extremely unfortunate, both because it destroys local reasoning and because it makes it extra hard to be sure you haven't broken backwards compatibility when merely refactoring a function body.
Per one 🐸, two 🐸, tree 🐸's suggestion, I'm writing this issue in the hopes that providing counterintuitive example code may help push for the current behavior to be changed. I'd really like it if I could worry about getting each function to compile one at a time, without having to consider the possibility that different function bodies may interact negatively.
Thank you!
Meta
(this behavior is also exhibited on beta and nightly versions of Rust)
rustc --version --verbose
:(the backtrace doesn't reveal anything new:)
Backtrace
The text was updated successfully, but these errors were encountered: