1
Fork 0

Rephrased description of casting

This commit is contained in:
Martin Pool 2015-11-29 12:00:07 -08:00
parent 34e6995aa3
commit 797d5433c9

View file

@ -7,9 +7,12 @@ most dangerous features of Rust!
# Coercion # Coercion
Coercion between types is implicit and has no explicit syntax. Coercion occurs Coercion between types is implicit and has no syntax of its own, but can
in `let`, `const`, and `static` statements; in function call arguments; in be spelled out with [`as`](#explicit-coercions).
field values in struct initialization; and in a function result.
Coercion occurs in `let`, `const`, and `static` statements; in
function call arguments; in field values in struct initialization; and in a
function result.
The main cases of coercion are: The main cases of coercion are:
@ -21,6 +24,9 @@ The main cases of coercion are:
* `&mut T` to `*mut T` * `&mut T` to `*mut T`
* A custom coercion using [`Deref`](deref-coercions.md)
# `as` # `as`
The `as` keyword does safe casting: The `as` keyword does safe casting:
@ -50,15 +56,14 @@ let a = "hello";
let b = a as String; let b = a as String;
``` ```
All coercions will be made implicitly when necessary and unambiguous.
## Numeric casts ## Numeric casts
A cast `e as U` is also valid in any of the following cases: A cast `e as U` is also valid in any of the following cases:
* `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast* * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
* `e` is a C-like enum and `U` is an integer type; *enum-cast* * `e` is a C-like enum (with no data attached to the variants),
* `e` has type `bool` or `char` and `U` is an integer; *prim-int-cast* and `U` is an integer type; *enum-cast*
* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
* `e` has type `u8` and `U` is `char`; *u8-char-cast* * `e` has type `u8` and `U` is `char`; *u8-char-cast*
For example For example
@ -68,7 +73,7 @@ let one = true as u8;
let at_sign = 64 as char; let at_sign = 64 as char;
``` ```
For numeric casts, there are quite a few cases to consider: The semantics of numeric casts are:
* Casting between two integers of the same size (e.g. i32 -> u32) is a no-op * Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will * Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
@ -100,13 +105,20 @@ Perhaps surprisingly, it is safe to cast pointers to and from integers, and
to cast between pointers to different types subject to some constraints. It to cast between pointers to different types subject to some constraints. It
is only unsafe to dereference the pointer. is only unsafe to dereference the pointer.
`e as U` is a valid pointer cast in any of the following cases:
* `e` has type `*T`, `U` has type `*U_0`, and either `U_0: Sized` or * `e` has type `*T`, `U` has type `*U_0`, and either `U_0: Sized` or
unsize_kind(`T`) = unsize_kind(`U_0`); a *ptr-ptr-cast* `unsize_kind(T) == unsize_kind(U_0)`; a *ptr-ptr-cast*
* `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast* * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
* `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast* * `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
* `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast* * `e` has type `&[T; n]` and `U` is `*const T`; *array-ptr-cast*
* `e` is a function pointer type and `U` has type `*T`, * `e` is a function pointer type and `U` has type `*T`,
while `T: Sized`; *fptr-ptr-cast* while `T: Sized`; *fptr-ptr-cast*
* `e` is a function pointer type and `U` is an integer; *fptr-addr-cast* * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast*