]> git.lizzy.rs Git - rust.git/commitdiff
last of the emphasis cleanup
authorAlexis Beingessner <a.beingessner@gmail.com>
Fri, 31 Jul 2015 05:48:36 +0000 (22:48 -0700)
committerAlexis Beingessner <a.beingessner@gmail.com>
Fri, 31 Jul 2015 14:11:35 +0000 (07:11 -0700)
12 files changed:
src/doc/tarpl/races.md
src/doc/tarpl/repr-rust.md
src/doc/tarpl/safe-unsafe-meaning.md
src/doc/tarpl/send-and-sync.md
src/doc/tarpl/subtyping.md
src/doc/tarpl/unwinding.md
src/doc/tarpl/vec-alloc.md
src/doc/tarpl/vec-drain.md
src/doc/tarpl/vec-insert-remove.md
src/doc/tarpl/vec-into-iter.md
src/doc/tarpl/vec-push-pop.md
src/doc/tarpl/vec-zsts.md

index 2ad62c14a806b8cc8dbb87a95aa9fb4a707677e0..28b52e9bb3b79154a4e30726eddf91aa6dee049d 100644 (file)
@@ -12,11 +12,13 @@ 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
 we have the Send and Sync traits (see below).
 
-However Rust *does not* prevent general race conditions. This is
-pretty fundamentally impossible, and probably honestly undesirable. Your hardware
-is racy, your OS is racy, the other programs on your computer are racy, and the
-world this all runs in is racy. Any system that could genuinely claim to prevent
-*all* race conditions would be pretty awful to use, if not just incorrect.
+**However Rust does not prevent general race conditions.**
+
+This is pretty fundamentally impossible, and probably honestly undesirable. Your
+hardware is racy, your OS is racy, the other programs on your computer are racy,
+and the world this all runs in is racy. Any system that could genuinely claim to
+prevent *all* race conditions would be pretty awful to use, if not just
+incorrect.
 
 So it's perfectly "fine" for a Safe Rust program to get deadlocked or do
 something incredibly stupid with incorrect synchronization. Obviously such a
@@ -46,7 +48,7 @@ thread::spawn(move || {
 });
 
 // Index with the value loaded from the atomic. This is safe because we
-// read the atomic memory only once, and then pass a *copy* of that value
+// read the atomic memory only once, and then pass a copy of that value
 // to the Vec's indexing implementation. This indexing will be correctly
 // 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
@@ -75,7 +77,7 @@ thread::spawn(move || {
 
 if idx.load(Ordering::SeqCst) < data.len() {
     unsafe {
-        // Incorrectly loading the idx *after* we did the bounds check.
+        // Incorrectly loading the idx after we did the bounds check.
         // It could have changed. This is a race condition, *and dangerous*
         // because we decided to do `get_unchecked`, which is `unsafe`.
         println!("{}", data.get_unchecked(idx.load(Ordering::SeqCst)));
index 639d64adc18b8dae273e9960cbe67606c9f5bf6b..9073495c517670594e3baadd90eb49b8f3110a3b 100644 (file)
@@ -70,7 +70,7 @@ struct B {
 Rust *does* guarantee that two instances of A have their data laid out in
 exactly the same way. However Rust *does not* guarantee that an instance of A
 has the same field ordering or padding as an instance of B (in practice there's
-no *particular* reason why they wouldn't, other than that its not currently
+no particular reason why they wouldn't, other than that its not currently
 guaranteed).
 
 With A and B as written, this is basically nonsensical, but several other
@@ -88,9 +88,9 @@ struct Foo<T, U> {
 ```
 
 Now consider the monomorphizations of `Foo<u32, u16>` and `Foo<u16, u32>`. If
-Rust lays out the fields in the order specified, we expect it to *pad* the
-values in the struct to satisfy their *alignment* requirements. So if Rust
-didn't reorder fields, we would expect Rust to produce the following:
+Rust lays out the fields in the order specified, we expect it to pad the
+values in the struct to satisfy their alignment requirements. So if Rust
+didn't reorder fields, we would expect it to produce the following:
 
 ```rust,ignore
 struct Foo<u16, u32> {
@@ -112,7 +112,7 @@ The latter case quite simply wastes space. An optimal use of space therefore
 requires different monomorphizations to have *different field orderings*.
 
 **Note: this is a hypothetical optimization that is not yet implemented in Rust
-**1.0
+1.0**
 
 Enums make this consideration even more complicated. Naively, an enum such as:
 
@@ -128,8 +128,8 @@ would be laid out as:
 
 ```rust
 struct FooRepr {
-    data: u64, // this is *really* either a u64, u32, or u8 based on `tag`
-    tag: u8, // 0 = A, 1 = B, 2 = C
+    data: u64, // this is either a u64, u32, or u8 based on `tag`
+    tag: u8,   // 0 = A, 1 = B, 2 = C
 }
 ```
 
index 909308397d717bff7ff172c7d3aa5d477fdc3e2c..2f15b7050e362018f3701b63805e673fea109806 100644 (file)
@@ -5,7 +5,7 @@ So what's the relationship between Safe and Unsafe Rust? How do they interact?
 Rust models the separation between Safe and Unsafe Rust with the `unsafe`
 keyword, which can be thought as a sort of *foreign function interface* (FFI)
 between Safe and Unsafe Rust. This is the magic behind why we can say Safe Rust
-is a safe language: all the scary unsafe bits are relegated *exclusively* to FFI
+is a safe language: all the scary unsafe bits are relegated exclusively to FFI
 *just like every other safe language*.
 
 However because one language is a subset of the other, the two can be cleanly
@@ -61,13 +61,13 @@ 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
 Behaviour.**
 
-This means that Unsafe, **the royal vanguard of Undefined Behaviour**, has to be
-*super paranoid* about generic safe code. Unsafe is free to trust *specific* safe
-code (or else you would degenerate into infinite spirals of paranoid despair).
-It is generally regarded as ok to trust the standard library to be correct, as
-`std` is effectively an extension of the language (and you *really* just have
-to trust the language). If `std` fails to uphold the guarantees it declares,
-then it's basically a language bug.
+This means that Unsafe Rust, **the royal vanguard of Undefined Behaviour**, has to be
+*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
+paranoid despair. In particular it's generally regarded as ok to trust the standard library
+to be correct. `std` is effectively an extension of the language, and you
+really just have to trust the language. If `std` fails to uphold the
+guarantees it declares, then it's basically a language bug.
 
 That said, it would be best to minimize *needlessly* relying on properties of
 concrete safe code. Bugs happen! Of course, I must reinforce that this is only
@@ -75,36 +75,36 @@ a concern for Unsafe code. Safe code can blindly trust anyone and everyone
 as far as basic memory-safety is concerned.
 
 On the other hand, safe traits are free to declare arbitrary contracts, but because
-implementing them is Safe, Unsafe can't trust those contracts to actually
+implementing them is safe, unsafe code can't trust those contracts to actually
 be upheld. This is different from the concrete case because *anyone* can
 randomly implement the interface. There is something fundamentally different
-about trusting a *particular* piece of code to be correct, and trusting *all the
+about trusting a particular piece of code to be correct, and trusting *all the
 code that will ever be written* to be correct.
 
 For instance Rust has `PartialOrd` and `Ord` traits to try to differentiate
 between types which can "just" be compared, and those that actually implement a
-*total* ordering. Pretty much every API that wants to work with data that can be
-compared *really* wants Ord data. For instance, a sorted map like BTreeMap
+total ordering. Pretty much every API that wants to work with data that can be
+compared wants Ord data. For instance, a sorted map like BTreeMap
 *doesn't even make sense* for partially ordered types. If you claim to implement
 Ord for a type, but don't actually provide a proper total ordering, BTreeMap will
 get *really confused* and start making a total mess of itself. Data that is
 inserted may be impossible to find!
 
 But that's okay. BTreeMap is safe, so it guarantees that even if you give it a
-*completely* garbage Ord implementation, it will still do something *safe*. You
-won't start reading uninitialized memory or unallocated memory. In fact, BTreeMap
+completely garbage Ord implementation, it will still do something *safe*. You
+won't start reading uninitialized or unallocated memory. In fact, BTreeMap
 manages to not actually lose any of your data. When the map is dropped, all the
 destructors will be successfully called! Hooray!
 
-However BTreeMap is implemented using a modest spoonful of Unsafe (most collections
-are). That means that it is not necessarily *trivially true* that a bad Ord
-implementation will make BTreeMap behave safely. Unsafe must be sure not to rely
-on Ord *where safety is at stake*. Ord is provided by Safe, and safety is not
-Safe's responsibility to uphold.
+However BTreeMap is implemented using a modest spoonful of Unsafe Rust (most collections
+are). That means that it's not necessarily *trivially true* that a bad Ord
+implementation will make BTreeMap behave safely. BTreeMap must be sure not to rely
+on Ord *where safety is at stake*. Ord is provided by safe code, and safety is not
+safe code's responsibility to uphold.
 
-But wouldn't it be grand if there was some way for Unsafe to trust *some* trait
+But wouldn't it be grand if there was some way for Unsafe to trust some trait
 contracts *somewhere*? This is the problem that unsafe traits tackle: by marking
-*the trait itself* as unsafe *to implement*, Unsafe can trust the implementation
+*the trait itself* as unsafe to implement, unsafe code can trust the implementation
 to uphold the trait's contract. Although the trait implementation may be
 incorrect in arbitrary other ways.
 
@@ -126,7 +126,7 @@ But it's probably not the implementation you want.
 
 Rust has traditionally avoided making traits unsafe because it makes Unsafe
 pervasive, which is not desirable. Send and Sync are unsafe is because thread
-safety is a *fundamental property* that Unsafe cannot possibly hope to defend
+safety is a *fundamental property* that unsafe code cannot possibly hope to defend
 against in the same way it would defend against a bad Ord implementation. The
 only way to possibly defend against thread-unsafety would be to *not use
 threading at all*. Making every load and store atomic isn't even sufficient,
@@ -135,10 +135,10 @@ in memory. For instance, the pointer and capacity of a Vec must be in sync.
 
 Even concurrent paradigms that are traditionally regarded as Totally Safe like
 message passing implicitly rely on some notion of thread safety -- are you
-really message-passing if you pass a *pointer*? Send and Sync therefore require
-some *fundamental* level of trust that Safe code can't provide, so they must be
+really message-passing if you pass a pointer? Send and Sync therefore require
+some fundamental level of trust that Safe code can't provide, so they must be
 unsafe to implement. To help obviate the pervasive unsafety that this would
-introduce, Send (resp. Sync) is *automatically* derived for all types composed only
+introduce, Send (resp. Sync) is automatically derived for all types composed only
 of Send (resp. Sync) values. 99% of types are Send and Sync, and 99% of those
 never actually say it (the remaining 1% is overwhelmingly synchronization
 primitives).
index 5b00709a1bf40d1045e7a33267ec066410d7b73b..af8fb43f2e9133fcfeea1914347710732d4938e0 100644 (file)
@@ -8,20 +8,19 @@ captures this with through the `Send` and `Sync` traits.
 * A type is Send if it is safe to send it to another thread. A type is Sync if
 * it is safe to share between threads (`&T` is Send).
 
-Send and Sync are *very* fundamental to Rust's concurrency story. As such, a
+Send and Sync are fundamental to Rust's concurrency story. As such, a
 substantial amount of special tooling exists to make them work right. First and
-foremost, they're *unsafe traits*. This means that they are unsafe *to
-implement*, and other unsafe code can *trust* that they are correctly
+foremost, they're [unsafe traits][]. This means that they are unsafe to
+implement, and other unsafe code can  that they are correctly
 implemented. Since they're *marker traits* (they have no associated items like
 methods), correctly implemented simply means that they have the intrinsic
 properties an implementor should have. Incorrectly implementing Send or Sync can
 cause Undefined Behaviour.
 
-Send and Sync are also what Rust calls *opt-in builtin traits*. This means that,
-unlike every other trait, they are *automatically* derived: if a type is
-composed entirely of Send or Sync types, then it is Send or Sync. Almost all
-primitives are Send and Sync, and as a consequence pretty much all types you'll
-ever interact with are Send and Sync.
+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
+is Send or Sync. Almost all primitives are Send and Sync, and as a consequence
+pretty much all types you'll ever interact with are Send and Sync.
 
 Major exceptions include:
 
@@ -37,13 +36,12 @@ sense, one could argue that it would be "fine" for them to be marked as thread
 safe.
 
 However it's important that they aren't thread safe to prevent types that
-*contain them* from being automatically marked as thread safe. These types have
+contain them from being automatically marked as thread safe. These types have
 non-trivial untracked ownership, and it's unlikely that their author was
 necessarily thinking hard about thread safety. In the case of Rc, we have a nice
-example of a type that contains a `*mut` that is *definitely* not thread safe.
+example of a type that contains a `*mut` that is definitely not thread safe.
 
-Types that aren't automatically derived can *opt-in* to Send and Sync by simply
-implementing them:
+Types that aren't automatically derived can simply implement them if desired:
 
 ```rust
 struct MyBox(*mut u8);
@@ -52,12 +50,13 @@ unsafe impl Send for MyBox {}
 unsafe impl Sync for MyBox {}
 ```
 
-In the *incredibly rare* case that a type is *inappropriately* automatically
-derived to be Send or Sync, then one can also *unimplement* Send and Sync:
+In the *incredibly rare* case that a type is inappropriately automatically
+derived to be Send or Sync, then one can also unimplement Send and Sync:
 
 ```rust
 #![feature(optin_builtin_traits)]
 
+// I have some magic semantics for some synchronization primitive!
 struct SpecialThreadToken(u8);
 
 impl !Send for SpecialThreadToken {}
@@ -77,3 +76,5 @@ largely behave like an `&` or `&mut` into the collection.
 
 TODO: better explain what can or can't be Send or Sync. Sufficient to appeal
 only to data races?
+
+[unsafe traits]: safe-unsafe-meaning.html
index 767a0aca542f96b26ec7127f428aa6184439bffd..3c57297f323cc7ad69f2545c148886a5e1d1a50a 100644 (file)
@@ -1,14 +1,14 @@
 % Subtyping and Variance
 
 Although Rust doesn't have any notion of structural inheritance, it *does*
-include subtyping. In Rust, subtyping derives entirely from *lifetimes*. Since
+include subtyping. In Rust, subtyping derives entirely from lifetimes. Since
 lifetimes are scopes, we can partially order them based on the *contains*
 (outlives) relationship. We can even express this as a generic bound.
 
-Subtyping on lifetimes in terms of that relationship: if `'a: 'b` ("a contains
+Subtyping on lifetimes is in terms of that relationship: if `'a: 'b` ("a contains
 b" or "a outlives b"), then `'a` is a subtype of `'b`. This is a large source of
 confusion, because it seems intuitively backwards to many: the bigger scope is a
-*sub type* of the smaller scope.
+*subtype* of the smaller scope.
 
 This does in fact make sense, though. The intuitive reason for this is that if
 you expect an `&'a u8`, then it's totally fine for me to hand you an `&'static
@@ -72,7 +72,7 @@ to be able to pass `&&'static str` where an `&&'a str` is expected. The
 additional level of indirection does not change the desire to be able to pass
 longer lived things where shorted lived things are expected.
 
-However this logic *does not* apply to `&mut`. To see why `&mut` should
+However this logic doesn't apply to `&mut`. To see why `&mut` should
 be invariant over T, consider the following code:
 
 ```rust,ignore
@@ -109,7 +109,7 @@ between `'a` and T is that `'a` is a property of the reference itself,
 while T is something the reference is borrowing. If you change T's type, then
 the source still remembers the original type. However if you change the
 lifetime's type, no one but the reference knows this information, so it's fine.
-Put another way, `&'a mut T` owns `'a`, but only *borrows* T.
+Put another way: `&'a mut T` owns `'a`, but only *borrows* T.
 
 `Box` and `Vec` are interesting cases because they're variant, but you can
 definitely store values in them! This is where Rust gets really clever: it's
@@ -118,7 +118,7 @@ in them *via a mutable reference*! The mutable reference makes the whole type
 invariant, and therefore prevents you from smuggling a short-lived type into
 them.
 
-Being variant *does* allows `Box` and `Vec` to be weakened when shared
+Being variant allows `Box` and `Vec` to be weakened when shared
 immutably. So you can pass a `&Box<&'static str>` where a `&Box<&'a str>` is
 expected.
 
@@ -126,7 +126,7 @@ However what should happen when passing *by-value* is less obvious. It turns out
 that, yes, you can use subtyping when passing by-value. That is, this works:
 
 ```rust
-fn get_box<'a>(str: &'a u8) -> Box<&'a str> {
+fn get_box<'a>(str: &'a str) -> Box<&'a str> {
     // string literals are `&'static str`s
     Box::new("hello")
 }
@@ -150,7 +150,7 @@ signature:
 fn foo(&'a str) -> usize;
 ```
 
-This signature claims that it can handle any `&str` that lives *at least* as
+This signature claims that it can handle any `&str` that lives at least as
 long as `'a`. Now if this signature was variant over `&'a str`, that
 would mean
 
@@ -159,10 +159,12 @@ fn foo(&'static str) -> usize;
 ```
 
 could be provided in its place, as it would be a subtype. However this function
-has a *stronger* requirement: it says that it can *only* handle `&'static str`s,
-and nothing else. Therefore functions are not variant over their arguments.
+has a stronger requirement: it says that it can only handle `&'static str`s,
+and nothing else. Giving `&'a str`s to it would be unsound, as it's free to
+assume that what it's given lives forever. Therefore functions are not variant
+over their arguments.
 
-To see why `Fn(T) -> U` should be *variant* over U, consider the following
+To see why `Fn(T) -> U` should be variant over U, consider the following
 function signature:
 
 ```rust,ignore
@@ -177,7 +179,7 @@ therefore completely reasonable to provide
 fn foo(usize) -> &'static str;
 ```
 
-in its place. Therefore functions *are* variant over their return type.
+in its place. Therefore functions are variant over their return type.
 
 `*const` has the exact same semantics as `&`, so variance follows. `*mut` on the
 other hand can dereference to an `&mut` whether shared or not, so it is marked
index 59494d8647467921b74c33ce81f6a65ab0b42e8a..3ad95dde39deda47fc61395384af3915a6221097 100644 (file)
@@ -31,12 +31,12 @@ panics can only be caught by the parent thread. This means catching a panic
 requires spinning up an entire OS thread! This unfortunately stands in conflict
 to Rust's philosophy of zero-cost abstractions.
 
-There is an *unstable* API called `catch_panic` that enables catching a panic
+There is an unstable API called `catch_panic` that enables catching a panic
 without spawning a thread. Still, we would encourage you to only do this
 sparingly. In particular, Rust's current unwinding implementation is heavily
 optimized for the "doesn't unwind" case. If a program doesn't unwind, there
 should be no runtime cost for the program being *ready* to unwind. As a
-consequence, *actually* unwinding will be more expensive than in e.g. Java.
+consequence, actually unwinding will be more expensive than in e.g. Java.
 Don't build your programs to unwind under normal circumstances. Ideally, you
 should only panic for programming errors or *extreme* problems.
 
index 93efbbbdf89a2e49df2bedad48ca8361c26dd518..fc7feba2356d5a4fb742a5b9ea06a99d32e86085 100644 (file)
@@ -60,7 +60,7 @@ of memory at once (e.g. half the theoretical address space). As such it's
 like the standard library as much as possible, so we'll just kill the whole
 program.
 
-We said we don't want to use intrinsics, so doing *exactly* what `std` does is
+We said we don't want to use intrinsics, so doing exactly what `std` does is
 out. Instead, we'll call `std::process::exit` with some random number.
 
 ```rust
@@ -84,7 +84,7 @@ But Rust's only supported allocator API is so low level that we'll need to do a
 fair bit of extra work. We also need to guard against some special
 conditions that can occur with really large allocations or empty allocations.
 
-In particular, `ptr::offset` will cause us *a lot* of trouble, because it has
+In particular, `ptr::offset` will cause us a lot of trouble, because it has
 the semantics of LLVM's GEP inbounds instruction. If you're fortunate enough to
 not have dealt with this instruction, here's the basic story with GEP: alias
 analysis, alias analysis, alias analysis. It's super important to an optimizing
@@ -102,7 +102,7 @@ As a simple example, consider the following fragment of code:
 If the compiler can prove that `x` and `y` point to different locations in
 memory, the two operations can in theory be executed in parallel (by e.g.
 loading them into different registers and working on them independently).
-However in *general* the compiler can't do this because if x and y point to
+However the compiler can't do this in general because if x and y point to
 the same location in memory, the operations need to be done to the same value,
 and they can't just be merged afterwards.
 
@@ -118,7 +118,7 @@ possible.
 So that's what GEP's about, how can it cause us trouble?
 
 The first problem is that we index into arrays with unsigned integers, but
-GEP (and as a consequence `ptr::offset`) takes a *signed integer*. This means
+GEP (and as a consequence `ptr::offset`) takes a signed integer. This means
 that half of the seemingly valid indices into an array will overflow GEP and
 actually go in the wrong direction! As such we must limit all allocations to
 `isize::MAX` elements. This actually means we only need to worry about
@@ -138,7 +138,7 @@ However since this is a tutorial, we're not going to be particularly optimal
 here, and just unconditionally check, rather than use clever platform-specific
 `cfg`s.
 
-The other corner-case we need to worry about is *empty* allocations. There will
+The other corner-case we need to worry about is empty allocations. There will
 be two kinds of empty allocations we need to worry about: `cap = 0` for all T,
 and `cap > 0` for zero-sized types.
 
@@ -165,9 +165,9 @@ protected from being allocated anyway (a whole 4k, on many platforms).
 
 However what about for positive-sized types? That one's a bit trickier. In
 principle, you can argue that offsetting by 0 gives LLVM no information: either
-there's an element before the address, or after it, but it can't know which.
+there's an element before the address or after it, but it can't know which.
 However we've chosen to conservatively assume that it may do bad things. As
-such we *will* guard against this case explicitly.
+such we will guard against this case explicitly.
 
 *Phew*
 
index 3be295f1adc2d301ad643c8294469725312e9d4f..4521bbdd05e6b0456df7e86f38f548f67c20cfc3 100644 (file)
@@ -130,7 +130,7 @@ impl<'a, T> Drop for Drain<'a, T> {
 impl<T> Vec<T> {
     pub fn drain(&mut self) -> Drain<T> {
         // this is a mem::forget safety thing. If Drain is forgotten, we just
-        // leak the whole Vec's contents. Also we need to do this *eventually*
+        // leak the whole Vec's contents. Also we need to do this eventually
         // anyway, so why not do it now?
         self.len = 0;
 
index 6f88a77b32a7537378f2576ca2f9218b9dc3eacf..0a37170c52ca34bf39bef5bd96a80dbec6492f1f 100644 (file)
@@ -10,7 +10,7 @@ handling the case where the source and destination overlap (which will
 definitely happen here).
 
 If we insert at index `i`, we want to shift the `[i .. len]` to `[i+1 .. len+1]`
-using the *old* len.
+using the old len.
 
 ```rust,ignore
 pub fn insert(&mut self, index: usize, elem: T) {
index a9c1917feb9c64213ceab007a5311a037452298a..ebb0a79bb651ac05a83f24bfcf68633a636ba97e 100644 (file)
@@ -21,8 +21,8 @@ read out the value pointed to at that end and move the pointer over by one. When
 the two pointers are equal, we know we're done.
 
 Note that the order of read and offset are reversed for `next` and `next_back`
-For `next_back` the pointer is always *after* the element it wants to read next,
-while for `next` the pointer is always *at* the element it wants to read next.
+For `next_back` the pointer is always after the element it wants to read next,
+while for `next` the pointer is always at the element it wants to read next.
 To see why this is, consider the case where every element but one has been
 yielded.
 
@@ -124,7 +124,7 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
 ```
 
 Because IntoIter takes ownership of its allocation, it needs to implement Drop
-to free it. However it *also* wants to implement Drop to drop any elements it
+to free it. However it also wants to implement Drop to drop any elements it
 contains that weren't yielded.
 
 
index 2ef15e324b6e9ae2561d83788ca963fc4e7a1004..b518e8aa48ffb1beb82b0b796cce45d60e6192f3 100644 (file)
@@ -32,14 +32,14 @@ pub fn push(&mut self, elem: T) {
 
 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
-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
 intrprets 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.
 
 For `pop`, if the old len is 1, we want to read out of the 0th index. So we
-should offset by the *new* len.
+should offset by the new len.
 
 ```rust,ignore
 pub fn pop(&mut self) -> Option<T> {
index 931aed33ef5d5d8312525313f26781cfbedae684..72e8a34488bae73751aa6306d60613d32321bbdc 100644 (file)
@@ -2,7 +2,7 @@
 
 It's time. We're going to fight the spectre that is zero-sized types. Safe Rust
 *never* needs to care about this, but Vec is very intensive on raw pointers and
-raw allocations, which are exactly the *only* 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:
 
 * The raw allocator API has undefined behaviour if you pass in 0 for an
@@ -22,7 +22,7 @@ So if the allocator API doesn't support zero-sized allocations, what on earth
 do we store as our allocation? Why, `heap::EMPTY` of course! Almost every operation
 with a ZST is a no-op since ZSTs have exactly one value, and therefore no state needs
 to be considered to store or load them. This actually extends to `ptr::read` and
-`ptr::write`: they won't actually look at the pointer at all. As such we *never* need
+`ptr::write`: they won't actually look at the pointer at all. As such we never need
 to change the pointer.
 
 Note however that our previous reliance on running out of memory before overflow is