Struct core::raw::TraitObject [] [src]

pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}
Unstable (raw #27751)

The representation of a trait object like &SomeTrait.

This struct has the same layout as types like &SomeTrait and Box<AnotherTrait>. The Trait Objects chapter of the Book contains more details about the precise nature of these internals.

TraitObject is guaranteed to match layouts, but it is not the type of trait objects (e.g. the fields are not directly accessible on a &SomeTrait) nor does it control that layout (changing the definition will not change the layout of a &SomeTrait). It is only designed to be used by unsafe code that needs to manipulate the low-level details.

There is no Repr implementation for TraitObject because there is no way to refer to all trait objects generically, so the only way to create values of this type is with functions like std::mem::transmute. Similarly, the only way to create a true trait object from a TraitObject value is with transmute.

Synthesizing a trait object with mismatched types—one where the vtable does not correspond to the type of the value to which the data pointer points—is highly likely to lead to undefined behavior.

Examples

#![feature(raw)] fn main() { use std::mem; use std::raw; // an example trait trait Foo { fn bar(&self) -> i32; } impl Foo for i32 { fn bar(&self) -> i32 { *self + 1 } } let value: i32 = 123; // let the compiler make a trait object let object: &Foo = &value; // look at the raw representation let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; // the data pointer is the address of `value` assert_eq!(raw_object.data as *const i32, &value as *const _); let other_value: i32 = 456; // construct a new object, pointing to a different `i32`, being // careful to use the `i32` vtable from `object` let synthesized: &Foo = unsafe { mem::transmute(raw::TraitObject { data: &other_value as *const _ as *mut (), vtable: raw_object.vtable }) }; // it should work just like we constructed a trait object out of // `other_value` directly assert_eq!(synthesized.bar(), 457); }
#![feature(raw)]

use std::mem;
use std::raw;

// an example trait
trait Foo {
    fn bar(&self) -> i32;
}
impl Foo for i32 {
    fn bar(&self) -> i32 {
         *self + 1
    }
}

let value: i32 = 123;

// let the compiler make a trait object
let object: &Foo = &value;

// look at the raw representation
let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };

// the data pointer is the address of `value`
assert_eq!(raw_object.data as *const i32, &value as *const _);


let other_value: i32 = 456;

// construct a new object, pointing to a different `i32`, being
// careful to use the `i32` vtable from `object`
let synthesized: &Foo = unsafe {
     mem::transmute(raw::TraitObject {
         data: &other_value as *const _ as *mut (),
         vtable: raw_object.vtable
     })
};

// it should work just like we constructed a trait object out of
// `other_value` directly
assert_eq!(synthesized.bar(), 457);

Fields

data
Unstable (raw #27751)
vtable
Unstable (raw #27751)

Trait Implementations

Derived Implementations

impl Clone for TraitObject

fn clone(&self) -> TraitObject

Unstable (raw #27751)

fn clone_from(&mut self, source: &Self)1.0.0

impl Copy for TraitObject