Auto merge of #29610 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #29416, #29537, #29538, #29539, #29567, #29568, #29571, #29579 - Failed merges:
This commit is contained in:
commit
2509948b3e
179
RELEASES.md
179
RELEASES.md
@ -1,3 +1,182 @@
|
||||
Version 1.4.0 (2015-10-29)
|
||||
============================
|
||||
|
||||
* ~1200 changes, numerous bugfixes
|
||||
|
||||
Highlights
|
||||
----------
|
||||
|
||||
* Windows builds targeting the 64-bit MSVC ABI and linker (instead of
|
||||
GNU) are now supported and recommended for use.
|
||||
|
||||
Breaking Changes
|
||||
----------------
|
||||
|
||||
* [Several changes have been made to fix type soundness and improve
|
||||
the behavior of associated types][sound]. See [RFC 1214]. Although
|
||||
we have mostly introduced these changes as warnings this release, to
|
||||
become errors next release, there are still some scenarios that will
|
||||
see immediate breakage.
|
||||
* [The `str::lines` and `BufRead::lines` iterators treat `\r\n` as
|
||||
line breaks in addition to `\n`][crlf].
|
||||
* [Loans of `'static` lifetime extend to the end of a function][stat].
|
||||
* [`str::parse` no longer introduces avoidable rounding error when
|
||||
parsing floating point numbers. Together with earlier changes to
|
||||
float formatting/output, "round trips" like f.to_string().parse()
|
||||
now preserve the value of f exactly. Additionally, leading plus
|
||||
signs are now accepted][fp3].
|
||||
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
* `use` statements that import multiple items [can now rename
|
||||
them][i], as in `use foo::{bar as kitten, baz as puppy}`.
|
||||
* [Binops work correctly on fat pointers][binfat].
|
||||
* `pub extern crate`, which does not behave as expected, [issues a
|
||||
warning][pec] until a better solution is found.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
* [Many APIs were stabilized][stab]: `<Box<str>>::into_string`,
|
||||
[`Arc::downgrade`], [`Arc::get_mut`], [`Arc::make_mut`],
|
||||
[`Arc::try_unwrap`], [`Box::from_raw`], [`Box::into_raw`], [`CStr::to_str`],
|
||||
[`CStr::to_string_lossy`], [`CString::from_raw`], [`CString::into_raw`],
|
||||
[`IntoRawFd::into_raw_fd`], [`IntoRawFd`],
|
||||
`IntoRawHandle::into_raw_handle`, `IntoRawHandle`,
|
||||
`IntoRawSocket::into_raw_socket`, `IntoRawSocket`, [`Rc::downgrade`],
|
||||
[`Rc::get_mut`], [`Rc::make_mut`], [`Rc::try_unwrap`], [`Result::expect`],
|
||||
[`String::into_boxed_str`], [`TcpStream::read_timeout`],
|
||||
[`TcpStream::set_read_timeout`], [`TcpStream::set_write_timeout`],
|
||||
[`TcpStream::write_timeout`], [`UdpSocket::read_timeout`],
|
||||
[`UdpSocket::set_read_timeout`], [`UdpSocket::set_write_timeout`],
|
||||
[`UdpSocket::write_timeout`], `Vec::append`, `Vec::split_off`,
|
||||
[`VecDeque::append`], [`VecDeque::retain`], [`VecDeque::split_off`],
|
||||
[`rc::Weak::upgrade`], [`rc::Weak`], [`slice::Iter::as_slice`],
|
||||
[`slice::IterMut::into_slice`], [`str::CharIndices::as_str`],
|
||||
[`str::Chars::as_str`], [`str::split_at_mut`], [`str::split_at`],
|
||||
[`sync::Weak::upgrade`], [`sync::Weak`], [`thread::park_timeout`],
|
||||
[`thread::sleep`].
|
||||
* [Some APIs were deprecated][dep]: `BTreeMap::with_b`,
|
||||
`BTreeSet::with_b`, `Option::as_mut_slice`, `Option::as_slice`,
|
||||
`Result::as_mut_slice`, `Result::as_slice`, `f32::from_str_radix`,
|
||||
`f64::from_str_radix`.
|
||||
* [Reverse-searching strings is faster with the 'two-way'
|
||||
algorithm][s].
|
||||
* [`std::io::copy` allows `?Sized` arguments][cc].
|
||||
* The `Windows`, `Chunks`, and `ChunksMut` iterators over slices all
|
||||
[override `count`, `nth` and `last` with an O(1)
|
||||
implementation][it].
|
||||
* [`Default` is implemented for arrays up to `[T; 32]`][d].
|
||||
* [`IntoRawFd` has been added to the Unix-specific prelude,
|
||||
`IntoRawSocket` and `IntoRawHandle` to the Windows-specific
|
||||
prelude][pr].
|
||||
* [`Extend<String>` and `FromIterator<String` are both implemented for
|
||||
`String`][es].
|
||||
* [`IntoIterator` is implemented for references to `Option` and
|
||||
`Result`][into2].
|
||||
* [`HashMap` and `HashSet` implement `Extend<&T>` where `T:
|
||||
Copy`][ext] as part of [RFC 839]. This will cause type inferance
|
||||
breakage in rare situations.
|
||||
* [`BinaryHeap` implements `Debug`][bh2].
|
||||
* [`Borrow` and `BorrowMut` are implemented for fixed-size
|
||||
arrays][bm].
|
||||
* [`extern fn`s with the "Rust" and "C" ABIs implement common
|
||||
traits including `Eq`, `Ord`, `Debug`, `Hash`][fp].
|
||||
* [String comparison is faster][faststr].
|
||||
* `&mut T` where `T: std::fmt::Write` [also implements
|
||||
`std::fmt::Write`][mutw].
|
||||
* [A stable regression in `VecDeque::push_back` and other
|
||||
capicity-altering methods that caused panics for zero-sized types
|
||||
was fixed][vd].
|
||||
* [Function pointers implement traits for up to 12 parameters][fp2].
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
* The compiler [no longer uses the 'morestack' feature to prevent
|
||||
stack overflow][mm]. Instead it uses guard pages and stack
|
||||
probes (though stack probes are not yet implemented on any platform
|
||||
but Windows).
|
||||
* [The compiler matches traits faster when projections are involved][p].
|
||||
* The 'improper_ctypes' lint [no longer warns about use of `isize` and
|
||||
`usize`][ffi].
|
||||
* [Cargo now displays useful information about what its doing during
|
||||
`cargo update`][cu].
|
||||
|
||||
[`Arc::downgrade`]: http://doc.rust-lang.org/nightly/alloc/arc/struct.Arc.html#method.downgrade
|
||||
[`Arc::make_mut`]: http://doc.rust-lang.org/nightly/alloc/arc/struct.Arc.html#method.make_mut
|
||||
[`Arc::get_mut`]: http://doc.rust-lang.org/nightly/alloc/arc/struct.Arc.html#method.get_mut
|
||||
[`Arc::try_unwrap`]: http://doc.rust-lang.org/nightly/alloc/arc/struct.Arc.html#method.try_unwrap
|
||||
[`Box::from_raw`]: http://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html#method.from_raw
|
||||
[`Box::into_raw`]: http://doc.rust-lang.org/nightly/alloc/boxed/struct.Box.html#method.into_raw
|
||||
[`CStr::to_str`]: http://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.to_str
|
||||
[`CStr::to_string_lossy`]: http://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.to_string_lossy
|
||||
[`CString::from_raw`]: http://doc.rust-lang.org/nightly/std/ffi/struct.CString.html#method.from_raw
|
||||
[`CString::into_raw`]: http://doc.rust-lang.org/nightly/std/ffi/struct.CString.html#method.into_raw
|
||||
[`IntoRawFd::into_raw_fd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.IntoRawFd.html#tymethod.into_raw_fd
|
||||
[`IntoRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.IntoRawFd.html
|
||||
[`Rc::downgrade`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.downgrade
|
||||
[`Rc::get_mut`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.get_mut
|
||||
[`Rc::make_mut`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.make_mut
|
||||
[`Rc::try_unwrap`]: http://doc.rust-lang.org/nightly/alloc/rc/struct.Rc.html#method.try_unwrap
|
||||
[`Result::expect`]: http://doc.rust-lang.org/nightly/core/result/enum.Result.html#method.expect
|
||||
[`String::into_boxed_str`]: http://doc.rust-lang.org/nightly/collections/string/struct.String.html#method.into_boxed_str
|
||||
[`TcpStream::read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.read_timeout
|
||||
[`TcpStream::set_read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.set_read_timeout
|
||||
[`TcpStream::write_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.write_timeout
|
||||
[`TcpStream::set_write_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.set_write_timeout
|
||||
[`UdpSocket::read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.read_timeout
|
||||
[`UdpSocket::set_read_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.set_read_timeout
|
||||
[`UdpSocket::write_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.write_timeout
|
||||
[`UdpSocket::set_write_timeout`]: http://doc.rust-lang.org/nightly/std/net/struct.TcpStream.html#method.set_write_timeout
|
||||
[`VecDeque::append`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.append
|
||||
[`VecDeque::retain`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.retain
|
||||
[`VecDeque::split_off`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.split_off
|
||||
[`rc::Weak::upgrade`]: http://doc.rust-lang.org/nightly/std/rc/struct.Weak.html#method.upgrade
|
||||
[`rc::Weak`]: http://doc.rust-lang.org/nightly/std/rc/struct.Weak.html
|
||||
[`slice::Iter::as_slice`]: http://doc.rust-lang.org/nightly/std/slice/struct.Iter.html#method.as_slice
|
||||
[`slice::IterMut::into_slice`]: http://doc.rust-lang.org/nightly/std/slice/struct.IterMut.html#method.into_slice
|
||||
[`str::CharIndices::as_str`]: http://doc.rust-lang.org/nightly/std/str/struct.CharIndices.html#method.as_str
|
||||
[`str::Chars::as_str`]: http://doc.rust-lang.org/nightly/std/str/struct.Chars.html#method.as_str
|
||||
[`str::split_at_mut`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_at_mut
|
||||
[`str::split_at`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_at
|
||||
[`sync::Weak::upgrade`]: http://doc.rust-lang.org/nightly/std/sync/struct.Weak.html#method.upgrade
|
||||
[`sync::Weak`]: http://doc.rust-lang.org/nightly/std/sync/struct.Weak.html
|
||||
[`thread::park_timeout`]: http://doc.rust-lang.org/nightly/std/thread/fn.park_timeout.html
|
||||
[`thread::sleep`]: http://doc.rust-lang.org/nightly/std/thread/fn.sleep.html
|
||||
[bh2]: https://github.com/rust-lang/rust/pull/28156
|
||||
[binfat]: https://github.com/rust-lang/rust/pull/28270
|
||||
[bm]: https://github.com/rust-lang/rust/pull/28197
|
||||
[cc]: https://github.com/rust-lang/rust/pull/27531
|
||||
[crlf]: https://github.com/rust-lang/rust/pull/28034
|
||||
[cu]: https://github.com/rust-lang/cargo/pull/1931
|
||||
[d]: https://github.com/rust-lang/rust/pull/27825
|
||||
[dep]: https://github.com/rust-lang/rust/pull/28339
|
||||
[es]: https://github.com/rust-lang/rust/pull/27956
|
||||
[ext]: https://github.com/rust-lang/rust/pull/28094
|
||||
[faststr]: https://github.com/rust-lang/rust/pull/28338
|
||||
[ffi]: https://github.com/rust-lang/rust/pull/28779
|
||||
[fp]: https://github.com/rust-lang/rust/pull/28268
|
||||
[fp2]: https://github.com/rust-lang/rust/pull/28560
|
||||
[fp3]: https://github.com/rust-lang/rust/pull/27307
|
||||
[i]: https://github.com/rust-lang/rust/pull/27451
|
||||
[into2]: https://github.com/rust-lang/rust/pull/28039
|
||||
[it]: https://github.com/rust-lang/rust/pull/27652
|
||||
[mm]: https://github.com/rust-lang/rust/pull/27338
|
||||
[mutw]: https://github.com/rust-lang/rust/pull/28368
|
||||
[sound]: https://github.com/rust-lang/rust/pull/27641
|
||||
[p]: https://github.com/rust-lang/rust/pull/27866
|
||||
[pec]: https://github.com/rust-lang/rust/pull/28486
|
||||
[pr]: https://github.com/rust-lang/rust/pull/27896
|
||||
[RFC 839]: https://github.com/rust-lang/rfcs/blob/master/text/0839-embrace-extend-extinguish.md
|
||||
[RFC 1214]: https://github.com/rust-lang/rfcs/blob/master/text/1214-projections-lifetimes-and-wf.md
|
||||
[s]: https://github.com/rust-lang/rust/pull/27474
|
||||
[stab]: https://github.com/rust-lang/rust/pull/28339
|
||||
[stat]: https://github.com/rust-lang/rust/pull/28321
|
||||
[vd]: https://github.com/rust-lang/rust/pull/28494
|
||||
|
||||
Version 1.3.0 (2015-09-17)
|
||||
==============================
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
# Summary
|
||||
|
||||
* [Getting Started](getting-started.md)
|
||||
* [Installing Rust](installing-rust.md)
|
||||
* [Hello, world!](hello-world.md)
|
||||
* [Hello, Cargo!](hello-cargo.md)
|
||||
* [Learn Rust](learn-rust.md)
|
||||
* [Guessing Game](guessing-game.md)
|
||||
* [Dining Philosophers](dining-philosophers.md)
|
||||
|
@ -1605,14 +1605,11 @@ arguments.
|
||||
|
||||
## Writing the logic
|
||||
|
||||
We're all different in how we write code, but error handling is
|
||||
usually the last thing we want to think about. This isn't very good
|
||||
practice for good design, but it can be useful for rapidly
|
||||
prototyping. In our case, because Rust forces us to be explicit about
|
||||
error handling, it will also make it obvious what parts of our program
|
||||
can cause errors. Why? Because Rust will make us call `unwrap`! This
|
||||
can give us a nice bird's eye view of how we need to approach error
|
||||
handling.
|
||||
We all write code differently, but error handling is usually the last thing we
|
||||
want to think about. This isn't great for the overall design of a program, but
|
||||
it can be useful for rapid prototyping. Because Rust forces us to be explicit
|
||||
about error handling (by making us call `unwrap`), it is easy to see which
|
||||
parts of our program can cause errors.
|
||||
|
||||
In this case study, the logic is really simple. All we need to do is parse the
|
||||
CSV data given to us and print out a field in matching rows. Let's do it. (Make
|
||||
|
@ -3,3 +3,608 @@
|
||||
This first section of the book will get us going with Rust and its tooling.
|
||||
First, we’ll install Rust. Then, the classic ‘Hello World’ program. Finally,
|
||||
we’ll talk about Cargo, Rust’s build system and package manager.
|
||||
|
||||
# Installing Rust
|
||||
|
||||
The first step to using Rust is to install it. Generally speaking, you’ll need
|
||||
an Internet connection to run the commands in this chapter, as we’ll be
|
||||
downloading Rust from the internet.
|
||||
|
||||
We’ll be showing off a number of commands using a terminal, and those lines all
|
||||
start with `$`. We don't need to type in the `$`s, they are there to indicate
|
||||
the start of each command. We’ll see many tutorials and examples around the web
|
||||
that follow this convention: `$` for commands run as our regular user, and `#`
|
||||
for commands we should be running as an administrator.
|
||||
|
||||
## Platform support
|
||||
|
||||
The Rust compiler runs on, and compiles to, a great number of platforms, though
|
||||
not all platforms are equally supported. Rust's support levels are organized
|
||||
into three tiers, each with a different set of guarantees.
|
||||
|
||||
Platforms are identified by their "target triple" which is the string to inform
|
||||
the compiler what kind of output should be produced. The columns below indicate
|
||||
whether the corresponding component works on the specified platform.
|
||||
|
||||
### Tier 1
|
||||
|
||||
Tier 1 platforms can be thought of as "guaranteed to build and work".
|
||||
Specifically they will each satisfy the following requirements:
|
||||
|
||||
* Automated testing is set up to run tests for the platform.
|
||||
* Landing changes to the `rust-lang/rust` repository's master branch is gated on
|
||||
tests passing.
|
||||
* Official release artifacts are provided for the platform.
|
||||
* Documentation for how to use and how to build the platform is available.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | 64-bit MSVC (Windows 7+) |
|
||||
| `i686-pc-windows-gnu` | ✓ | ✓ | ✓ | 32-bit MinGW (Windows 7+) |
|
||||
| `x86_64-pc-windows-gnu` | ✓ | ✓ | ✓ | 64-bit MinGW (Windows 7+) |
|
||||
| `i686-apple-darwin` | ✓ | ✓ | ✓ | 32-bit OSX (10.7+, Lion+) |
|
||||
| `x86_64-apple-darwin` | ✓ | ✓ | ✓ | 64-bit OSX (10.7+, Lion+) |
|
||||
| `i686-unknown-linux-gnu` | ✓ | ✓ | ✓ | 32-bit Linux (2.6.18+) |
|
||||
| `x86_64-unknown-linux-gnu` | ✓ | ✓ | ✓ | 64-bit Linux (2.6.18+) |
|
||||
|
||||
### Tier 2
|
||||
|
||||
Tier 2 platforms can be thought of as "guaranteed to build". Automated tests
|
||||
are not run so it's not guaranteed to produce a working build, but platforms
|
||||
often work to quite a good degree and patches are always welcome! Specifically,
|
||||
these platforms are required to have each of the following:
|
||||
|
||||
* Automated building is set up, but may not be running tests.
|
||||
* Landing changes to the `rust-lang/rust` repository's master branch is gated on
|
||||
platforms **building**. Note that this means for some platforms only the
|
||||
standard library is compiled, but for others the full bootstrap is run.
|
||||
* Official release artifacts are provided for the platform.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `i686-pc-windows-msvc` | ✓ | ✓ | ✓ | 32-bit MSVC (Windows 7+) |
|
||||
|
||||
### Tier 3
|
||||
|
||||
Tier 3 platforms are those which Rust has support for, but landing changes is
|
||||
not gated on the platform either building or passing tests. Working builds for
|
||||
these platforms may be spotty as their reliability is often defined in terms of
|
||||
community contributions. Additionally, release artifacts and installers are not
|
||||
provided, but there may be community infrastructure producing these in
|
||||
unofficial locations.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL |
|
||||
| `arm-linux-androideabi` | ✓ | | | ARM Android |
|
||||
| `i686-linux-android` | ✓ | | | 32-bit x86 Android |
|
||||
| `aarch64-linux-android` | ✓ | | | ARM64 Android |
|
||||
| `arm-unknown-linux-gnueabi` | ✓ | ✓ | | ARM Linux (2.6.18+) |
|
||||
| `arm-unknown-linux-gnueabihf` | ✓ | ✓ | | ARM Linux (2.6.18+) |
|
||||
| `aarch64-unknown-linux-gnu` | ✓ | | | ARM64 Linux (2.6.18+) |
|
||||
| `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) |
|
||||
| `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) |
|
||||
| `powerpc-unknown-linux-gnu` | ✓ | | | PowerPC Linux (2.6.18+) |
|
||||
| `i386-apple-ios` | ✓ | | | 32-bit x86 iOS |
|
||||
| `x86_64-apple-ios` | ✓ | | | 64-bit x86 iOS |
|
||||
| `armv7-apple-ios` | ✓ | | | ARM iOS |
|
||||
| `armv7s-apple-ios` | ✓ | | | ARM iOS |
|
||||
| `aarch64-apple-ios` | ✓ | | | ARM64 iOS |
|
||||
| `i686-unknown-freebsd` | ✓ | ✓ | | 32-bit FreeBSD |
|
||||
| `x86_64-unknown-freebsd` | ✓ | ✓ | | 64-bit FreeBSD |
|
||||
| `x86_64-unknown-openbsd` | ✓ | ✓ | | 64-bit OpenBSD |
|
||||
| `x86_64-unknown-netbsd` | ✓ | ✓ | | 64-bit NetBSD |
|
||||
| `x86_64-unknown-bitrig` | ✓ | ✓ | | 64-bit Bitrig |
|
||||
| `x86_64-unknown-dragonfly` | ✓ | ✓ | | 64-bit DragonFlyBSD |
|
||||
| `x86_64-rumprun-netbsd` | ✓ | | | 64-bit NetBSD Rump Kernel |
|
||||
| `i686-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
|
||||
| `x86_64-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
|
||||
|
||||
Note that this table can be expanded over time, this isn't the exhaustive set of
|
||||
tier 3 platforms that will ever be!
|
||||
|
||||
## Installing on Linux or Mac
|
||||
|
||||
If we're on Linux or a Mac, all we need to do is open a terminal and type this:
|
||||
|
||||
```bash
|
||||
$ curl -sSf https://static.rust-lang.org/rustup.sh | sh
|
||||
```
|
||||
|
||||
This will download a script, and stat the installation. If it all goes well,
|
||||
you’ll see this appear:
|
||||
|
||||
```text
|
||||
Welcome to Rust.
|
||||
|
||||
This script will download the Rust compiler and its package manager, Cargo, and
|
||||
install them to /usr/local. You may install elsewhere by running this script
|
||||
with the --prefix=<path> option.
|
||||
|
||||
The installer will run under ‘sudo’ and may ask you for your password. If you do
|
||||
not want the script to run ‘sudo’ then pass it the --disable-sudo flag.
|
||||
|
||||
You may uninstall later by running /usr/local/lib/rustlib/uninstall.sh,
|
||||
or by running this script again with the --uninstall flag.
|
||||
|
||||
Continue? (y/N)
|
||||
```
|
||||
|
||||
From here, press `y` for ‘yes’, and then follow the rest of the prompts.
|
||||
|
||||
## Installing on Windows
|
||||
|
||||
If you're on Windows, please download the appropriate [installer][install-page].
|
||||
|
||||
[install-page]: https://www.rust-lang.org/install.html
|
||||
|
||||
## Uninstalling
|
||||
|
||||
Uninstalling Rust is as easy as installing it. On Linux or Mac, just run
|
||||
the uninstall script:
|
||||
|
||||
```bash
|
||||
$ sudo /usr/local/lib/rustlib/uninstall.sh
|
||||
```
|
||||
|
||||
If we used the Windows installer, we can re-run the `.msi` and it will give us
|
||||
an uninstall option.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If we've got Rust installed, we can open up a shell, and type this:
|
||||
|
||||
```bash
|
||||
$ rustc --version
|
||||
```
|
||||
|
||||
You should see the version number, commit hash, and commit date.
|
||||
|
||||
If you do, Rust has been installed successfully! Congrats!
|
||||
|
||||
If you don't and you're on Windows, check that Rust is in your %PATH% system
|
||||
variable. If it isn't, run the installer again, select "Change" on the "Change,
|
||||
repair, or remove installation" page and ensure "Add to PATH" is installed on
|
||||
the local hard drive.
|
||||
|
||||
If not, there are a number of places where we can get help. The easiest is
|
||||
[the #rust IRC channel on irc.mozilla.org][irc], which we can access through
|
||||
[Mibbit][mibbit]. Click that link, and we'll be chatting with other Rustaceans
|
||||
(a silly nickname we call ourselves) who can help us out. Other great resources
|
||||
include [the user’s forum][users], and [Stack Overflow][stackoverflow].
|
||||
|
||||
[irc]: irc://irc.mozilla.org/#rust
|
||||
[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
|
||||
[users]: https://users.rust-lang.org/
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
|
||||
|
||||
This installer also installs a copy of the documentation locally, so we can
|
||||
read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location.
|
||||
On Windows, it's in a `share/doc` directory, inside the directory to which Rust
|
||||
was installed.
|
||||
|
||||
# Hello, world!
|
||||
|
||||
Now that you have Rust installed, we'll help you write your first Rust program.
|
||||
It's traditional when learning a new language to write a little program to
|
||||
print the text “Hello, world!” to the screen, and in this section, we'll follow
|
||||
that tradition.
|
||||
|
||||
The nice thing about starting with such a simple program is that you can
|
||||
quickly verify that your compiler is installed, and that it's working properly.
|
||||
Printing information to the screen is also just a pretty common thing to do, so
|
||||
practicing it early on is good.
|
||||
|
||||
> Note: This book assumes basic familiarity with the command line. Rust itself
|
||||
> makes no specific demands about your editing, tooling, or where your code
|
||||
> lives, so if you prefer an IDE to the command line, that's an option. You may
|
||||
> want to check out [SolidOak], which was built specifically with Rust in mind.
|
||||
> There are a number of extensions in development by the community, and the
|
||||
> Rust team ships plugins for [various editors]. Configuring your editor or
|
||||
> IDE is out of the scope of this tutorial, so check the documentation for your
|
||||
> specific setup.
|
||||
|
||||
[SolidOak]: https://github.com/oakes/SolidOak
|
||||
[various editors]: https://github.com/rust-lang/rust/blob/master/src/etc/CONFIGS.md
|
||||
|
||||
## Creating a Project File
|
||||
|
||||
First, make a file to put your Rust code in. Rust doesn't care where your code
|
||||
lives, but for this book, I suggest making a *projects* directory in your home
|
||||
directory, and keeping all your projects there. Open a terminal and enter the
|
||||
following commands to make a directory for this particular project:
|
||||
|
||||
```bash
|
||||
$ mkdir ~/projects
|
||||
$ cd ~/projects
|
||||
$ mkdir hello_world
|
||||
$ cd hello_world
|
||||
```
|
||||
|
||||
> Note: If you’re on Windows and not using PowerShell, the `~` may not work.
|
||||
> Consult the documentation for your shell for more details.
|
||||
|
||||
## Writing and Running a Rust Program
|
||||
|
||||
Next, make a new source file and call it *main.rs*. Rust files always end
|
||||
in a *.rs* extension. If you’re using more than one word in your filename, use
|
||||
an underscore to separate them; for example, you'd use *hello_world.rs* rather
|
||||
than *helloworld.rs*.
|
||||
|
||||
Now open the *main.rs* file you just created, and type the following code:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
Save the file, and go back to your terminal window. On Linux or OSX, enter the
|
||||
following commands:
|
||||
|
||||
```bash
|
||||
$ rustc main.rs
|
||||
$ ./main
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
In Windows, just replace `main` with `main.exe`. Regardless of your operating
|
||||
system, you should see the string `Hello, world!` print to the terminal. If you
|
||||
did, then congratulations! You've officially written a Rust program. That makes
|
||||
you a Rust programmer! Welcome.
|
||||
|
||||
## Anatomy of a Rust Program
|
||||
|
||||
Now, let’s go over what just happened in your "Hello, world!" program in
|
||||
detail. Here's the first piece of the puzzle:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
These lines define a *function* in Rust. The `main` function is special: it's
|
||||
the beginning of every Rust program. The first line says, “I’m declaring a
|
||||
function named `main` that takes no arguments and returns nothing.” If there
|
||||
were arguments, they would go inside the parentheses (`(` and `)`), and because
|
||||
we aren’t returning anything from this function, we can omit the return type
|
||||
entirely.
|
||||
|
||||
Also note that the function body is wrapped in curly braces (`{` and `}`). Rust
|
||||
requires these around all function bodies. It's considered good style to put
|
||||
the opening curly brace on the same line as the function declaration, with one
|
||||
space in between.
|
||||
|
||||
Inside the `main()` function:
|
||||
|
||||
```rust
|
||||
println!("Hello, world!");
|
||||
```
|
||||
|
||||
This line does all of the work in this little program: it prints text to the
|
||||
screen. There are a number of details that are important here. The first is
|
||||
that it’s indented with four spaces, not tabs.
|
||||
|
||||
The second important part is the `println!()` line. This is calling a Rust
|
||||
*[macro]*, which is how metaprogramming is done in Rust. If it were calling a
|
||||
function instead, it would look like this: `println()` (without the !). We'll
|
||||
discuss Rust macros in more detail later, but for now you just need to
|
||||
know that when you see a `!` that means that you’re calling a macro instead of
|
||||
a normal function.
|
||||
|
||||
|
||||
[macro]: macros.html
|
||||
|
||||
Next is `"Hello, world!"` which is a *string*. Strings are a surprisingly
|
||||
complicated topic in a systems programming language, and this is a *[statically
|
||||
allocated]* string. We pass this string as an argument to `println!`, which
|
||||
prints the string to the screen. Easy enough!
|
||||
|
||||
[statically allocated]: the-stack-and-the-heap.html
|
||||
|
||||
The line ends with a semicolon (`;`). Rust is an *[expression oriented]*
|
||||
language, which means that most things are expressions, rather than statements.
|
||||
The `;` indicates that this expression is over, and the next one is ready to
|
||||
begin. Most lines of Rust code end with a `;`.
|
||||
|
||||
[expression-oriented language]: glossary.html#expression-oriented-language
|
||||
|
||||
## Compiling and Running Are Separate Steps
|
||||
|
||||
In "Writing and Running a Rust Program", we showed you how to run a newly
|
||||
created program. We'll break that process down and examine each step now.
|
||||
|
||||
Before running a Rust program, you have to compile it. You can use the Rust
|
||||
compiler by entering the `rustc` command and passing it the name of your source
|
||||
file, like this:
|
||||
|
||||
```bash
|
||||
$ rustc main.rs
|
||||
```
|
||||
|
||||
If you come from a C or C++ background, you'll notice that this is similar to
|
||||
`gcc` or `clang`. After compiling successfully, Rust should output a binary
|
||||
executable, which you can see on Linux or OSX by entering the `ls` command in
|
||||
your shell as follows:
|
||||
|
||||
```bash
|
||||
$ ls
|
||||
main main.rs
|
||||
```
|
||||
|
||||
On Windows, you'd enter:
|
||||
|
||||
```bash
|
||||
$ dir
|
||||
main.exe main.rs
|
||||
```
|
||||
|
||||
This shows we have two files: the source code, with an `.rs` extension, and the
|
||||
executable (`main.exe` on Windows, `main` everywhere else). All that's left to
|
||||
do from here is run the `main` or `main.exe` file, like this:
|
||||
|
||||
```bash
|
||||
$ ./main # or main.exe on Windows
|
||||
```
|
||||
|
||||
If *main.rs* were your "Hello, world!" program, this would print `Hello,
|
||||
world!` to your terminal.
|
||||
|
||||
If you come from a dynamic language like Ruby, Python, or JavaScript, you may
|
||||
not be used to compiling and running a program being separate steps. Rust is an
|
||||
*ahead-of-time compiled* language, which means that you can compile a program,
|
||||
give it to someone else, and they can run it even without Rust installed. If
|
||||
you give someone a `.rb` or `.py` or `.js` file, on the other hand, they need
|
||||
to have a Ruby, Python, or JavaScript implementation installed (respectively),
|
||||
but you only need one command to both compile and run your program. Everything
|
||||
is a tradeoff in language design.
|
||||
|
||||
Just compiling with `rustc` is fine for simple programs, but as your project
|
||||
grows, you'll want to be able to manage all of the options your project has,
|
||||
and make it easy to share your code with other people and projects. Next, I'll
|
||||
introduce you to a tool called Cargo, which will help you write real-world Rust
|
||||
programs.
|
||||
|
||||
# Hello, Cargo!
|
||||
|
||||
Cargo is Rust’s build system and package manager, and Rustaceans use Cargo to
|
||||
manage their Rust projects. Cargo manages three things: building your code,
|
||||
downloading the libraries your code depends on, and building those libraries.
|
||||
We call libraries your code needs ‘dependencies’ since your code depends on
|
||||
them.
|
||||
|
||||
The simplest Rust programs don’t have any dependencies, so right now, you'd
|
||||
only use the first part of its functionality. As you write more complex Rust
|
||||
programs, you’ll want to add dependencies, and if you start off using Cargo,
|
||||
that will be a lot easier to do.
|
||||
|
||||
As the vast, vast majority of Rust projects use Cargo, we will assume that
|
||||
you’re using it for the rest of the book. Cargo comes installed with Rust
|
||||
itself, if you used the official installers. If you installed Rust through some
|
||||
other means, you can check if you have Cargo installed by typing:
|
||||
|
||||
```bash
|
||||
$ cargo --version
|
||||
```
|
||||
|
||||
Into a terminal. If you see a version number, great! If you see an error like
|
||||
‘`command not found`’, then you should look at the documentation for the system
|
||||
in which you installed Rust, to determine if Cargo is separate.
|
||||
|
||||
## Converting to Cargo
|
||||
|
||||
Let’s convert the Hello World program to Cargo. To Cargo-fy a project, you need
|
||||
to do three things:
|
||||
|
||||
1. Put your source file in the right directory.
|
||||
2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere else)
|
||||
and make a new one.
|
||||
3. Make a Cargo configuration file.
|
||||
|
||||
Let's get started!
|
||||
|
||||
### Creating a new Executable and Source Directory
|
||||
|
||||
First, go back to your terminal, move to your *hello_world* directory, and
|
||||
enter the following commands:
|
||||
|
||||
```bash
|
||||
$ mkdir src
|
||||
$ mv main.rs src/main.rs
|
||||
$ rm main # or 'del main.exe' on Windows
|
||||
```
|
||||
|
||||
Cargo expects your source files to live inside a *src* directory, so do that
|
||||
first. This leaves the top-level project directory (in this case,
|
||||
*hello_world*) for READMEs, license information, and anything else not related
|
||||
to your code. In this way, using Cargo helps you keep your projects nice and
|
||||
tidy. There's a place for everything, and everything is in its place.
|
||||
|
||||
Now, copy *main.rs* to the *src* directory, and delete the compiled file you
|
||||
created with `rustc`. As usual, replace `main` with `main.exe` if you're on
|
||||
Windows.
|
||||
|
||||
This example retains `main.rs` as the source filename because it's creating an
|
||||
executable. If you wanted to make a library instead, you'd name the file
|
||||
`lib.rs`. This convention is used by Cargo to successfully compile your
|
||||
projects, but it can be overridden if you wish.
|
||||
|
||||
### Creating a Configuration File
|
||||
|
||||
Next, create a new file inside your *hello_world* directory, and call it
|
||||
`Cargo.toml`.
|
||||
|
||||
Make sure to capitalize the `C` in `Cargo.toml`, or Cargo won't know what to do
|
||||
with the configuration file.
|
||||
|
||||
This file is in the *[TOML]* (Tom's Obvious, Minimal Language) format. TOML is
|
||||
similar to INI, but has some extra goodies, and is used as Cargo’s
|
||||
configuration format.
|
||||
|
||||
[TOML]: https://github.com/toml-lang/toml
|
||||
|
||||
Inside this file, type the following information:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
|
||||
name = "hello_world"
|
||||
version = "0.0.1"
|
||||
authors = [ "Your name <you@example.com>" ]
|
||||
```
|
||||
|
||||
The first line, `[package]`, indicates that the following statements are
|
||||
configuring a package. As we add more information to this file, we’ll add other
|
||||
sections, but for now, we just have the package configuration.
|
||||
|
||||
The other three lines set the three bits of configuration that Cargo needs to
|
||||
know to compile your program: its name, what version it is, and who wrote it.
|
||||
|
||||
Once you've added this information to the *Cargo.toml* file, save it to finish
|
||||
creating the configuration file.
|
||||
|
||||
## Building and Running a Cargo Project
|
||||
|
||||
With your *Cargo.toml* file in place in your project's root directory, you
|
||||
should be ready to build and run your Hello World program! To do so, enter the
|
||||
following commands:
|
||||
|
||||
```bash
|
||||
$ cargo build
|
||||
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
|
||||
$ ./target/debug/hello_world
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
|
||||
|
||||
You just built a project with `cargo build` and ran it with
|
||||
`./target/debug/hello_world`, but you can actually do both in one step with
|
||||
`cargo run` as follows:
|
||||
|
||||
```bash
|
||||
$ cargo run
|
||||
Running `target/debug/hello_world`
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Notice that this example didn’t re-build the project. Cargo figured out that
|
||||
the file hasn’t changed, and so it just ran the binary. If you'd modified your
|
||||
source code, Cargo would have rebuilt the project before running it, and you
|
||||
would have seen something like this:
|
||||
|
||||
```bash
|
||||
$ cargo run
|
||||
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
|
||||
Running `target/debug/hello_world`
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Cargo checks to see if any of your project’s files have been modified, and only
|
||||
rebuilds your project if they’ve changed since the last time you built it.
|
||||
|
||||
With simple projects, Cargo doesn't bring a whole lot over just using `rustc`,
|
||||
but it will become useful in future. With complex projects composed of multiple
|
||||
crates, it’s much easier to let Cargo coordinate the build. With Cargo, you can
|
||||
just run `cargo build`, and it should work the right way.
|
||||
|
||||
## Building for Release
|
||||
|
||||
When your project is finally ready for release, you can use `cargo build
|
||||
--release` to compile your project with optimizations. These optimizations make
|
||||
your Rust code run faster, but turning them on makes your program take longer
|
||||
to compile. This is why there are two different profiles, one for development,
|
||||
and one for building the final program you’ll give to a user.
|
||||
|
||||
Running this command also causes Cargo to create a new file called
|
||||
*Cargo.lock*, which looks like this:
|
||||
|
||||
```toml
|
||||
[root]
|
||||
name = "hello_world"
|
||||
version = "0.0.1"
|
||||
```
|
||||
|
||||
Cargo uses the *Cargo.lock* file to keep track of dependencies in your
|
||||
application. This is the Hello World project's *Cargo.lock* file. This project
|
||||
doesn't have dependencies, so the file is a bit sparse. Realistically, you
|
||||
won't ever need to touch this file yourself; just let Cargo handle it.
|
||||
|
||||
That’s it! If you've been following along, you should have successfully built
|
||||
`hello_world` with Cargo.
|
||||
|
||||
Even though the project is simple, it now uses much of the real tooling you’ll
|
||||
use for the rest of your Rust career. In fact, you can expect to start
|
||||
virtually all Rust projects with some variation on the following commands:
|
||||
|
||||
```bash
|
||||
$ git clone someurl.com/foo
|
||||
$ cd foo
|
||||
$ cargo build
|
||||
```
|
||||
|
||||
## Making A New Cargo Project the Easy Way
|
||||
|
||||
You don’t have to go through that previous process every time you want to start
|
||||
a new project! Cargo can quickly make a bare-bones project directory that you
|
||||
can start developing in right away.
|
||||
|
||||
To start a new project with Cargo, enter `cargo new` at the command line:
|
||||
|
||||
```bash
|
||||
$ cargo new hello_world --bin
|
||||
```
|
||||
|
||||
This command passes `--bin` because the goal is to get straight to making an
|
||||
executable application, as opposed to a library. Executables are often called
|
||||
*binaries* (as in `/usr/bin`, if you’re on a Unix system).
|
||||
|
||||
Cargo has generated two files and one directory for us: a `Cargo.toml` and a
|
||||
*src* directory with a *main.rs* file inside. These should look familliar,
|
||||
they’re exactly what we created by hand, above.
|
||||
|
||||
This output is all you need to get started. First, open `Cargo.toml`. It should
|
||||
look something like this:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
|
||||
name = "hello_world"
|
||||
version = "0.1.0"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
```
|
||||
|
||||
Cargo has populated *Cargo.toml* with reasonable defaults based on the arguments
|
||||
you gave it and your `git` global configuration. You may notice that Cargo has
|
||||
also initialized the `hello_world` directory as a `git` repository.
|
||||
|
||||
Here’s what should be in `src/main.rs`:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
Cargo has generated a "Hello World!" for you, and you’re ready to start coding!
|
||||
|
||||
> Note: If you want to look at Cargo in more detail, check out the official [Cargo
|
||||
guide], which covers all of its features.
|
||||
|
||||
[Cargo guide]: http://doc.crates.io/guide.html
|
||||
|
||||
# Closing Thoughts
|
||||
|
||||
This chapter covered the basics that will serve you well through the rest of
|
||||
this book, and the rest of your time with Rust. Now that you’ve got the tools
|
||||
down, we'll cover more about the Rust language itself.
|
||||
|
||||
You have two options: Dive into a project with ‘[Learn Rust][learnrust]’, or
|
||||
start from the bottom and work your way up with ‘[Syntax and
|
||||
Semantics][syntax]’. More experienced systems programmers will probably prefer
|
||||
‘Learn Rust’, while those from dynamic backgrounds may enjoy either. Different
|
||||
people learn differently! Choose whatever’s right for you.
|
||||
|
||||
[learnrust]: learn-rust.html
|
||||
[syntax]: syntax-and-semantics.html
|
||||
|
@ -1,210 +0,0 @@
|
||||
% Hello, Cargo!
|
||||
|
||||
[Cargo][cratesio] is a tool that Rustaceans use to help manage their Rust
|
||||
projects. Cargo is currently in a pre-1.0 state, and so it is still a work in
|
||||
progress. However, it is already good enough to use for many Rust projects, and
|
||||
so it is assumed that Rust projects will use Cargo from the beginning.
|
||||
|
||||
[cratesio]: http://doc.crates.io
|
||||
|
||||
Cargo manages three things: building our code, downloading the dependencies our
|
||||
code needs, and building those dependencies. At first, our program doesn’t have
|
||||
any dependencies, so we’ll only be using the first part of its functionality.
|
||||
Eventually, we’ll add more. Since we started off by using Cargo, it'll be easy
|
||||
to add later.
|
||||
|
||||
If you installed Rust via the official installers you will also have Cargo. If
|
||||
you installed Rust some other way, you may want to
|
||||
[check the Cargo README][cargoreadme] for specific instructions about installing
|
||||
it.
|
||||
|
||||
[cargoreadme]: https://github.com/rust-lang/cargo#installing-cargo-from-nightlies
|
||||
|
||||
## Converting to Cargo
|
||||
|
||||
Let’s convert Hello World to Cargo.
|
||||
|
||||
To Cargo-ify our project, we need to do three things: Make a `Cargo.toml`
|
||||
configuration file, put our source file in the right place, and get rid of the
|
||||
old executable (`main.exe` on Windows, `main` everywhere else). Let's do that part first:
|
||||
|
||||
```bash
|
||||
$ mkdir src
|
||||
$ mv main.rs src/main.rs
|
||||
$ rm main # or 'del main.exe' on Windows
|
||||
```
|
||||
|
||||
> Note: since we're creating an executable, we retain `main.rs` as the source
|
||||
> filename. If we want to make a library instead, we should use `lib.rs`. This
|
||||
> convention is used by Cargo to successfully compile our projects, but it can
|
||||
> be overridden if we wish. Custom file locations for the entry point can be
|
||||
> specified with a [`[lib]` or `[[bin]]`][crates-custom] key in the TOML file.
|
||||
|
||||
[crates-custom]: http://doc.crates.io/manifest.html#configuring-a-target
|
||||
|
||||
Cargo expects our source files to live inside a `src` directory. That leaves the
|
||||
top level for other things, like READMEs, license information, and anything not
|
||||
related to our code. Cargo helps us keep our projects nice and tidy. A place for
|
||||
everything, and everything in its place.
|
||||
|
||||
Next, our configuration file:
|
||||
|
||||
```bash
|
||||
$ editor Cargo.toml # or 'notepad Cargo.toml' on Windows
|
||||
```
|
||||
|
||||
Make sure to get this name right: we need the capital `C`!
|
||||
|
||||
Put this inside:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
|
||||
name = "hello_world"
|
||||
version = "0.0.1"
|
||||
authors = [ "Your name <you@example.com>" ]
|
||||
```
|
||||
|
||||
This file is in the [TOML][toml] format. TOML is similar to INI, but has some
|
||||
extra goodies. According to the TOML docs,
|
||||
|
||||
> TOML aims to be a minimal configuration file format that's easy to read due
|
||||
> to obvious semantics. TOML is designed to map unambiguously to a hash table.
|
||||
> TOML should be easy to parse into data structures in a wide variety of
|
||||
> languages.
|
||||
|
||||
[toml]: https://github.com/toml-lang/toml
|
||||
|
||||
Once we have this file in place in our project's root directory, we should be
|
||||
ready to build! To do so, run:
|
||||
|
||||
```bash
|
||||
$ cargo build
|
||||
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
|
||||
$ ./target/debug/hello_world
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Bam! We built our project with `cargo build`, and ran it with
|
||||
`./target/debug/hello_world`. We can do both in one step with `cargo run`:
|
||||
|
||||
```bash
|
||||
$ cargo run
|
||||
Running `target/debug/hello_world`
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Notice that we didn’t re-build the project this time. Cargo figured out that
|
||||
we hadn’t changed the source file, and so it just ran the binary. If we had
|
||||
made a modification, we would have seen it do both:
|
||||
|
||||
```bash
|
||||
$ cargo run
|
||||
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
|
||||
Running `target/debug/hello_world`
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
This hasn’t bought us a whole lot over our simple use of `rustc`, but think
|
||||
about the future: when our project gets more complex, we need to do more
|
||||
things to get all of the parts to properly compile. With Cargo, as our project
|
||||
grows, we can just run `cargo build`, and it’ll work the right way.
|
||||
|
||||
When our project is finally ready for release, we can use `cargo build
|
||||
--release` to compile our project with optimizations.
|
||||
|
||||
You'll also notice that Cargo has created a new file: `Cargo.lock`.
|
||||
|
||||
```toml
|
||||
[root]
|
||||
name = "hello_world"
|
||||
version = "0.0.1"
|
||||
```
|
||||
|
||||
The `Cargo.lock` file is used by Cargo to keep track of dependencies in our
|
||||
application. Right now, we don’t have any, so it’s a bit sparse. We won't ever
|
||||
need to touch this file ourselves, just let Cargo handle it.
|
||||
|
||||
That’s it! We’ve successfully built `hello_world` with Cargo. Even though our
|
||||
program is simple, it’s using much of the real tooling that we’ll use for the
|
||||
rest of our Rust career. We can expect to do this to get started with virtually
|
||||
all Rust projects:
|
||||
|
||||
```bash
|
||||
$ git clone someurl.com/foo
|
||||
$ cd foo
|
||||
$ cargo build
|
||||
```
|
||||
|
||||
## A New Project
|
||||
|
||||
We don’t have to go through this whole process every time we want to start a new
|
||||
project! Cargo has the ability to make a bare-bones project directory in which
|
||||
we can start developing right away.
|
||||
|
||||
To start a new project with Cargo, we use `cargo new`:
|
||||
|
||||
```bash
|
||||
$ cargo new hello_world --bin
|
||||
```
|
||||
|
||||
We’re passing `--bin` because our goal is to get straight to making an
|
||||
executable application, as opposed to a library. Executables are often called
|
||||
‘binaries.’ (as in `/usr/bin`, if we’re on a Unix system)
|
||||
|
||||
Let's check out what Cargo has generated for us:
|
||||
|
||||
```bash
|
||||
$ cd hello_world
|
||||
$ tree .
|
||||
.
|
||||
├── Cargo.toml
|
||||
└── src
|
||||
└── main.rs
|
||||
|
||||
1 directory, 2 files
|
||||
```
|
||||
|
||||
If we don't have the `tree` command, we can probably get it from our
|
||||
distribution’s package manager. It’s not necessary, but it’s certainly useful.
|
||||
|
||||
This is all we need to get started. First, let’s check out `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
|
||||
name = "hello_world"
|
||||
version = "0.1.0"
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
```
|
||||
|
||||
Cargo has populated this file with reasonable defaults based off the arguments
|
||||
we gave it and our `git` global configuration. You may notice that Cargo has
|
||||
also initialized the `hello_world` directory as a `git` repository.
|
||||
|
||||
Here’s what’s in `src/main.rs`:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
Cargo has generated a "Hello World!" for us, and we’re ready to start coding!
|
||||
Cargo has its own [guide][guide] which covers Cargo’s features in much more
|
||||
depth.
|
||||
|
||||
[guide]: http://doc.crates.io/guide.html
|
||||
|
||||
Now that we’ve got the tools down, let’s actually learn more about the Rust
|
||||
language itself. These are the basics that will serve us well through the rest
|
||||
of our time with Rust.
|
||||
|
||||
You have two options: Dive into a project with ‘[Learn Rust][learnrust]’, or
|
||||
start from the bottom and work your way up with
|
||||
‘[Syntax and Semantics][syntax]’. More experienced systems programmers will
|
||||
probably prefer ‘Learn Rust’, while those from dynamic backgrounds may enjoy
|
||||
either. Different people learn differently! Choose whatever’s right for you.
|
||||
|
||||
[learnrust]: learn-rust.html
|
||||
[syntax]: syntax-and-semantics.html
|
@ -1,171 +0,0 @@
|
||||
% Hello, world!
|
||||
|
||||
Now that we have Rust installed, let’s write our first Rust program. It’s
|
||||
traditional to make our first program in any new language one that prints the
|
||||
text “Hello, world!” to the screen. The nice thing about starting with such a
|
||||
simple program is that we can verify that our compiler isn’t just installed, but
|
||||
also working properly. And printing information to the screen is a pretty common
|
||||
thing to do.
|
||||
|
||||
The first thing that we need to do is make a file to put our code in. I like to
|
||||
make a `projects` directory in my home directory, and keep all my projects
|
||||
there. Rust doesn't care where our code lives.
|
||||
|
||||
This actually leads to one other concern we should address: this guide will
|
||||
assume that we have basic familiarity with the command line. Rust itself makes
|
||||
no specific demands on our editing tooling, or where our code lives. If we
|
||||
prefer an IDE to the command line, we may want to check out
|
||||
[SolidOak][solidoak], or wherever plugins are for our favorite IDE. There are a
|
||||
number of extensions of varying quality in development by the community. The
|
||||
Rust team also ships [plugins for various editors][plugins]. Configuring our
|
||||
editor or IDE is out of the scope of this tutorial, so check the documentation
|
||||
for our setup, specifically.
|
||||
|
||||
[solidoak]: https://github.com/oakes/SolidOak
|
||||
[plugins]: https://github.com/rust-lang/rust/blob/master/src/etc/CONFIGS.md
|
||||
|
||||
With that said, let’s make a directory in our projects directory.
|
||||
|
||||
```bash
|
||||
$ mkdir ~/projects
|
||||
$ cd ~/projects
|
||||
$ mkdir hello_world
|
||||
$ cd hello_world
|
||||
```
|
||||
|
||||
If we’re on Windows and not using PowerShell, the `~` may not work. Consult the
|
||||
documentation for our shell for more details.
|
||||
|
||||
Let’s make a new source file next. We’ll call our file `main.rs`. Rust files
|
||||
always end in a `.rs` extension, and if we’re using more than one word in a
|
||||
Rust filename, we use an underscore: for example, `linked_list.rs`, not
|
||||
`linkedlist.rs` or `LinkedList.rs`.
|
||||
|
||||
Now that we’ve got our file open, type this in:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
Save the file, and then type this into our terminal window:
|
||||
|
||||
```bash
|
||||
$ rustc main.rs
|
||||
$ ./main # or main.exe on Windows
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Success! Let’s go over what just happened in detail.
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
These lines define a *function* in Rust. The `main` function is special:
|
||||
it's the beginning of every Rust program. The first line says "I’m declaring a
|
||||
function named `main` which takes no arguments and returns nothing." If there
|
||||
were arguments, they would go inside the parentheses (`(` and `)`), and because
|
||||
we aren’t returning anything from this function, we can omit the return type
|
||||
entirely. We’ll get to it later.
|
||||
|
||||
You’ll also note that the function is wrapped in curly braces (`{` and `}`).
|
||||
Rust requires these around all function bodies. It is also considered good style
|
||||
to put the opening curly brace on the same line as the function declaration,
|
||||
with one space in between.
|
||||
|
||||
Next up is this line:
|
||||
|
||||
```rust
|
||||
println!("Hello, world!");
|
||||
```
|
||||
|
||||
This line does all of the work in our little program. There are a number of
|
||||
details that are important here. The first is that it’s indented with four
|
||||
spaces, not tabs. Please configure your editor of choice to insert four spaces
|
||||
with the tab key. We provide some
|
||||
[sample configurations for various editors][configs].
|
||||
|
||||
[configs]: https://github.com/rust-lang/rust/tree/master/src/etc/CONFIGS.md
|
||||
|
||||
The second point is the `println!()` part. This is calling a Rust
|
||||
[macro][macro], which is how metaprogramming is done in Rust. If it were a
|
||||
function instead, it would look like this: `println()`. For our purposes, we
|
||||
don’t need to worry about this difference. Just know that sometimes, we’ll see a
|
||||
`!`, and that means that we’re calling a macro instead of a normal function.
|
||||
Rust implements `println!` as a macro rather than a function for good reasons,
|
||||
but that's an advanced topic. One last thing to mention: Rust’s macros are
|
||||
significantly different from C macros, if you’ve used those. Don’t be scared of
|
||||
using macros. We’ll get to the details eventually, you’ll just have to take it
|
||||
on trust for now.
|
||||
|
||||
[macro]: macros.html
|
||||
|
||||
Next, `"Hello, world!"` is a ‘string’. Strings are a surprisingly complicated
|
||||
topic in a systems programming language, and this is a ‘statically allocated’
|
||||
string. If you want to read further about allocation, check out [the stack and
|
||||
the heap][allocation], but you don’t need to right now if you don’t want to. We
|
||||
pass this string as an argument to `println!`, which prints the string to the
|
||||
screen. Easy enough!
|
||||
|
||||
[allocation]: the-stack-and-the-heap.html
|
||||
|
||||
Finally, the line ends with a semicolon (`;`). Rust is an [‘expression oriented’
|
||||
language][expression-oriented language], which means that most things are
|
||||
expressions, rather than statements. The `;` is used to indicate that this
|
||||
expression is over, and the next one is ready to begin. Most lines of Rust code
|
||||
end with a `;`.
|
||||
|
||||
[expression-oriented language]: glossary.html#expression-oriented-language
|
||||
|
||||
Finally, actually compiling and running our program. We can compile with our
|
||||
compiler, `rustc`, by passing it the name of our source file:
|
||||
|
||||
```bash
|
||||
$ rustc main.rs
|
||||
```
|
||||
|
||||
This is similar to `gcc` or `clang`, if you come from a C or C++ background.
|
||||
Rust will output a binary executable. We can see it with `ls`:
|
||||
|
||||
```bash
|
||||
$ ls
|
||||
main main.rs
|
||||
```
|
||||
|
||||
Or on Windows:
|
||||
|
||||
```bash
|
||||
$ dir
|
||||
main.exe main.rs
|
||||
```
|
||||
|
||||
There are now two files: our source code, with the `.rs` extension, and the
|
||||
executable (`main.exe` on Windows, `main` everywhere else).
|
||||
|
||||
```bash
|
||||
$ ./main # or main.exe on Windows
|
||||
```
|
||||
|
||||
This prints out our `Hello, world!` text to our terminal.
|
||||
|
||||
If you come from a dynamic language like Ruby, Python, or JavaScript, you may
|
||||
not be used to these two steps being separate. Rust is an ‘ahead-of-time
|
||||
compiled language’, which means that we can compile a program, give it to
|
||||
someone else, and they don't need to have Rust installed. If we give someone a
|
||||
`.rb` or `.py` or `.js` file, they need to have a Ruby/Python/JavaScript
|
||||
implementation installed, but we just need one command to both compile and run
|
||||
our program. Everything is a tradeoff in language design, and Rust has made its
|
||||
choice.
|
||||
|
||||
Congratulations! You have officially written a Rust program. That makes you a
|
||||
Rust programmer! Welcome. 🎊🎉👍
|
||||
|
||||
Next, I'd like to introduce you to another tool, Cargo, which is used to write
|
||||
real-world Rust programs. Just using `rustc` is nice for simple things, but as
|
||||
our project grows, we'll want something to help us manage all of the options
|
||||
that it has, and to make it easy to share our code with other people and
|
||||
projects.
|
@ -1,184 +0,0 @@
|
||||
% Installing Rust
|
||||
|
||||
The first step to using Rust is to install it! There are a number of ways to
|
||||
install Rust, but the easiest is to use the `rustup` script. If we're on Linux
|
||||
or a Mac, all we need to do is this:
|
||||
|
||||
> Note: we don't need to type in the `$`s, they are there to indicate the start of
|
||||
> each command. We’ll see many tutorials and examples around the web that
|
||||
> follow this convention: `$` for commands run as our regular user, and `#` for
|
||||
> commands we should be running as an administrator.
|
||||
|
||||
```bash
|
||||
$ curl -sf -L https://static.rust-lang.org/rustup.sh | sh
|
||||
```
|
||||
|
||||
If we're concerned about the [potential insecurity][insecurity] of using `curl |
|
||||
sh`, please keep reading and see our disclaimer below. And feel free to use a
|
||||
two-step version of the installation and examine our installation script:
|
||||
|
||||
```bash
|
||||
$ curl -f -L https://static.rust-lang.org/rustup.sh -O
|
||||
$ sh rustup.sh
|
||||
```
|
||||
|
||||
[insecurity]: http://curlpipesh.tumblr.com
|
||||
|
||||
If you're on Windows, please download the appropriate [installer][install-page].
|
||||
|
||||
> Note: By default, the Windows installer won't add Rust to the %PATH% system
|
||||
> variable. If this is the only version of Rust we are installing and we want to
|
||||
> be able to run it from the command line, click on "Advanced" on the install
|
||||
> dialog and on the "Product Features" page ensure "Add to PATH" is installed on
|
||||
> the local hard drive.
|
||||
|
||||
|
||||
[install-page]: https://www.rust-lang.org/install.html
|
||||
|
||||
## Uninstalling
|
||||
|
||||
If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
|
||||
Not every programming language is great for everyone. We can run the
|
||||
uninstall script:
|
||||
|
||||
```bash
|
||||
$ sudo /usr/local/lib/rustlib/uninstall.sh
|
||||
```
|
||||
|
||||
If we used the Windows installer, we can re-run the `.msi` and it will give
|
||||
us an uninstall option.
|
||||
|
||||
## That disclaimer we promised
|
||||
|
||||
Some people, and somewhat rightfully so, get very upset when we tell them to
|
||||
`curl | sh`. Their concern is that `curl | sh` implicitly requires you to trust
|
||||
that the good people who maintain Rust aren't going to hack your computer and
|
||||
do bad things — and even having accepted that, there is still the possibility
|
||||
that the Rust website has been hacked and the `rustup` script compromised.
|
||||
|
||||
Being wary of such possibilities is a good instinct! If you're uncomfortable
|
||||
using `curl | sh` for reasons like these, please check out the documentation on
|
||||
[building Rust from Source][from-source], or
|
||||
[the official binary downloads][install-page].
|
||||
|
||||
[from-source]: https://github.com/rust-lang/rust#building-from-source
|
||||
|
||||
## Platform support
|
||||
|
||||
The Rust compiler runs on, and compiles to, a great number of platforms, though
|
||||
not all platforms are equally supported. Rust's support levels are organized
|
||||
into three tiers, each with a different set of guarantees.
|
||||
|
||||
Platforms are identified by their "target triple" which is the string to inform
|
||||
the compiler what kind of output should be produced. The columns below indicate
|
||||
whether the corresponding component works on the specified platform.
|
||||
|
||||
### Tier 1
|
||||
|
||||
Tier 1 platforms can be thought of as "guaranteed to build and work".
|
||||
Specifically they will each satisfy the following requirements:
|
||||
|
||||
* Automated testing is set up to run tests for the platform.
|
||||
* Landing changes to the `rust-lang/rust` repository's master branch is gated on
|
||||
tests passing.
|
||||
* Official release artifacts are provided for the platform.
|
||||
* Documentation for how to use and how to build the platform is available.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | 64-bit MSVC (Windows 7+) |
|
||||
| `i686-pc-windows-gnu` | ✓ | ✓ | ✓ | 32-bit MinGW (Windows 7+) |
|
||||
| `x86_64-pc-windows-gnu` | ✓ | ✓ | ✓ | 64-bit MinGW (Windows 7+) |
|
||||
| `i686-apple-darwin` | ✓ | ✓ | ✓ | 32-bit OSX (10.7+, Lion+) |
|
||||
| `x86_64-apple-darwin` | ✓ | ✓ | ✓ | 64-bit OSX (10.7+, Lion+) |
|
||||
| `i686-unknown-linux-gnu` | ✓ | ✓ | ✓ | 32-bit Linux (2.6.18+) |
|
||||
| `x86_64-unknown-linux-gnu` | ✓ | ✓ | ✓ | 64-bit Linux (2.6.18+) |
|
||||
|
||||
### Tier 2
|
||||
|
||||
Tier 2 platforms can be thought of as "guaranteed to build". Automated tests are
|
||||
not run so it's not guaranteed to produce a working build, but platforms often
|
||||
work to quite a good degree and patches are always welcome! Specifically, these
|
||||
platforms are required to have each of the following:
|
||||
|
||||
* Automated building is set up, but may not be running tests.
|
||||
* Landing changes to the `rust-lang/rust` repository's master branch is gated on
|
||||
platforms **building**. Note that this means for some platforms only the
|
||||
standard library is compiled, but for others the full bootstrap is run.
|
||||
* Official release artifacts are provided for the platform.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `i686-pc-windows-msvc` | ✓ | ✓ | ✓ | 32-bit MSVC (Windows 7+) |
|
||||
|
||||
### Tier 3
|
||||
|
||||
Tier 3 platforms are those which Rust has support for, but landing changes is
|
||||
not gated on the platform either building or passing tests. Working builds for
|
||||
these platforms may be spotty as their reliability is often defined in terms of
|
||||
community contributions. Additionally, release artifacts and installers are not
|
||||
provided, but there may be community infrastructure producing these in
|
||||
unofficial locations.
|
||||
|
||||
| Target | std |rustc|cargo| notes |
|
||||
|-------------------------------|-----|-----|-----|----------------------------|
|
||||
| `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL |
|
||||
| `arm-linux-androideabi` | ✓ | | | ARM Android |
|
||||
| `i686-linux-android` | ✓ | | | 32-bit x86 Android |
|
||||
| `aarch64-linux-android` | ✓ | | | ARM64 Android |
|
||||
| `arm-unknown-linux-gnueabi` | ✓ | ✓ | | ARM Linux (2.6.18+) |
|
||||
| `arm-unknown-linux-gnueabihf` | ✓ | ✓ | | ARM Linux (2.6.18+) |
|
||||
| `aarch64-unknown-linux-gnu` | ✓ | | | ARM64 Linux (2.6.18+) |
|
||||
| `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) |
|
||||
| `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) |
|
||||
| `powerpc-unknown-linux-gnu` | ✓ | | | PowerPC Linux (2.6.18+) |
|
||||
| `i386-apple-ios` | ✓ | | | 32-bit x86 iOS |
|
||||
| `x86_64-apple-ios` | ✓ | | | 64-bit x86 iOS |
|
||||
| `armv7-apple-ios` | ✓ | | | ARM iOS |
|
||||
| `armv7s-apple-ios` | ✓ | | | ARM iOS |
|
||||
| `aarch64-apple-ios` | ✓ | | | ARM64 iOS |
|
||||
| `i686-unknown-freebsd` | ✓ | ✓ | | 32-bit FreeBSD |
|
||||
| `x86_64-unknown-freebsd` | ✓ | ✓ | | 64-bit FreeBSD |
|
||||
| `x86_64-unknown-openbsd` | ✓ | ✓ | | 64-bit OpenBSD |
|
||||
| `x86_64-unknown-netbsd` | ✓ | ✓ | | 64-bit NetBSD |
|
||||
| `x86_64-unknown-bitrig` | ✓ | ✓ | | 64-bit Bitrig |
|
||||
| `x86_64-unknown-dragonfly` | ✓ | ✓ | | 64-bit DragonFlyBSD |
|
||||
| `x86_64-rumprun-netbsd` | ✓ | | | 64-bit NetBSD Rump Kernel |
|
||||
| `i686-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
|
||||
| `x86_64-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
|
||||
|
||||
Note that this table can be expanded over time, this isn't the exhaustive set of
|
||||
tier 3 platforms that will ever be!
|
||||
|
||||
## After installation
|
||||
|
||||
If we've got Rust installed, we can open up a shell, and type this:
|
||||
|
||||
```bash
|
||||
$ rustc --version
|
||||
```
|
||||
|
||||
You should see the version number, commit hash, and commit date.
|
||||
|
||||
If you do, Rust has been installed successfully! Congrats!
|
||||
|
||||
If you don't and you're on Windows, check that Rust is in your %PATH% system
|
||||
variable. If it isn't, run the installer again, select "Change" on the "Change,
|
||||
repair, or remove installation" page and ensure "Add to PATH" is installed on
|
||||
the local hard drive.
|
||||
|
||||
This installer also installs a copy of the documentation locally, so we can read
|
||||
it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location. On
|
||||
Windows, it's in a `share/doc` directory, inside the directory to which Rust was
|
||||
installed.
|
||||
|
||||
If not, there are a number of places where we can get help. The easiest is
|
||||
[the #rust IRC channel on irc.mozilla.org][irc], which we can access through
|
||||
[Mibbit][mibbit]. Click that link, and we'll be chatting with other Rustaceans
|
||||
(a silly nickname we call ourselves) who can help us out. Other great resources
|
||||
include [the user’s forum][users], and [Stack Overflow][stackoverflow].
|
||||
|
||||
[irc]: irc://irc.mozilla.org/#rust
|
||||
[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
|
||||
[users]: https://users.rust-lang.org/
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
|
@ -43,8 +43,6 @@ fn main() {
|
||||
|
||||
This will print `12.566371`.
|
||||
|
||||
|
||||
|
||||
We’ve made a `struct` that represents a circle. We then write an `impl` block,
|
||||
and inside it, define a method, `area`.
|
||||
|
||||
@ -83,6 +81,35 @@ impl Circle {
|
||||
}
|
||||
```
|
||||
|
||||
You can use as many `impl` blocks as you’d like. The previous example could
|
||||
have also been written like this:
|
||||
|
||||
```rust
|
||||
struct Circle {
|
||||
x: f64,
|
||||
y: f64,
|
||||
radius: f64,
|
||||
}
|
||||
|
||||
impl Circle {
|
||||
fn reference(&self) {
|
||||
println!("taking self by reference!");
|
||||
}
|
||||
}
|
||||
|
||||
impl Circle {
|
||||
fn mutable_reference(&mut self) {
|
||||
println!("taking self by mutable reference!");
|
||||
}
|
||||
}
|
||||
|
||||
impl Circle {
|
||||
fn takes_ownership(self) {
|
||||
println!("taking ownership of self!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Chaining method calls
|
||||
|
||||
So, now we know how to call a method, such as `foo.bar()`. But what about our
|
||||
|
@ -732,6 +732,8 @@ impl<T> [T] {
|
||||
///
|
||||
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
|
||||
///
|
||||
/// This is a stable sort.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -1565,6 +1565,8 @@ pub trait Iterator {
|
||||
/// as soon as it finds a `false`, given that no matter what else happens,
|
||||
/// the result will also be `false`.
|
||||
///
|
||||
/// An empty iterator returns `true`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -1613,6 +1615,8 @@ pub trait Iterator {
|
||||
/// as soon as it finds a `true`, given that no matter what else happens,
|
||||
/// the result will also be `true`.
|
||||
///
|
||||
/// An empty iterator returns `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -2071,6 +2075,8 @@ pub trait Iterator {
|
||||
///
|
||||
/// Takes each element, adds them together, and returns the result.
|
||||
///
|
||||
/// An empty iterator returns the zero value of the type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -2094,6 +2100,8 @@ pub trait Iterator {
|
||||
|
||||
/// Iterates over the entire iterator, multiplying all the elements
|
||||
///
|
||||
/// An empty iterator returns the one value of the type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -601,6 +601,9 @@ impl<K, V, S> HashMap<K, V, S>
|
||||
|
||||
/// Returns the number of elements the map can hold without reallocating.
|
||||
///
|
||||
/// This number is a lower bound; the `HashMap<K, V>` might be able to hold
|
||||
/// more, but is guaranteed to be able to hold at least this many.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
22
src/test/run-pass/issue-24954.rs
Normal file
22
src/test/run-pass/issue-24954.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
macro_rules! foo {
|
||||
($y:expr) => ({
|
||||
$y = 2;
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[allow(unused_assignments)]
|
||||
fn main() {
|
||||
let mut x = 1;
|
||||
foo!(x);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user