Is it possible to save a value in a structure through a dash?

Editor's Note: This code example is for Rust prior to 1.0 and is not syntactically correct Rust 1.0 code. Updated versions of this code give rise to various errors, but the answers still contain valuable information.

I tried this with and without Box , with and without a lifetime:

 trait TraitToImpl { fn do_something(self, val: i32); } struct Cont { value: i32, } impl TraitToImpl for Cont { fn do_something(self, val: i32) { println!("{}", val); } } struct StoreTrait<'a> { field: Box<TraitToImpl + 'a>, } fn main() { let cont = Box::new(Cont { value: 12 }) as Box<TraitToImpl>; let a = StoreTrait { field: cont }; a.field.do_something(123); } 

All I get is an error:

error: cannot convert to a trait object because trait `TraitToImpl` is not object-safe

+6
source share
2 answers

The problem is that, as stated in the error message, the TraitToImpl property TraitToImpl not safe for the object. That is, it is not safe to use this particular attribute by reference (i.e. &TraitToImpl or Box<TraitToImpl> .

In particular, the do_something method takes the value self by value. Consider: how Box<TraitToImpl> compiler call this method on a Cont that was placed in a Box<TraitToImpl> ? It should copy the value into an argument of type Cont (this is what impl expects), but this call should work for any type of any size that TraitToImpl can implement!

Bottom line: if you have a trait containing the value self or generics, it cannot be used with a link. The moment the call comes in, the compiler no longer has enough information to actually generate the necessary code.

Maybe instead we take &self ? :)

+8
source

To understand the source of this error, it can also help find the definition of object-safe in Object Security RFC :

We say that a method m based on T is object-safe if it is legal (in the current Rust) to call xm(...) , where x is of type &T , i.e. x is a feature object. If all methods from T are object-safe, then we say that T is object-safe.

As @DK pointed out, x.do_something(...) is illegal because TraitToImpl cannot be passed by value.

Please note that the security of objects can also be compromised by receiving an unsafe object. For instance.

 trait TraitToImpl : Clone { fn do_something(&self, val: int); // this method is object-safe } 

will not be object-safe, because Clone itself has a non-object-safe method ( fn clone(&self) -> Self ).

+3
source

Source: https://habr.com/ru/post/978409/


All Articles