Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Why can’t I write TryFrom>?
I have an API that I want to call that takes C strings. I don’t want to pass in a string which contains a \0
character, and to avoid adding another case to the Result
type I’m returning, I want to just protect against that at the type level, so I do something like this:
use std::ffi::OsStr;
struct SpecialStr(OsStr);
impl SpecialStr {
unsafe fn new_unchecked(source: &OsStr) -> &Self {
unsafe { &*(source as *const OsStr as *const SpecialStr) }
}
}
impl<'a, S: AsRef<OsStr>> TryFrom<&'a S> for &'a SpecialStr {
type Error = ();
fn try_from(value: &'a S) -> Result<Self, Self::Error> {
Ok(unsafe { SpecialStr::new_unchecked(value.as_ref()) })
}
}
But when doing so, I get the error:
error[E0119]: conflicting implementations of trait `TryFrom<&_>` for type `&SpecialStr`
--> src/lib.rs:18:1
|
18 | impl<'a, S: AsRef<OsStr>> TryFrom<&'a S> for &'a SpecialStr {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> TryFrom<U> for T
where U: Into<T>;
where there is decidedly not an implementation of S.into() -> &SpecialStr
for any S
(or any type at all).
I’ve also tried the version where I don’t play the same stupid pointer tricks and do this instead:
struct FancyStr<'a>(&'a OsStr);
and it has the same problem.
I know I can just try being less clever, but also I really don’t understand why it seems to be giving me a diagnostic about an impl that clearly does not exist.
(At this point, I am also sorely tempted by the prospect of Just Panic When You Get A String With A Zero Byte In It because what reasonable person would do such a thing?)
2 posts - 1 participant
🏷️ rust_feed