Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I cast a struct reference to isize?

Tags:

rust

I want to get b in the following code.

unsafe {
    struct Test {
        num: i32,
    }
    let a = Test { num: 0 };
    let b = &mut a as isize;
}

But it results in the following error message.

error: casting `&on_create::Test` as `isize` is invalid
   --> main.rs:181:15
    |
181 |       let b = &a as isize;
    |    

I thought it would be coerced to *const _, then applied ptr-addr-cast. What have I missed on this? Should I use mem::transmute?

like image 474
jeiea Avatar asked Jan 04 '23 04:01

jeiea


1 Answers

I thought it would be coerced to *const _, then applied ptr-addr-cast. ...

Firstly, implicit coercion doesn't happen everywhere, and certainly not inside part of an expression like e as T as you have noticed. The places where coercion happens, called coercion sites, are usually where you've done evaluating the expression, e.g.

  • RHS of let/const/static statements:

    let x = foo
    //      ^~~
    
  • Arguments to functions:

    foo(bar)
    //  ^~~
    
  • Returned expressions:

    fn f() -> u32 {
        foo
    //  ^~~
    }
    
  • struct/array/tuple literals:

       [foo, bar, baz]
    //  ^~~  ^~~  ^~~
       (foo, bar, baz)
    //  ^~~  ^~~  ^~~
       Foo { field: foo }
    //              ^~~
    
  • Last expression in a block:

    { ...; foo }
    //     ^~~
    

foo as isize is not among this list.

Secondly, even if implicit coercion were allowed everywhere, that does not mean Rust should choose to coerce to a type that makes the conversion valid. An &mut Test can be coerced to &Test or *mut Test or *const Test or &mut SomeTrait etc, the compiler will need to check all of them! This can only work if you tell what type the expression should coerce to:

#![feature(type_ascription)]

let b = {&a}: *const _ as isize;
//       ^~ ^~~~~~~~~~
//        |   we explicitly make the type a const raw pointer
//        |                             using type-ascription
//        a coercion site

But this has not much of a difference than the canonical solution &a as *const _ as isize.

like image 76
kennytm Avatar answered Jan 12 '23 01:01

kennytm