Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trait associated type bounds are stable #251

Closed
eduardosm opened this issue Mar 6, 2020 · 4 comments
Closed

Trait associated type bounds are stable #251

eduardosm opened this issue Mar 6, 2020 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@eduardosm
Copy link
Collaborator

Looking at:

x11rb/src/utils.rs

Lines 88 to 98 in efece4d

/// A wrapper around some piece of raw bytes.
///
/// If trait associated type bounds were stable, the Connection trait could just use an associated
/// type with bound Deref<[u8]>. Since this does not work, we get this enumeration that represents
/// some owned bytes.
#[derive(Debug)]
pub enum Buffer {
#[cfg(feature = "allow-unsafe-code")]
CSlice(CSlice),
Vec(Vec<u8>),
}

However, the following code is allowed in rust 1.37 (https://godbolt.org/z/Xe9rG9):

pub trait MyTrait {
    type Buf: AsRef<[u8]>;
}

pub fn get<T: MyTrait>(v: &T::Buf) -> &[u8] {
    v.as_ref()
}
@psychon psychon assigned psychon and unassigned psychon Mar 7, 2020
@psychon psychon added the help wanted Extra attention is needed label Mar 7, 2020
@psychon
Copy link
Owner

psychon commented Mar 7, 2020

One problem that I came across: What to do with stuff like the following in the generated code?

impl TryFrom<&Buffer> for Point {
    type Error = ParseError;
    fn try_from(value: &Buffer) -> Result<Self, Self::Error> {
        Self::try_from(&**value)
    }
}
impl TryFrom<Buffer> for Point {
    type Error = ParseError;
    fn try_from(value: Buffer) -> Result<Self, Self::Error> {
        Self::try_from(&*value)
    }
}

The following is the "correct" replacement, I think:

impl<B: AsRef<[u8]>> TryFrom<B> for Point {
    type Error = ParseError;
    fn try_from(value: B) -> Result<Self, Self::Error> {
        Self::try_from(value.as_ref())
    }
}

However, coherence complains:

error[E0119]: conflicting implementations of trait `std::convert::TryFrom<_>` for type `generated::xproto::Char2b`:
  --> /[snip]/out/generated/xproto.rs:41:1
   |
41 | impl<B: AsRef<[u8]>> TryFrom<B> for Char2b {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::TryFrom<U> for T
             where U: std::convert::Into<T>;

@eduardosm
Copy link
Collaborator Author

You caught me looking at it also. As done in this PR, I propose to just use TryFrom<&[u8]>.

@yshui
Copy link

yshui commented Mar 7, 2020

Looks like it's just not possible to have a generic TryFrom implementation: rust-lang/rust#50133

@eduardosm
Copy link
Collaborator Author

Closing because #259 has been merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants