Correct spelling in docs

pull/10/head
Andrew Paseltiner 9 years ago committed by Manish Goregaokar
parent d264bf6b3b
commit 703285826a

@ -52,7 +52,7 @@ For numeric casts, there are quite a few cases to consider:
* zero-extend if the source is unsigned * zero-extend if the source is unsigned
* sign-extend if the source is signed * sign-extend if the source is signed
* casting from a float to an integer will round the float towards zero * casting from a float to an integer will round the float towards zero
* **[NOTE: currently this will cause Undefined Behaviour if the rounded * **[NOTE: currently this will cause Undefined Behavior if the rounded
value cannot be represented by the target integer type][float-int]**. value cannot be represented by the target integer type][float-int]**.
This includes Inf and NaN. This is a bug and will be fixed. This includes Inf and NaN. This is a bug and will be fixed.
* casting from an integer to float will produce the floating point * casting from an integer to float will produce the floating point
@ -61,7 +61,7 @@ For numeric casts, there are quite a few cases to consider:
* casting from an f32 to an f64 is perfect and lossless * casting from an f32 to an f64 is perfect and lossless
* casting from an f64 to an f32 will produce the closest possible value * casting from an f64 to an f32 will produce the closest possible value
(rounding strategy unspecified) (rounding strategy unspecified)
* **[NOTE: currently this will cause Undefined Behaviour if the value * **[NOTE: currently this will cause Undefined Behavior if the value
is finite but larger or smaller than the largest or smallest finite is finite but larger or smaller than the largest or smallest finite
value representable by f32][float-float]**. This is a bug and will value representable by f32][float-float]**. This is a bug and will
be fixed. be fixed.

@ -6,7 +6,7 @@ interacted with the *outlives* relationship in an inclusive manner. That is,
when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
`'b`. At first glance, this seems to be a meaningless distinction. Nothing ever `'b`. At first glance, this seems to be a meaningless distinction. Nothing ever
gets dropped at the same time as another, right? This is why we used the gets dropped at the same time as another, right? This is why we used the
following desugarring of `let` statements: following desugaring of `let` statements:
```rust,ignore ```rust,ignore
let x; let x;

@ -20,7 +20,7 @@ information that "completes" them (more on this below).
There are two major DSTs exposed by the language: trait objects, and slices. There are two major DSTs exposed by the language: trait objects, and slices.
A trait object represents some type that implements the traits it specifies. A trait object represents some type that implements the traits it specifies.
The exact original type is *erased* in favour of runtime reflection The exact original type is *erased* in favor of runtime reflection
with a vtable containing all the information necessary to use the type. with a vtable containing all the information necessary to use the type.
This is the information that completes a trait object: a pointer to its vtable. This is the information that completes a trait object: a pointer to its vtable.
@ -128,7 +128,7 @@ But neither of these tricks work today, so all Void types get you is
the ability to be confident that certain situations are statically impossible. the ability to be confident that certain situations are statically impossible.
One final subtle detail about empty types is that raw pointers to them are One final subtle detail about empty types is that raw pointers to them are
actually valid to construct, but dereferencing them is Undefined Behaviour actually valid to construct, but dereferencing them is Undefined Behavior
because that doesn't actually make sense. That is, you could model C's `void *` because that doesn't actually make sense. That is, you could model C's `void *`
type with `*const Void`, but this doesn't necessarily gain anything over using type with `*const Void`, but this doesn't necessarily gain anything over using
e.g. `*const ()`, which *is* safe to randomly dereference. e.g. `*const ()`, which *is* safe to randomly dereference.

@ -90,7 +90,7 @@ let mut vec = vec![Box::new(0); 4];
println!("{}", vec[0]); println!("{}", vec[0]);
``` ```
This is pretty clearly Not Good. Unfortunately, we're kind've stuck between a This is pretty clearly Not Good. Unfortunately, we're kind of stuck between a
rock and a hard place: maintaining consistent state at every step has an rock and a hard place: maintaining consistent state at every step has an
enormous cost (and would negate any benefits of the API). Failing to maintain enormous cost (and would negate any benefits of the API). Failing to maintain
consistent state gives us Undefined Behavior in safe code (making the API consistent state gives us Undefined Behavior in safe code (making the API
@ -248,4 +248,4 @@ let mut data = Box::new(0);
``` ```
Dang. Here the destructor running was pretty fundamental to the API, and it had Dang. Here the destructor running was pretty fundamental to the API, and it had
to be scrapped in favour of a completely different design. to be scrapped in favor of a completely different design.

@ -26,7 +26,7 @@ do some really crazy unsafe things.
Safe Rust is the *true* Rust programming language. If all you do is write Safe Safe Rust is the *true* Rust programming language. If all you do is write Safe
Rust, you will never have to worry about type-safety or memory-safety. You will Rust, you will never have to worry about type-safety or memory-safety. You will
never endure a null or dangling pointer, or any of that Undefined Behaviour never endure a null or dangling pointer, or any of that Undefined Behavior
nonsense. nonsense.
*That's totally awesome.* *That's totally awesome.*
@ -52,11 +52,11 @@ The only things that are different in Unsafe Rust are that you can:
* Mutate statics * Mutate statics
That's it. The reason these operations are relegated to Unsafe is that misusing That's it. The reason these operations are relegated to Unsafe is that misusing
any of these things will cause the ever dreaded Undefined Behaviour. Invoking any of these things will cause the ever dreaded Undefined Behavior. Invoking
Undefined Behaviour gives the compiler full rights to do arbitrarily bad things Undefined Behavior gives the compiler full rights to do arbitrarily bad things
to your program. You definitely *should not* invoke Undefined Behaviour. to your program. You definitely *should not* invoke Undefined Behavior.
Unlike C, Undefined Behaviour is pretty limited in scope in Rust. All the core Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
language cares about is preventing the following things: language cares about is preventing the following things:
* Dereferencing null or dangling pointers * Dereferencing null or dangling pointers
@ -71,9 +71,9 @@ language cares about is preventing the following things:
* Unwinding into another language * Unwinding into another language
* Causing a [data race][race] * Causing a [data race][race]
That's it. That's all the causes of Undefined Behaviour baked into Rust. Of That's it. That's all the causes of Undefined Behavior baked into Rust. Of
course, unsafe functions and traits are free to declare arbitrary other course, unsafe functions and traits are free to declare arbitrary other
constraints that a program must maintain to avoid Undefined Behaviour. However, constraints that a program must maintain to avoid Undefined Behavior. However,
generally violations of these constraints will just transitively lead to one of generally violations of these constraints will just transitively lead to one of
the above problems. Some additional constraints may also derive from compiler the above problems. Some additional constraints may also derive from compiler
intrinsics that make special assumptions about how code can be optimized. intrinsics that make special assumptions about how code can be optimized.

@ -6,7 +6,7 @@ Safe Rust guarantees an absence of data races, which are defined as:
* one of them is a write * one of them is a write
* one of them is unsynchronized * one of them is unsynchronized
A data race has Undefined Behaviour, and is therefore impossible to perform A data race has Undefined Behavior, and is therefore impossible to perform
in Safe Rust. Data races are *mostly* prevented through rust's ownership system: in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
it's impossible to alias a mutable reference, so it's impossible to perform a it's impossible to alias a mutable reference, so it's impossible to perform a
data race. Interior mutability makes this more complicated, which is largely why data race. Interior mutability makes this more complicated, which is largely why
@ -53,7 +53,7 @@ thread::spawn(move || {
// bounds checked, and there's no chance of the value getting changed // bounds checked, and there's no chance of the value getting changed
// in the middle. However our program may panic if the thread we spawned // in the middle. However our program may panic if the thread we spawned
// managed to increment before this ran. A race condition because correct // managed to increment before this ran. A race condition because correct
// program execution (panicing is rarely correct) depends on order of // program execution (panicking is rarely correct) depends on order of
// thread execution. // thread execution.
println!("{}", data[idx.load(Ordering::SeqCst)]); println!("{}", data[idx.load(Ordering::SeqCst)]);
``` ```

@ -41,7 +41,7 @@ Some examples of unsafe functions:
* `slice::get_unchecked` will perform unchecked indexing, allowing memory * `slice::get_unchecked` will perform unchecked indexing, allowing memory
safety to be freely violated. safety to be freely violated.
* `ptr::offset` is an intrinsic that invokes Undefined Behaviour if it is * `ptr::offset` is an intrinsic that invokes Undefined Behavior if it is
not "in bounds" as defined by LLVM. not "in bounds" as defined by LLVM.
* `mem::transmute` reinterprets some value as having the given type, * `mem::transmute` reinterprets some value as having the given type,
bypassing type safety in arbitrary ways. (see [conversions] for details) bypassing type safety in arbitrary ways. (see [conversions] for details)
@ -59,9 +59,9 @@ As of Rust 1.0 there are exactly two unsafe traits:
The need for unsafe traits boils down to the fundamental property of safe code: The need for unsafe traits boils down to the fundamental property of safe code:
**No matter how completely awful Safe code is, it can't cause Undefined **No matter how completely awful Safe code is, it can't cause Undefined
Behaviour.** Behavior.**
This means that Unsafe Rust, **the royal vanguard of Undefined Behaviour**, has to be This means that Unsafe Rust, **the royal vanguard of Undefined Behavior**, has to be
*super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust *super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
specific safe code. Anything else would degenerate into infinite spirals of specific safe code. Anything else would degenerate into infinite spirals of
paranoid despair. In particular it's generally regarded as ok to trust the standard library paranoid despair. In particular it's generally regarded as ok to trust the standard library

@ -15,7 +15,7 @@ implement, and other unsafe code can assume that they are correctly
implemented. Since they're *marker traits* (they have no associated items like implemented. Since they're *marker traits* (they have no associated items like
methods), correctly implemented simply means that they have the intrinsic methods), correctly implemented simply means that they have the intrinsic
properties an implementor should have. Incorrectly implementing Send or Sync can properties an implementor should have. Incorrectly implementing Send or Sync can
cause Undefined Behaviour. cause Undefined Behavior.
Send and Sync are also automatically derived traits. This means that, unlike Send and Sync are also automatically derived traits. This means that, unlike
every other trait, if a type is composed entirely of Send or Sync types, then it every other trait, if a type is composed entirely of Send or Sync types, then it

@ -8,7 +8,7 @@ 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>` 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 type `U`. The only restriction is that the `T` and `U` are verified to have the
same size. The ways to cause Undefined Behaviour with this are mind boggling. 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.
@ -26,7 +26,7 @@ same size. The ways to cause Undefined Behaviour with this are mind boggling.
`mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than `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`. this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
The size check that `mem::transmute` has is gone (as it may be valid to copy 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`. 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.

@ -2,7 +2,7 @@
Unsafe code can often end up producing references or lifetimes out of thin air. Unsafe code can often end up producing references or lifetimes out of thin air.
Such lifetimes come into the world as *unbounded*. The most common source of this Such lifetimes come into the world as *unbounded*. The most common source of this
is derefencing a raw pointer, which produces a reference with an unbounded lifetime. is dereferencing a raw pointer, which produces a reference with an unbounded lifetime.
Such a lifetime becomes as big as context demands. This is in fact more powerful Such a lifetime becomes as big as context demands. This is in fact more powerful
than simply becoming `'static`, because for instance `&'static &'a T` than simply becoming `'static`, because for instance `&'static &'a T`
will fail to typecheck, but the unbound lifetime will perfectly mold into will fail to typecheck, but the unbound lifetime will perfectly mold into
@ -10,7 +10,7 @@ will fail to typecheck, but the unbound lifetime will perfectly mold into
lifetime can be regarded as `'static`. lifetime can be regarded as `'static`.
Almost no reference is `'static`, so this is probably wrong. `transmute` and Almost no reference is `'static`, so this is probably wrong. `transmute` and
`transmute_copy` are the two other primary offenders. One should endeavour to `transmute_copy` are the two other primary offenders. One should endeavor to
bound an unbounded lifetime as quick as possible, especially across function bound an unbounded lifetime as quick as possible, especially across function
boundaries. boundaries.

@ -38,7 +38,7 @@ dropping the old value: `write`, `copy`, and `copy_nonoverlapping`.
(this is equivalent to memcpy -- note that the argument order is reversed!) (this is equivalent to memcpy -- note that the argument order is reversed!)
It should go without saying that these functions, if misused, will cause serious It should go without saying that these functions, if misused, will cause serious
havoc or just straight up Undefined Behaviour. The only things that these havoc or just straight up Undefined Behavior. The only things that these
functions *themselves* require is that the locations you want to read and write functions *themselves* require is that the locations you want to read and write
are allocated. However the ways writing arbitrary bits to arbitrary are allocated. However the ways writing arbitrary bits to arbitrary
locations of memory can break things are basically uncountable! locations of memory can break things are basically uncountable!

@ -4,7 +4,7 @@ All runtime-allocated memory in a Rust program begins its life as
*uninitialized*. In this state the value of the memory is an indeterminate pile *uninitialized*. In this state the value of the memory is an indeterminate pile
of bits that may or may not even reflect a valid state for the type that is of bits that may or may not even reflect a valid state for the type that is
supposed to inhabit that location of memory. Attempting to interpret this memory supposed to inhabit that location of memory. Attempting to interpret this memory
as a value of *any* type will cause Undefined Behaviour. Do Not Do This. as a value of *any* type will cause Undefined Behavior. Do Not Do This.
Rust provides mechanisms to work with uninitialized memory in checked (safe) and Rust provides mechanisms to work with uninitialized memory in checked (safe) and
unchecked (unsafe) ways. unchecked (unsafe) ways.

@ -42,7 +42,7 @@ should only panic for programming errors or *extreme* problems.
Rust's unwinding strategy is not specified to be fundamentally compatible Rust's unwinding strategy is not specified to be fundamentally compatible
with any other language's unwinding. As such, unwinding into Rust from another with any other language's unwinding. As such, unwinding into Rust from another
language, or unwinding into another language from Rust is Undefined Behaviour. language, or unwinding into another language from Rust is Undefined Behavior.
You must *absolutely* catch any panics at the FFI boundary! What you do at that You must *absolutely* catch any panics at the FFI boundary! What you do at that
point is up to you, but *something* must be done. If you fail to do this, point is up to you, but *something* must be done. If you fail to do this,
at best, your application will crash and burn. At worst, your application *won't* at best, your application will crash and burn. At worst, your application *won't*

@ -93,7 +93,7 @@ pub struct Vec<T> {
If you don't care about the null-pointer optimization, then you can use the If you don't care about the null-pointer optimization, then you can use the
stable code. However we will be designing the rest of the code around enabling stable code. However we will be designing the rest of the code around enabling
the optimization. In particular, `Unique::new` is unsafe to call, because the optimization. In particular, `Unique::new` is unsafe to call, because
putting `null` inside of it is Undefined Behaviour. Our stable Unique doesn't putting `null` inside of it is Undefined Behavior. Our stable Unique doesn't
need `new` to be unsafe because it doesn't make any interesting guarantees about need `new` to be unsafe because it doesn't make any interesting guarantees about
its contents. its contents.

@ -34,7 +34,7 @@ Easy! How about `pop`? Although this time the index we want to access is
initialized, Rust won't just let us dereference the location of memory to move initialized, Rust won't just let us dereference the location of memory to move
the value out, because that would leave the memory uninitialized! For this we the value out, because that would leave the memory uninitialized! For this we
need `ptr::read`, which just copies out the bits from the target address and need `ptr::read`, which just copies out the bits from the target address and
intrprets it as a value of type T. This will leave the memory at this address interprets it as a value of type T. This will leave the memory at this address
logically uninitialized, even though there is in fact a perfectly good instance logically uninitialized, even though there is in fact a perfectly good instance
of T there. of T there.

@ -1,6 +1,6 @@
% Handling Zero-Sized Types % Handling Zero-Sized Types
It's time. We're going to fight the spectre that is zero-sized types. Safe Rust It's time. We're going to fight the specter that is zero-sized types. Safe Rust
*never* needs to care about this, but Vec is very intensive on raw pointers and *never* needs to care about this, but Vec is very intensive on raw pointers and
raw allocations, which are exactly the two things that care about raw allocations, which are exactly the two things that care about
zero-sized types. We need to be careful of two things: zero-sized types. We need to be careful of two things:

Loading…
Cancel
Save