Minor improvements

* Prefer compile_fail over ignore, to catch if the code accidentally
  starts compiling in future versions.
* Make an example compile by providing mocked environment around it in
  case it should be correct.
* Links into std.
pull/129/head
Michal 'vorner' Vaner 6 years ago
parent c02e0e7754
commit 5d56de9fcc
No known key found for this signature in database
GPG Key ID: F700D0C019E4C66F

@ -26,7 +26,7 @@ println!("{} {} {} {}", a, b, c, c2);
However borrowck doesn't understand arrays or slices in any way, so this doesn't However borrowck doesn't understand arrays or slices in any way, so this doesn't
work: work:
```rust,ignore ```rust,compile_fail
let mut x = [1, 2, 3]; let mut x = [1, 2, 3];
let a = &mut x[0]; let a = &mut x[0];
let b = &mut x[1]; let b = &mut x[1];
@ -60,7 +60,12 @@ the left of the index, and one for everything to the right. Intuitively we know
this is safe because the slices don't overlap, and therefore alias. However this is safe because the slices don't overlap, and therefore alias. However
the implementation requires some unsafety: the implementation requires some unsafety:
```rust,ignore ```rust
# use std::slice::from_raw_parts_mut;
# struct FakeSlice<T>(T);
# impl<T> FakeSlice<T> {
# fn len(&self) -> usize { unimplemented!() }
# fn as_mut_ptr(&mut self) -> *mut T { unimplemented!() }
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
let len = self.len(); let len = self.len();
let ptr = self.as_mut_ptr(); let ptr = self.as_mut_ptr();
@ -70,6 +75,7 @@ fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
from_raw_parts_mut(ptr.offset(mid as isize), len - mid)) from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
} }
} }
# }
``` ```
This is actually a bit subtle. So as to avoid ever making two `&mut`'s to the This is actually a bit subtle. So as to avoid ever making two `&mut`'s to the

@ -4,7 +4,7 @@ Like C, all stack variables in Rust are uninitialized until a value is
explicitly assigned to them. Unlike C, Rust statically prevents you from ever explicitly assigned to them. Unlike C, Rust statically prevents you from ever
reading them until you do: reading them until you do:
```rust,ignore ```rust,compile_fail
fn main() { fn main() {
let x: i32; let x: i32;
println!("{}", x); println!("{}", x);
@ -39,7 +39,7 @@ fn main() {
but this doesn't: but this doesn't:
```rust,ignore ```rust,compile_fail
fn main() { fn main() {
let x: i32; let x: i32;
if true { if true {

@ -5,7 +5,7 @@ types or lifetimes are logically associated with a struct, but not actually
part of a field. This most commonly occurs with lifetimes. For instance, the part of a field. This most commonly occurs with lifetimes. For instance, the
`Iter` for `&'a [T]` is (approximately) defined as follows: `Iter` for `&'a [T]` is (approximately) defined as follows:
```rust,ignore ```rust,compile_fail
struct Iter<'a, T: 'a> { struct Iter<'a, T: 'a> {
ptr: *const T, ptr: *const T,
end: *const T, end: *const T,

@ -6,9 +6,10 @@ 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 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. 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 [`mem::transmute<T, U>`][transmute] takes a value of type `T` and reinterprets
type `U`. The only restriction is that the `T` and `U` are verified to have the it to have type `U`. The only restriction is that the `T` and `U` are verified
same size. The ways to cause Undefined Behavior with this are mind boggling. to have the same size. The ways to cause Undefined Behavior with this are mind
boggling.
* First and foremost, creating an instance of *any* type with an invalid state * First and foremost, creating an instance of *any* type with an invalid state
is going to cause arbitrary chaos that can't really be predicted. is going to cause arbitrary chaos that can't really be predicted.
@ -23,13 +24,16 @@ same size. The ways to cause Undefined Behavior with this are mind boggling.
* Transmuting to a reference without an explicitly provided lifetime * Transmuting to a reference without an explicitly provided lifetime
produces an [unbounded lifetime] produces an [unbounded lifetime]
`mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than [`mem::transmute_copy<T, U>`][transmute_copy] somehow manages to be *even more*
this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`. wildly unsafe than this. It copies `size_of<U>` bytes out of an `&T` and
The size check that `mem::transmute` has is gone (as it may be valid to copy interprets them as a `U`. The size check that `mem::transmute` has is gone (as
out a prefix), though it is Undefined Behavior for `U` to be larger than `T`. it may be valid to copy out a prefix), though it is Undefined Behavior for `U`
to be larger than `T`.
Also of course you can get most of the functionality of these functions using Also of course you can get most of the functionality of these functions using
pointer casts. pointer casts.
[unbounded lifetime]: unbounded-lifetimes.html [unbounded lifetime]: unbounded-lifetimes.html
[transmute]: ../std/mem/fn.transmute.html
[transmute_copy]: ../std/mem/fn.transmute.html

Loading…
Cancel
Save