about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexis Beingessner <a.beingessner@gmail.com>2015-07-19 21:43:17 -0700
committerAlexis Beingessner <a.beingessner@gmail.com>2015-07-19 21:43:17 -0700
commit94a89e561a62d54d25dd64329ef8af396d8ec032 (patch)
treee1fa2b3e9aed65a646b1db3c055f107b6cb3eb74
parent13b2605ed985a37481dc497357dc6dcdf37ba6ff (diff)
downloadrust-94a89e561a62d54d25dd64329ef8af396d8ec032.tar.gz
rust-94a89e561a62d54d25dd64329ef8af396d8ec032.zip
some conversions cleanup
-rw-r--r--src/doc/tarpl/casts.md27
-rw-r--r--src/doc/tarpl/coercions.md6
-rw-r--r--src/doc/tarpl/conversions.md11
-rw-r--r--src/doc/tarpl/transmutes.md18
4 files changed, 39 insertions, 23 deletions
diff --git a/src/doc/tarpl/casts.md b/src/doc/tarpl/casts.md
index cbcf81d8371..37f84ead797 100644
--- a/src/doc/tarpl/casts.md
+++ b/src/doc/tarpl/casts.md
@@ -1,9 +1,21 @@
 % Casts
 
-Casts are a superset of coercions: every coercion can be explicitly invoked via
-a cast, but some conversions *require* a cast. These "true casts" are generally
-regarded as dangerous or problematic actions. True casts revolve around raw
-pointers and the primitive numeric types. True casts aren't checked.
+Casts are a superset of coercions: every coercion can be explicitly
+invoked via a cast. However some conversions *require* a cast.
+While coercions are pervasive and largely harmless, these "true casts"
+are rare and potentially dangerous. As such, casts must be explicitly invoked
+using the `as` keyword: `expr as Type`.
+
+True casts generally revolve around raw pointers and the primitive numeric
+types. Even though they're dangerous, these casts are *infallible* at runtime.
+If a cast triggers some subtle corner case no indication will be given that
+this occurred. The cast will simply succeed.
+
+That said, casts aren't `unsafe` because they generally can't violate memory
+safety *on their own*. For instance, converting an integer to a raw pointer can
+very easily lead to terrible things. However the act of creating the pointer
+itself is safe, because actually using a raw pointer is already marked as
+`unsafe`.
 
 Here's an exhaustive list of all the true casts. For brevity, we will use `*`
 to denote either a `*const` or `*mut`, and `integer` to denote any integral
@@ -22,13 +34,8 @@ primitive:
  * `fn as *T` where `T: Sized`
  * `fn as integer`
 
-where `&.T` and `*T` are references of either mutability,
-and where unsize_kind(`T`) is the kind of the unsize info
-in `T` - the vtable for a trait definition (e.g. `fmt::Display` or
-`Iterator`, not `Iterator<Item=u8>`) or a length (or `()` if `T: Sized`).
-
 Note that lengths are not adjusted when casting raw slices -
-`T: *const [u16] as *const [u8]` creates a slice that only includes
+`*const [u16] as *const [u8]` creates a slice that only includes
 half of the original memory.
 
 Casting is not transitive, that is, even if `e as U1 as U2` is a valid
diff --git a/src/doc/tarpl/coercions.md b/src/doc/tarpl/coercions.md
index df0fdfa57ca..0eb03d271c4 100644
--- a/src/doc/tarpl/coercions.md
+++ b/src/doc/tarpl/coercions.md
@@ -9,8 +9,7 @@ Here's all the kinds of coercion:
 
 Coercion is allowed between the following types:
 
-* Subtyping: `T` to `U` if `T` is a [subtype](lifetimes.html#subtyping-and-variance)
-  of `U`
+* Subtyping: `T` to `U` if `T` is a [subtype][] of `U`
 * Transitivity: `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to `T_3`
 * Pointer Weakening:
     * `&mut T` to `&T`
@@ -25,7 +24,6 @@ only implemented automatically, and enables the following transformations:
 
 * `[T, ..n]` => `[T]`
 * `T` => `Trait` where `T: Trait`
-* `SubTrait` => `Trait` where `SubTrait: Trait` (TODO: is this now implied by the previous?)
 * `Foo<..., T, ...>` => `Foo<..., U, ...>` where:
     * `T: Unsize<U>`
     * `Foo` is a struct
@@ -70,3 +68,5 @@ fn main() {
 <anon>:10     foo(t);
               ^~~
 ```
+
+[subtype]: subtyping.html
diff --git a/src/doc/tarpl/conversions.md b/src/doc/tarpl/conversions.md
index 56c050072b9..2309c45c6a8 100644
--- a/src/doc/tarpl/conversions.md
+++ b/src/doc/tarpl/conversions.md
@@ -1,9 +1,12 @@
 % Type Conversions
 
 At the end of the day, everything is just a pile of bits somewhere, and type
-systems are just there to help us use those bits right. Needing to reinterpret
-those piles of bits as different types is a common problem and Rust consequently
-gives you several ways to do that.
+systems are just there to help us use those bits right. There are two common
+problems with typing bits: needing to reinterpret those exact bits as a
+different type, and needing to change the bits to have equivalent meaning for
+a different type. Because Rust encourages encoding important properties in the
+type system, these problems are incredibly pervasive. As such, Rust
+consequently gives you several ways to solve them.
 
 First we'll look at the ways that *Safe Rust* gives you to reinterpret values.
 The most trivial way to do this is to just destructure a value into its
@@ -26,6 +29,6 @@ fn reinterpret(foo: Foo) -> Bar {
 }
 ```
 
-But this is, at best, annoying to do. For common conversions, Rust provides
+But this is, at best, annoying. For common conversions, Rust provides
 more ergonomic alternatives.
 
diff --git a/src/doc/tarpl/transmutes.md b/src/doc/tarpl/transmutes.md
index 577d35ddb56..f19dda0d8b8 100644
--- a/src/doc/tarpl/transmutes.md
+++ b/src/doc/tarpl/transmutes.md
@@ -1,10 +1,10 @@
 % Transmutes
 
 Get out of our way type system! We're going to reinterpret these bits or die
-trying! Even though this book is all about doing things that are unsafe, I really
-can't emphasize that you should deeply think about finding Another Way than the
-operations covered in this section. This is really, truly, the most horribly
-unsafe thing you can do in Rust. The railguards here are dental floss.
+trying! Even though this book is all about doing things that are unsafe, I
+really can't emphasize that you should deeply think about finding Another Way
+than the operations covered in this section. This is really, truly, the most
+horribly unsafe thing you can do in Rust. The railguards here are dental floss.
 
 `mem::transmute<T, U>` takes a value of type `T` and reinterprets it to have
 type `U`. The only restriction is that the `T` and `U` are verified to have the
@@ -17,8 +17,11 @@ same size. The ways to cause Undefined Behaviour with this are mind boggling.
 * Making a primitive with an invalid value is UB
 * Transmuting between non-repr(C) types is UB
 * Transmuting an & to &mut is UB
+    * Transmuting an & to &mut is *always* UB
+    * No you can't do it
+    * No you're not special
 * Transmuting to a reference without an explicitly provided lifetime
-  produces an [unbound lifetime](lifetimes.html#unbounded-lifetimes)
+  produces an [unbounded lifetime][]
 
 `mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than
 this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
@@ -26,4 +29,7 @@ The size check that `mem::transmute` has is gone (as it may be valid to copy
 out a prefix), though it is Undefined Behaviour for `U` to be larger than `T`.
 
 Also of course you can get most of the functionality of these functions using
-pointer casts.
\ No newline at end of file
+pointer casts.
+
+
+[unbounded lifetime]: unbounded-lifetimes.html