From 347a257a474c0ee2d24f9fe780df16fdd7fb4972 Mon Sep 17 00:00:00 2001 From: Ivan Kozik Date: Mon, 15 Feb 2016 15:49:24 +0000 Subject: [PATCH 01/11] reference: vtable entries are resolved at runtime --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 19c9b571a33c2..13288fbdbce21 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3565,7 +3565,7 @@ Each instance of a trait object includes: implementation (i.e. a function pointer). The purpose of trait objects is to permit "late binding" of methods. A call to -a method on a trait object is only resolved to a vtable entry at compile time. +a method on a trait object is only resolved to a vtable entry at runtime. The actual implementation for each vtable entry can vary on an object-by-object basis. From 58f0d72d90bd38171e633705482c2043e2ef36bf Mon Sep 17 00:00:00 2001 From: Ivan Kozik Date: Thu, 18 Feb 2016 19:16:56 +0000 Subject: [PATCH 02/11] reference: vtable entries: copy @nikomatsakis's wording --- src/doc/reference.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 13288fbdbce21..2fdc1be3e77ce 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3564,8 +3564,9 @@ Each instance of a trait object includes: each method of `SomeTrait` that `T` implements, a pointer to `T`'s implementation (i.e. a function pointer). -The purpose of trait objects is to permit "late binding" of methods. A call to -a method on a trait object is only resolved to a vtable entry at runtime. +The purpose of trait objects is to permit "late binding" of methods. Calling a +method on a trait object results in virtual dispatch at runtime: that is, a +function pointer is loaded from the trait object vtable and invoked indirectly. The actual implementation for each vtable entry can vary on an object-by-object basis. From 8c554e05ae1c0dae75defb0db2986e01befcbcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20H=C3=BCgel?= Date: Sat, 20 Feb 2016 08:52:54 +0000 Subject: [PATCH 03/11] Clarify chunks() and chunks_mut() iterator content Closes #31773 --- src/libcollections/slice.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 6252e4888eb3c..e431a7c08b9b6 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -406,7 +406,7 @@ impl [T] { core_slice::SliceExt::windows(self, size) } - /// Returns an iterator over `size` elements of the slice at a + /// Returns an iterator over `size` slices of the slice at a /// time. The chunks do not overlap. If `size` does not divide the /// length of the slice, then the last chunk will not have length /// `size`. @@ -432,7 +432,7 @@ impl [T] { core_slice::SliceExt::chunks(self, size) } - /// Returns an iterator over `chunk_size` elements of the slice at a time. + /// Returns an iterator over `chunk_size` slices of the slice at a time. /// The chunks are mutable and do not overlap. If `chunk_size` does /// not divide the length of the slice, then the last chunk will not /// have length `chunk_size`. From 41a63bdcab788938a27a46a8f73b834f94600549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20H=C3=BCgel?= Date: Sat, 20 Feb 2016 09:04:15 +0000 Subject: [PATCH 04/11] Correct size of returned iterator The methods don't return `size` slices, but rather slices of `size` elements. Sorry! --- src/libcollections/slice.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index e431a7c08b9b6..eab69088aa2b9 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -406,8 +406,8 @@ impl [T] { core_slice::SliceExt::windows(self, size) } - /// Returns an iterator over `size` slices of the slice at a - /// time. The chunks do not overlap. If `size` does not divide the + /// Returns an iterator over `size` elements of the slice at a + /// time. The chunks are slices and do not overlap. If `size` does not divide the /// length of the slice, then the last chunk will not have length /// `size`. /// @@ -432,8 +432,8 @@ impl [T] { core_slice::SliceExt::chunks(self, size) } - /// Returns an iterator over `chunk_size` slices of the slice at a time. - /// The chunks are mutable and do not overlap. If `chunk_size` does + /// Returns an iterator over `chunk_size` elements of the slice at a time. + /// The chunks are mutable slices, and do not overlap. If `chunk_size` does /// not divide the length of the slice, then the last chunk will not /// have length `chunk_size`. /// From 9d3bce38b4e7c2fe706d8228d720222ec2781e30 Mon Sep 17 00:00:00 2001 From: mitaa Date: Tue, 23 Feb 2016 12:04:27 +0100 Subject: [PATCH 05/11] Don't record self parameter for static methods --- src/librustdoc/html/render.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 692d230446cda..1b97b3865d421 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2734,18 +2734,19 @@ fn make_item_keywords(it: &clean::Item) -> String { fn get_index_search_type(item: &clean::Item, parent: Option) -> Option { - let decl = match item.inner { - clean::FunctionItem(ref f) => &f.decl, - clean::MethodItem(ref m) => &m.decl, - clean::TyMethodItem(ref m) => &m.decl, + let (decl, selfty) = match item.inner { + clean::FunctionItem(ref f) => (&f.decl, None), + clean::MethodItem(ref m) => (&m.decl, Some(&m.self_)), + clean::TyMethodItem(ref m) => (&m.decl, Some(&m.self_)), _ => return None }; let mut inputs = Vec::new(); // Consider `self` an argument as well. - if let Some(name) = parent { - inputs.push(Type { name: Some(name.to_ascii_lowercase()) }); + match parent.and_then(|p| selfty.map(|s| (p, s)) ) { + Some((_, &clean::SelfStatic)) | None => (), + Some((name, _)) => inputs.push(Type { name: Some(name.to_ascii_lowercase()) }), } inputs.extend(&mut decl.inputs.values.iter().map(|arg| { From fbfe70e6ab26c0cccb5fbbf5b805eecb751cb576 Mon Sep 17 00:00:00 2001 From: dileepb Date: Tue, 23 Feb 2016 21:18:07 +0530 Subject: [PATCH 06/11] #31820 - Utilize `if..let` instead of single `match` branch --- src/libgetopts/lib.rs | 5 ++--- src/librustc_trans/back/link.rs | 10 ++++------ src/librustc_trans/trans/base.rs | 20 ++++++++------------ src/librustc_trans/trans/common.rs | 5 ++--- src/librustc_trans/trans/type_of.rs | 10 ++++------ src/librustdoc/lib.rs | 5 ++--- src/libstd/net/addr.rs | 5 ++--- src/libstd/net/parser.rs | 5 ++--- src/libstd/sys/windows/thread_local.rs | 5 ++--- 9 files changed, 28 insertions(+), 42 deletions(-) diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 57ce53e73b025..fe059076926ee 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -331,9 +331,8 @@ impl Matches { /// Returns the string argument supplied to one of several matching options or `None`. pub fn opts_str(&self, names: &[String]) -> Option { for nm in names { - match self.opt_val(&nm[..]) { - Some(Val(ref s)) => return Some(s.clone()), - _ => (), + if let Some(Val(ref s)) = self.opt_val(&nm[..]) { + return Some(s.clone()) } } None diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 33734d615a621..76360dcc1b972 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -226,9 +226,8 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>, } fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> String { - match ccx.type_hashcodes().borrow().get(&t) { - Some(h) => return h.to_string(), - None => {} + if let Some(h) = ccx.type_hashcodes().borrow().get(&t) { + return h.to_string() } let mut symbol_hasher = ccx.symbol_hasher().borrow_mut(); @@ -315,9 +314,8 @@ pub fn mangle>(path: PI, hash: Option<&str>) - push(&mut n, &data); } - match hash { - Some(s) => push(&mut n, s), - None => {} + if let Some(s) = hash { + push(&mut n, s) } n.push('E'); // End name-sequence. diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index e36905c6d90ea..161ab90c03a73 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -150,9 +150,8 @@ impl Drop for _InsnCtxt { pub fn push_ctxt(s: &'static str) -> _InsnCtxt { debug!("new InsnCtxt: {}", s); TASK_LOCAL_INSN_KEY.with(|slot| { - match slot.borrow_mut().as_mut() { - Some(ctx) => ctx.push(s), - None => {} + if let Some(ctx) = slot.borrow_mut().as_mut() { + ctx.push(s) } }); _InsnCtxt { @@ -198,9 +197,8 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, did: DefId) -> ValueRef { - match ccx.externs().borrow().get(name) { - Some(n) => return *n, - None => (), + if let Some(n) = ccx.externs().borrow().get(name) { + return *n; } let f = declare::declare_rust_fn(ccx, name, fn_ty); @@ -238,9 +236,8 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, -> ValueRef { let name = ccx.sess().cstore.item_symbol(did); let ty = type_of(ccx, t); - match ccx.externs().borrow_mut().get(&name) { - Some(n) => return *n, - None => (), + if let Some(n) = ccx.externs().borrow_mut().get(&name) { + return *n; } // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow? // FIXME(nagisa): investigate whether it can be changed into define_global @@ -2755,9 +2752,8 @@ fn contains_null(s: &str) -> bool { pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { debug!("get_item_val(id=`{}`)", id); - match ccx.item_vals().borrow().get(&id).cloned() { - Some(v) => return v, - None => {} + if let Some(v) = ccx.item_vals().borrow().get(&id).cloned() { + return v; } let item = ccx.tcx().map.get(id); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index bdc0f8539d600..7f7de0e872b6c 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -947,9 +947,8 @@ pub fn C_u8(ccx: &CrateContext, i: u8) -> ValueRef { // our boxed-and-length-annotated strings. pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef { unsafe { - match cx.const_cstr_cache().borrow().get(&s) { - Some(&llval) => return llval, - None => () + if let Some(&llval) = cx.const_cstr_cache().borrow().get(&s) { + return llval; } let sc = llvm::LLVMConstStringInContext(cx.llcx(), diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 0f88269a2c9e9..24a7fd372f636 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -182,9 +182,8 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>) // recursive types. For example, enum types rely on this behavior. pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { - match cx.llsizingtypes().borrow().get(&t).cloned() { - Some(t) => return t, - None => () + if let Some(t) = cx.llsizingtypes().borrow().get(&t).cloned() { + return t; } debug!("sizing_type_of {:?}", t); @@ -317,9 +316,8 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type { /// NB: If you update this, be sure to update `sizing_type_of()` as well. pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { // Check the cache. - match cx.lltypes().borrow().get(&t) { - Some(&llty) => return llty, - None => () + if let Some(&llty) = cx.lltypes().borrow().get(&t) { + return llty; } debug!("type_of {:?}", t); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6cad0d7d940d7..ffb15d157b066 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -385,9 +385,8 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche *s.borrow_mut() = analysis.take(); }); - match matches.opt_str("crate-name") { - Some(name) => krate.name = name, - None => {} + if let Some(name) = matches.opt_str("crate-name") { + krate.name = name } // Process all of the crate attributes, extracting plugin metadata along diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 89c51c7084353..87d5dc20e9f70 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -467,9 +467,8 @@ impl ToSocketAddrs for str { type Iter = vec::IntoIter; fn to_socket_addrs(&self) -> io::Result> { // try to parse as a regular SocketAddr first - match self.parse().ok() { - Some(addr) => return Ok(vec![addr].into_iter()), - None => {} + if let Some(addr) = self.parse().ok() { + return Ok(vec![addr].into_iter()); } macro_rules! try_opt { diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index 46a0309dbb509..63eee6bcfded5 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -66,9 +66,8 @@ impl<'a> Parser<'a> { fn read_or(&mut self, parsers: &mut [Box Option + 'static>]) -> Option { for pf in parsers { - match self.read_atomically(|p: &mut Parser| pf(p)) { - Some(r) => return Some(r), - None => {} + if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) { + return Some(r); } } None diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index db2ad1d89c4d8..386d21a04c76d 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -69,9 +69,8 @@ static mut DTORS: *mut Vec<(Key, Dtor)> = ptr::null_mut(); pub unsafe fn create(dtor: Option) -> Key { let key = c::TlsAlloc(); assert!(key != c::TLS_OUT_OF_INDEXES); - match dtor { - Some(f) => register_dtor(key, f), - None => {} + if let Some(f) = dtor { + register_dtor(key, f); } return key; } From eb97c26d3b3a3c59ddd48fba2780259b906904a1 Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Tue, 23 Feb 2016 19:05:35 +0530 Subject: [PATCH 07/11] Updated the primitive docs for bool --- src/libstd/primitive_docs.rs | 45 +++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index b840e51873e3f..e5819522123c4 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -12,6 +12,50 @@ // /// The boolean type. /// +/// The `bool` represents a value, which could only be either `true` or `false`. +/// +/// # Basic usage +/// +/// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., +/// which allow us to perform boolean operations using `&`, `|` and `!`. +/// +/// [`if`] always demands a `bool` value. [`assert!`], being an important macro in testing, +/// checks whether an expression returns `true`. +/// +/// ``` +/// let bool_val = true & false | false; +/// assert!(!bool_val); +/// ``` +/// +/// [`assert!`]: std/macro.assert!.html +/// [`if` conditionals]: ../../book/if.html +/// [`BitAnd`]: ../ops/trait.BitAnd.html +/// [`BitOr`]: ../ops/trait.BitOr.html +/// [`Not`]: ../ops/trait.Not.html +/// +/// # Examples +/// +/// A trivial example of the usage of `bool`, +/// +/// ``` +/// let praise_the_borrow_checker = true; +/// +/// // using the `if` conditional +/// if praise_the_borrow_checker { +/// println!("oh, yeah!"); +/// } else { +/// println!("what?!!"); +/// } +/// +/// // ... or, a match pattern +/// match praise_the_borrow_checker { +/// true => println!("keep praising!"), +/// false => println!("you should praise!"), +/// } +/// ``` +/// +/// Also, since `bool` implements the [`Copy`](../marker/trait.Copy.html) trait, we don't +/// have to worry about the move semantics (just like the integer and float primitives). mod prim_bool { } #[doc(primitive = "char")] @@ -533,4 +577,3 @@ mod prim_isize { } /// *[See also the `std::usize` module](usize/index.html).* /// mod prim_usize { } - From 397ab315e76d59f634b79aa2c694571ad0c3e000 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 24 Feb 2016 19:13:31 +0300 Subject: [PATCH 08/11] reference: clarify use declaration location --- src/doc/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 19c9b571a33c2..43cac796d27e6 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -841,8 +841,8 @@ extern crate std as ruststd; // linking to 'std' under another name A _use declaration_ creates one or more local name bindings synonymous with some other [path](#paths). Usually a `use` declaration is used to shorten the -path required to refer to a module item. These declarations may appear at the -top of [modules](#modules) and [blocks](grammar.html#block-expressions). +path required to refer to a module item. These declarations may appear in +[modules](#modules) and [blocks](grammar.html#block-expressions), usually at the top. > **Note**: Unlike in many languages, > `use` declarations in Rust do *not* declare linkage dependency with external crates. From 145190bd2aec3b6ad9e4ed4da8490d810c9d0bee Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 24 Feb 2016 19:55:49 +0100 Subject: [PATCH 09/11] Capitalize some occurences of Rust in documentation --- src/doc/book/ownership.md | 2 +- src/doc/nomicon/other-reprs.md | 2 +- src/doc/reference.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book/ownership.md b/src/doc/book/ownership.md index 8f15544b20b2b..70d71c14ddf16 100644 --- a/src/doc/book/ownership.md +++ b/src/doc/book/ownership.md @@ -157,7 +157,7 @@ this point of time). These two parts of the vector (the one on the stack and one on the heap) must agree with each other at all times with regards to things like the length, capacity etc. -When we move `v` to `v2`, rust actually does a bitwise copy of the vector +When we move `v` to `v2`, Rust actually does a bitwise copy of the vector object `v` into the stack allocation represented by `v2`. This shallow copy does not create a copy of the heap allocation containing the actual data. Which means that there would be two pointers to the contents of the vector diff --git a/src/doc/nomicon/other-reprs.md b/src/doc/nomicon/other-reprs.md index 2639c1d4d6f76..b124f3ffc4652 100644 --- a/src/doc/nomicon/other-reprs.md +++ b/src/doc/nomicon/other-reprs.md @@ -57,7 +57,7 @@ These reprs have no effect on a struct. # repr(packed) -`repr(packed)` forces rust to strip any padding, and only align the type to a +`repr(packed)` forces Rust to strip any padding, and only align the type to a byte. This may improve the memory footprint, but will likely have other negative side-effects. diff --git a/src/doc/reference.md b/src/doc/reference.md index 19c9b571a33c2..718822b2bd0ac 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1764,7 +1764,7 @@ pub mod submodule { # fn main() {} ``` -For a rust program to pass the privacy checking pass, all paths must be valid +For a Rust program to pass the privacy checking pass, all paths must be valid accesses given the two rules above. This includes all use statements, expressions, types, etc. From 7042c8ef8d8242b96bbf9efd2a7de472a3b71e05 Mon Sep 17 00:00:00 2001 From: Ivan Kozik Date: Wed, 24 Feb 2016 20:00:58 +0000 Subject: [PATCH 10/11] book: Explain better why the filter closure gets a reference --- src/doc/book/iterators.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/book/iterators.md b/src/doc/book/iterators.md index 5622326d20c31..0c4f804126631 100644 --- a/src/doc/book/iterators.md +++ b/src/doc/book/iterators.md @@ -311,10 +311,12 @@ for i in (1..100).filter(|&x| x % 2 == 0) { ``` This will print all of the even numbers between one and a hundred. -(Note that because `filter` doesn't consume the elements that are -being iterated over, it is passed a reference to each element, and -thus the filter predicate uses the `&x` pattern to extract the integer -itself.) +(Note that, unlike `map`, the closure passed to `filter` is passed a reference +to the element instead of the element itself. The filter predicate here uses +the `&x` pattern to extract the integer. The filter closure is passed a +reference because it returns `true` or `false` instead of the element, +so the `filter` implementation must retain ownership to put the elements +into the newly constructed iterator.) You can chain all three things together: start with an iterator, adapt it a few times, and then consume the result. Check it out: From df33fc352d7b6aecc0ccadbfaf56484991cb80be Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 21 Feb 2016 03:00:50 +0100 Subject: [PATCH 11/11] Add more explanation on vec type --- src/libcollections/vec.rs | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 49c3552083334..ae442e155c0d0 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -135,6 +135,49 @@ use super::range::RangeArgument; /// } /// ``` /// +/// # Indexing +/// +/// The Vec type allows to access values by index, because it implements the +/// `Index` trait. An example will be more explicit: +/// +/// ``` +/// let v = vec!(0, 2, 4, 6); +/// println!("{}", v[1]); // it will display '2' +/// ``` +/// +/// However be careful: if you try to access an index which isn't in the Vec, +/// your software will panic! You cannot do this: +/// +/// ```ignore +/// let v = vec!(0, 2, 4, 6); +/// println!("{}", v[6]); // it will panic! +/// ``` +/// +/// In conclusion: always check if the index you want to get really exists +/// before doing it. +/// +/// # Slicing +/// +/// A Vec can be mutable. Slices, on the other hand, are read-only objects. +/// To get a slice, use "&". Example: +/// +/// ``` +/// fn read_slice(slice: &[usize]) { +/// // ... +/// } +/// +/// let v = vec!(0, 1); +/// read_slice(&v); +/// +/// // ... and that's all! +/// // you can also do it like this: +/// let x : &[usize] = &v; +/// ``` +/// +/// In Rust, it's more common to pass slices as arguments rather than vectors +/// when you just want to provide a read access. The same goes for String and +/// &str. +/// /// # Capacity and reallocation /// /// The capacity of a vector is the amount of space allocated for any future