about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhil Ruffwind <rf@rufflewind.com>2017-02-11 17:00:56 -0500
committerPhil Ruffwind <rf@rufflewind.com>2017-02-19 22:24:45 -0500
commitcc000599b8f3fd2b15a7d862bd70da440ff8b12b (patch)
treee95ea5b2d94ae10b0a57f4b58f1cd090c170aa21
parentf57a027f7153c0764a2b8bb5a68ee879e47cd255 (diff)
Rust Book: Generics: Resolving ambiguities
- Add a small section to generics.md to explain how ambiguities in type
  inference can be resolved using the ::<> syntax.
- Add links from syntax-index.md and iterators.md.
- Minor edits to iterators.md and structs.md.
-rw-r--r--src/doc/book/src/generics.md46
-rw-r--r--src/doc/book/src/iterators.md8
-rw-r--r--src/doc/book/src/structs.md2
-rw-r--r--src/doc/book/src/syntax-index.md2
4 files changed, 52 insertions, 6 deletions
diff --git a/src/doc/book/src/generics.md b/src/doc/book/src/generics.md
index 56655ac41d0..d02cd776d00 100644
--- a/src/doc/book/src/generics.md
+++ b/src/doc/book/src/generics.md
@@ -140,5 +140,51 @@ container types like [`Vec<T>`][Vec]. On the other hand, often you want to
 trade that flexibility for increased expressive power. Read about [trait
 bounds][traits] to see why and how.
 
+## Resolving ambiguities
+
+Most of the time when generics are involved, the compiler can infer the
+generic parameters automatically:
+
+```rust
+// v must be a Vec<T> but we don't know what T is yet
+let mut v = Vec::new();
+// v just got a bool value, so T must be bool!
+v.push(true);
+// Debug-print v
+println!("{:?}", v);
+```
+
+Sometimes though, the compiler needs a little help. For example, had we
+omitted the last line, we would get a compile error:
+
+```rust,ignore
+let v = Vec::new();
+//      ^^^^^^^^ cannot infer type for `T`
+//
+// note: type annotations or generic parameter binding required
+println!("{:?}", v);
+```
+
+We can solve this using either a type annotation:
+
+```rust
+let v: Vec<bool> = Vec::new();
+println!("{:?}", v);
+```
+
+or by binding the generic parameter `T` via the so-called
+[‘turbofish’][turbofish] `::<>` syntax:
+
+```rust
+let v = Vec::<bool>::new();
+println!("{:?}", v);
+```
+
+The second approach is useful in situations where we don’t want to bind the
+result to a variable. It can also be used to bind generic parameters in
+functions or methods. See [Iterators § Consumers](iterators.html#consumers)
+for an example.
+
 [traits]: traits.html
 [Vec]: ../std/vec/struct.Vec.html
+[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect
diff --git a/src/doc/book/src/iterators.md b/src/doc/book/src/iterators.md
index 1437c0f0b54..8ee6c0828ad 100644
--- a/src/doc/book/src/iterators.md
+++ b/src/doc/book/src/iterators.md
@@ -135,10 +135,10 @@ Here's the version that does compile:
 let one_to_one_hundred = (1..101).collect::<Vec<i32>>();
 ```
 
-If you remember, the `::<>` syntax allows us to give a type hint,
-and so we tell it that we want a vector of integers. You don't always
-need to use the whole type, though. Using a `_` will let you provide
-a partial hint:
+If you remember, the [`::<>` syntax](generics.html#resolving-ambiguities)
+allows us to give a type hint that tells the compiler we want a vector of
+integers. You don't always need to use the whole type, though. Using a `_`
+will let you provide a partial hint:
 
 ```rust
 let one_to_one_hundred = (1..101).collect::<Vec<_>>();
diff --git a/src/doc/book/src/structs.md b/src/doc/book/src/structs.md
index 6423147e66e..6b2a145c85e 100644
--- a/src/doc/book/src/structs.md
+++ b/src/doc/book/src/structs.md
@@ -134,7 +134,7 @@ fn main() {
     let age = 27;
     let peter = Person { name, age };
 
-    // Print debug struct
+    // Debug-print struct
     println!("{:?}", peter);
 }
 ```
diff --git a/src/doc/book/src/syntax-index.md b/src/doc/book/src/syntax-index.md
index 1e1d811a1d8..df7ae410ed1 100644
--- a/src/doc/book/src/syntax-index.md
+++ b/src/doc/book/src/syntax-index.md
@@ -125,7 +125,7 @@
 <!-- Generics -->
 
 * `path<…>` (*e.g.* `Vec<u8>`): specifies parameters to generic type *in a type*.  See [Generics].
-* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::<i32>()`): specifies parameters to generic type, function, or method *in an expression*.
+* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::<i32>()`): specifies parameters to generic type, function, or method *in an expression*.  See [Generics § Resolving ambiguities](generics.html#resolving-ambiguities).
 * `fn ident<…> …`: define generic function.  See [Generics].
 * `struct ident<…> …`: define generic structure.  See [Generics].
 * `enum ident<…> …`: define generic enumeration.  See [Generics].