Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created December 5, 2019 20:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rust-play/5f71fa5f7fb8051836d9d37200eb7d81 to your computer and use it in GitHub Desktop.
Save rust-play/5f71fa5f7fb8051836d9d37200eb7d81 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
pub mod zero_sized {
use std::marker::PhantomData;
pub struct ZeroSizeProof<T>(PhantomData<T>, ());
pub trait ZeroSized: Sized {
#[deny(const_err)]
const I_AM_ZERO_SIZED: ();
fn proof_zero_size(&self) -> ZeroSizeProof<Self>;
}
impl<T: Sized> ZeroSized for T {
const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()];
fn proof_zero_size(&self) -> ZeroSizeProof<Self> {
ZeroSizeProof(PhantomData, Self::I_AM_ZERO_SIZED)
}
}
}
pub mod foo {
use crate::zero_sized::*;
pub trait Foo: ZeroSized {
fn requires_zero_size(self, _proof: ZeroSizeProof<Self>) {
println!("requires_zero_size called");
}
}
pub trait FooExt: Foo {
fn requires_zero_size(self);
}
impl<T: Foo> FooExt for T {
fn requires_zero_size(self) {
let proof = self.proof_zero_size();
<Self as Foo>::requires_zero_size(self, proof)
}
}
}
use crate::zero_sized::ZeroSizeProof;
impl foo::Foo for () {}
impl foo::Foo for u32 {
fn requires_zero_size(self, _proof: ZeroSizeProof<Self>) {
println!("requires_zero_size was called, but Self is not zero-sized, bwa-ha-ha-ha!");
}
}
fn main() {
use foo::FooExt;
().requires_zero_size();
42_u32.requires_zero_size();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment