Skip to content

Need documentations on pointer casts #17481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nodakai opened this issue Sep 23, 2014 · 2 comments · Fixed by #23187
Closed

Need documentations on pointer casts #17481

nodakai opened this issue Sep 23, 2014 · 2 comments · Fixed by #23187

Comments

@nodakai
Copy link
Contributor

nodakai commented Sep 23, 2014

This is how the language reference describes the cast experssions:

Executing an as expression casts the value on the left-hand side to the type on the right-hand side.

A numeric value can be cast to any numeric type. A raw pointer value can be cast to or from any integral type or raw pointer type. Any other cast is unsupported and will fail to compile.

However, grepping for as .* as in src/libnative, for example, finds many instances of cast expressions which deviate from the above description. For example

          let mut storage = unsafe { mem::zeroed() };
(...snip...)
          let addrp = &storage as *const _ as *const libc::sockaddr;
  1. It seems like one can cast a refernce into a raw pointer. I assume that a reference is not of an "integral type," though the reference doesn't define what is an "integral type."
  2. The use of underscore in the cast expression seems to play the role of const_cast in C++ but is not described anywhere.

As for the above particular instance, the combination of ref_slice() and as_ptr() seems "more standard-compliant" to me and makes me wonder if the above special casts are really essential to Rust (ref_slice() is built on top of the magical intrinsic transmute()).

@mahkoh
Copy link
Contributor

mahkoh commented Sep 23, 2014

_ means that the type is inferred to make pointer casts less painful. For example in

let addrp: *const libc::sockaddr = &storage as *const _ as *const _;

the first _ is the type of storage and the second _ is libc::sockaddr.

as casts are necessary because they work in constant expressions and methods don't. For example

static X: u8 = 128;
static Y: *const i8 = &X as *const _ as *const _;

fn main() {
    assert_eq!(unsafe { *Y }, -128);
}

@nodakai
Copy link
Contributor Author

nodakai commented Sep 23, 2014

@mahkoh Thank you so much for your reply. However, you would be too busy if you had to answer to every single Rust programmer writing an FFI code involving *mut libc::c_void etc (few of them would be able to find this ticket). That's the point of describing it in the standard docs. Unfortunately my fluency of English and depth of understanding of Rust aren't enought to contribute a definitive description to the standard docs.

I indeed see the underscore symbol introduces syntax::ast::TyInfer which can let the type inferer to fill missing types:

However the language reference mentions to the underscore symbol only in the section on the match expression and it is different from what we are talking about.

steveklabnik added a commit to steveklabnik/rust that referenced this issue Mar 8, 2015
Manishearth added a commit to Manishearth/rust that referenced this issue Mar 9, 2015
dlrobertson pushed a commit to dlrobertson/rust that referenced this issue Nov 29, 2018
lnicola pushed a commit to lnicola/rust that referenced this issue Jul 11, 2024
fix: pattern completions in let-stmt

fix rust-lang#17480.

We can write `let S { a, b } = s;` or `let Some(x) = a else {}`, so it is reasonable to allow pattern completions in `LetStmt`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants