diff --git a/src/doc/trpl/dining-philosophers.md b/src/doc/trpl/dining-philosophers.md index 28702d95b60a7..e81ae4648ad43 100644 --- a/src/doc/trpl/dining-philosophers.md +++ b/src/doc/trpl/dining-philosophers.md @@ -512,6 +512,7 @@ impl Philosopher { fn eat(&self, table: &Table) { let _left = table.forks[self.left].lock().unwrap(); + thread::sleep_ms(150); let _right = table.forks[self.right].lock().unwrap(); println!("{} is eating.", self.name); @@ -597,6 +598,7 @@ We now need to construct those `left` and `right` values, so we add them to ```rust,ignore fn eat(&self, table: &Table) { let _left = table.forks[self.left].lock().unwrap(); + thread::sleep_ms(150); let _right = table.forks[self.right].lock().unwrap(); println!("{} is eating.", self.name); @@ -607,11 +609,14 @@ fn eat(&self, table: &Table) { } ``` -We have two new lines. We’ve also added an argument, `table`. We access the +We have three new lines. We’ve added an argument, `table`. We access the `Table`’s list of forks, and then use `self.left` and `self.right` to access the fork at that particular index. That gives us access to the `Mutex` at that index, and we call `lock()` on it. If the mutex is currently being accessed by -someone else, we’ll block until it becomes available. +someone else, we’ll block until it becomes available. We have also a call to +`thread::sleep_ms` between the moment first fork is picked and the moment the +second forked is picked, as the process of picking up the fork is not +immediate. The call to `lock()` might fail, and if it does, we want to crash. In this case, the error that could happen is that the mutex is [‘poisoned’][poison], @@ -660,7 +665,9 @@ We need to pass in our `left` and `right` values to the constructors for our you look at the pattern, it’s all consistent until the very end. Monsieur Foucault should have `4, 0` as arguments, but instead, has `0, 4`. This is what prevents deadlock, actually: one of our philosophers is left handed! This is -one way to solve the problem, and in my opinion, it’s the simplest. +one way to solve the problem, and in my opinion, it’s the simplest. If you +change the order of the parameters, you will be able to observe the deadlock +taking place. ```rust,ignore let handles: Vec<_> = philosophers.into_iter().map(|p| { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index f9dc65b95aade..93d9f04197f4d 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1618,7 +1618,13 @@ impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F> where impl<A, B> ExactSizeIterator for Zip<A, B> where A: ExactSizeIterator, B: ExactSizeIterator {} -/// An double-ended iterator with the direction inverted +/// An double-ended iterator with the direction inverted. +/// +/// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`rev()`]: trait.Iterator.html#method.rev +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1642,7 +1648,13 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator { fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() } } -/// An iterator that clones the elements of an underlying iterator +/// An iterator that clones the elements of an underlying iterator. +/// +/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cloned()`]: trait.Iterator.html#method.cloned +/// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_cloned", since = "1.1.0")] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Clone)] @@ -1679,7 +1691,13 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I> where I: ExactSizeIterator<Item=&'a T>, T: Clone {} -/// An iterator that repeats endlessly +/// An iterator that repeats endlessly. +/// +/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cycle()`]: trait.Iterator.html#method.cycle +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1711,7 +1729,13 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator { } } -/// An iterator that strings two iterators together +/// An iterator that strings two iterators together. +/// +/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1849,7 +1873,13 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where } } -/// An iterator that iterates two other iterators simultaneously +/// An iterator that iterates two other iterators simultaneously. +/// +/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`zip()`]: trait.Iterator.html#method.zip +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1915,7 +1945,13 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where } } -/// An iterator that maps the values of `iter` with `f` +/// An iterator that maps the values of `iter` with `f`. +/// +/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`map()`]: trait.Iterator.html#method.map +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -1949,7 +1985,13 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where } } -/// An iterator that filters the elements of `iter` with `predicate` +/// An iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter()`]: trait.Iterator.html#method.filter +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -1994,7 +2036,13 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P> } } -/// An iterator that uses `f` to both filter and map elements from `iter` +/// An iterator that uses `f` to both filter and map elements from `iter`. +/// +/// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter_map()`]: trait.Iterator.html#method.filter_map +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -2041,7 +2089,13 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F> } } -/// An iterator that yields the current count and the element during iteration +/// An iterator that yields the current count and the element during iteration. +/// +/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`enumerate()`]: trait.Iterator.html#method.enumerate +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2108,7 +2162,14 @@ impl<I> DoubleEndedIterator for Enumerate<I> where } } -/// An iterator with a `peek()` that returns an optional reference to the next element. +/// An iterator with a `peek()` that returns an optional reference to the next +/// element. +/// +/// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`peekable()`]: trait.Iterator.html#method.peekable +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2190,7 +2251,13 @@ impl<I: Iterator> Peekable<I> { } } -/// An iterator that rejects elements while `predicate` is true +/// An iterator that rejects elements while `predicate` is true. +/// +/// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip_while()`]: trait.Iterator.html#method.skip_while +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -2224,7 +2291,13 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P> } } -/// An iterator that only accepts elements while `predicate` is true +/// An iterator that only accepts elements while `predicate` is true. +/// +/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take_while()`]: trait.Iterator.html#method.take_while +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -2264,6 +2337,12 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P> } /// An iterator that skips over `n` elements of `iter`. +/// +/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip()`]: trait.Iterator.html#method.skip +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2338,6 +2417,12 @@ impl<I> Iterator for Skip<I> where I: Iterator { impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {} /// An iterator that only iterates over the first `n` iterations of `iter`. +/// +/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2393,7 +2478,13 @@ impl<I> Iterator for Take<I> where I: Iterator{ impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {} -/// An iterator to maintain state while iterating another iterator +/// An iterator to maintain state while iterating another iterator. +/// +/// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`scan()`]: trait.Iterator.html#method.scan +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -2422,9 +2513,14 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where } } -/// An iterator that maps each element to an iterator, -/// and yields the elements of the produced iterators +/// An iterator that maps each element to an iterator, and yields the elements +/// of the produced iterators. /// +/// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flat_map()`]: trait.Iterator.html#method.flat_map +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -2493,8 +2589,11 @@ impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> wher /// An iterator that yields `None` forever after the underlying iterator /// yields `None` once. /// -/// These can be created through -/// [`iter.fuse()`](trait.Iterator.html#method.fuse). +/// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`fuse()`]: trait.Iterator.html#method.fuse +/// [`Iterator`]: trait.Iterator.html #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2574,8 +2673,14 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator { #[stable(feature = "rust1", since = "1.0.0")] impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {} -/// An iterator that calls a function with a reference to each -/// element before yielding it. +/// An iterator that calls a function with a reference to each element before +/// yielding it. +/// +/// This `struct` is created by the [`inspect()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`inspect()`]: trait.Iterator.html#method.inspect +/// [`Iterator`]: trait.Iterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] @@ -3009,7 +3114,11 @@ impl<A: Step + One> Iterator for ops::RangeFrom<A> where } } -/// An iterator that repeats an element endlessly +/// An iterator that repeats an element endlessly. +/// +/// This `struct` is created by the [`repeat()`] function. See its documentation for more. +/// +/// [`repeat()`]: fn.repeat.html #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat<A> { @@ -3085,6 +3194,10 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> { } /// An iterator that yields nothing. +/// +/// This `struct` is created by the [`empty()`] function. See its documentation for more. +/// +/// [`empty()`]: fn.empty.html #[stable(feature = "iter_empty", since = "1.2.0")] pub struct Empty<T>(marker::PhantomData<T>); @@ -3153,6 +3266,10 @@ pub fn empty<T>() -> Empty<T> { } /// An iterator that yields an element exactly once. +/// +/// This `struct` is created by the [`once()`] function. See its documentation for more. +/// +/// [`once()`]: fn.once.html #[derive(Clone)] #[stable(feature = "iter_once", since = "1.2.0")] pub struct Once<T> { diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 0f72dcc1281a4..7225b4f6e0d2a 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -153,7 +153,8 @@ unsafe impl<T> Sync for AtomicPtr<T> {} #[stable(feature = "rust1", since = "1.0.0")] #[derive(Copy, Clone)] pub enum Ordering { - /// No ordering constraints, only atomic operations. + /// No ordering constraints, only atomic operations. Corresponds to LLVM's + /// `Monotonic` ordering. #[stable(feature = "rust1", since = "1.0.0")] Relaxed, /// When coupled with a store, all previous writes become visible diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 166909f20b7e1..ebe50a6e2b8a2 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -20,11 +20,11 @@ //! //! # Read and Write //! -//! Because they are traits, they're implemented by a number of other types, -//! and you can implement them for your types too. As such, you'll see a -//! few different types of I/O throughout the documentation in this module: -//! `File`s, `TcpStream`s, and sometimes even `Vec<T>`s. For example, `Read` -//! adds a `read()` method, which we can use on `File`s: +//! Because they are traits, `Read` and `Write` are implemented by a number +//! of other types, and you can implement them for your types too. As such, +//! you'll see a few different types of I/O throughout the documentation in +//! this module: `File`s, `TcpStream`s, and sometimes even `Vec<T>`s. For +//! example, `Read` adds a `read()` method, which we can use on `File`s: //! //! ``` //! use std::io; @@ -111,7 +111,7 @@ //! # } //! ``` //! -//! `BufWriter` doesn't add any new ways of writing, it just buffers every call +//! `BufWriter` doesn't add any new ways of writing; it just buffers every call //! to [`write()`][write]: //! //! ``` @@ -165,7 +165,7 @@ //! # } //! ``` //! -//! Of course, using `io::stdout()` directly is less comon than something like +//! Of course, using `io::stdout()` directly is less common than something like //! `println!`. //! //! ## Iterator types diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make/linker-output-non-utf8/Makefile new file mode 100644 index 0000000000000..b26940cb1b483 --- /dev/null +++ b/src/test/run-make/linker-output-non-utf8/Makefile @@ -0,0 +1,12 @@ +-include ../tools.mk + +# Make sure we don't ICE if the linker prints a non-UTF-8 error message. + +# The zzz it to allow humans to tab complete or glob this thing. +bad_dir := $(TMPDIR)/zzz$$'\xff' + +all: + $(RUSTC) library.rs + mkdir $(bad_dir) + mv $(call DYLIB,library) $(bad_dir) + LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | grep this_symbol_not_defined diff --git a/src/test/run-make/linker-output-non-utf8/exec.rs b/src/test/run-make/linker-output-non-utf8/exec.rs new file mode 100644 index 0000000000000..6864018d64e97 --- /dev/null +++ b/src/test/run-make/linker-output-non-utf8/exec.rs @@ -0,0 +1,6 @@ +#[link(name="library")] +extern "C" { + fn foo(); +} + +fn main() { unsafe { foo(); } } diff --git a/src/test/run-make/linker-output-non-utf8/library.rs b/src/test/run-make/linker-output-non-utf8/library.rs new file mode 100644 index 0000000000000..1a5138c3c20d6 --- /dev/null +++ b/src/test/run-make/linker-output-non-utf8/library.rs @@ -0,0 +1,9 @@ +#![crate_type = "dylib"] + +extern "C" { + fn this_symbol_not_defined(); +} + +pub extern "C" fn foo() { + unsafe { this_symbol_not_defined(); } +}