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
?
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With