Crate specialize [] [src]

Experimental specialization macros.

Syntax is highly volatile and subject to change. The use of these macros requires an unstable rust compiler and the #![feature(specialization)] crate attribute.

constrain!()

constrain!() attempts to add additional trait bounds to a generic type.

use std::io::{Read, Seek, SeekFrom, Cursor, Repeat};

fn generic_function<T: Read>(read: &mut T) {
    if let Some(read_seek) = constrain!(ref mut read as [IsReadSeek: Read + Seek] = Cursor<Repeat>) {
        read_seek.seek(SeekFrom::Start(0));
    }
}

Caveats

There are a few oddities in the above example...

  1. You must specify a name for the trait to be used behind the scenes for specialization, as in IsReadSeek. It may be called whatever you like.
  2. A default fallback type that implements the desired trait bounds must also be provided. This type must be concrete but will never be used or instantiated, and is only used to appease the type checker.

specialize! { }

Provides a type-level match statement with specialization bounds.

use std::io::{Read, BufRead, Write, copy, sink};

fn generic_function<T: Read>(read: &mut T) {
    specialize! {
        trait fn Trait::nonsensical[W: Write](&mut self, w: &mut W) -> bool where [W: Write];

        match impl['a, T: Read] for T where [T: Read] {
            where [T: BufRead] => self.fill_buf().and_then(|buf| w.write(buf)).is_ok(),
            impl[U: Into<u8> + Clone] where [T: BufRead + Iterator<Item=&'a U>, U: 'a] =>
                w.write(&self.cloned().map(Into::into).collect::<Vec<u8>>()).is_ok(),
            _ => copy(self, w).is_ok(),
        }
    }

    Trait::nonsensical(read, &mut sink());
}

Caveats

  1. This is not an inline statement or expression, and is instead used to generate a trait and method pair. This means the prototype must be specified up-front, and no variables will be automatically captured from the outside scope.
  2. Generic bounds and where clauses must be surrounded by [] rather than <> or similar due to macro parsing limitations.
  3. The specialization "more specific" rules must be followed in order to prevent conflicting trait impls.
  4. The various where [B: Bounds...] clauses may be omitted, and are mostly included here for syntax demonstration.