I had some previously working code that called as_ref on a Cow<str> to get a &str. The code broke after updating my dependencies (with cargo update), failing to compile with an error about missing type annotations:
error[E0283]: type annotations needed
--> src/ui/pages/phoneme_tables/custom/move_phoneme_popover.rs:106:54
|
106 | .label(phoneme.user_symbol(extras.get(&phoneme)).as_ref())
| ^^^^^^
|
= note: multiple `impl`s satisfying `Cow<'_, str>: AsRef<_>` found in the following crates: `alloc`, `typed_path`:
- impl<T> AsRef<T> for Cow<'_, T>
where T: ToOwned, T: ?Sized;
- impl<T> AsRef<typed_path::common::utf8::path::Utf8Path<T>> for Cow<'_, str>
where T: typed_path::common::utf8::Utf8Encoding;
help: try using a fully qualified path to specify the expected types
|
106 - .label(phoneme.user_symbol(extras.get(&phoneme)).as_ref())
106 + .label(<Cow<'_, str> as AsRef<T>>::as_ref(&phoneme.user_symbol(extras.get(&phoneme))))
I spent some time debugging the issue. It seems to be caused by an update to the zip dependency, which adds a dependency on typed-path.
I've created a small reproduction of the issue:
use std::borrow::Cow;
// use typed_path::Path;
fn main() {
let x = Cow::Borrowed("hello");
let y = x.as_ref();
println!("{y}");
}
This code compiles fine as-is, but fails to compile if the use typed_path::Path line is uncommented (after running cargo add typed-path, of course).
However, my code doesn't import typed_path::Path anywhere, and the file that contains the compiler error doesn't import zip.
This was a surprising error to encounter, and I'm not really sure how best to avoid it, either as a downstream user of zip, or as a hypothetical library author adding such a dependency.
- How should I, as a dependant on the
zipcrate, avoid this? Is my use ofCow::as_refconsidered "brittle"? Should I avoid it writing code likefunction(foo.as_ref()), preferring something likelet bar: &str = foo.as_ref(); function(bar)? - How could the
zipauthors (or the authors of any other library) avoid causing this in future? Should they? Is there a way that they or others would be able to tell that adding thetyped-pathdependency would constitute a break in downstream code usingCow<str>::as_ref? - Would this be considered a semver-breaking update to
zip? - Adding a non-exported dependency doesn't usually cause semver breaks, as far as I know. Have the
typed-pathdevelopers "done something wrong"?
Thanks for getting through all these complex questions ![]()