diff --git a/src/doc/book/ffi.md b/src/doc/book/ffi.md index 7510cd0b3b5..b53af694428 100644 --- a/src/doc/book/ffi.md +++ b/src/doc/book/ffi.md @@ -662,26 +662,31 @@ attribute turns off Rust's name mangling, so that it is easier to link to. It’s important to be mindful of `panic!`s when working with FFI. A `panic!` across an FFI boundary is undefined behavior. If you’re writing code that may -panic, you should run it in another thread, so that the panic doesn’t bubble up -to C: +panic, you should run it in a closure with [`catch_unwind()`]: ```rust -use std::thread; +use std::panic::catch_unwind; #[no_mangle] pub extern fn oh_no() -> i32 { - let h = thread::spawn(|| { + let result = catch_unwind(|| { panic!("Oops!"); }); - - match h.join() { - Ok(_) => 1, - Err(_) => 0, + match result { + Ok(_) => 0, + Err(_) => 1, } } -# fn main() {} + +fn main() {} ``` +Please note that [`catch_unwind()`] will only catch unwinding panics, not +those who abort the process. See the documentation of [`catch_unwind()`] +for more information. + +[`catch_unwind()`]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html + # Representing opaque structs Sometimes, a C library wants to provide a pointer to something, but not let you diff --git a/src/doc/reference.md b/src/doc/reference.md index 12d29f2a3a7..bf286aaec4b 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -603,7 +603,8 @@ syntax named by _designator_. Valid designators are: * `ty`: a [type](#types) * `ident`: an [identifier](#identifiers) * `path`: a [path](#paths) -* `tt`: either side of the `=>` in macro rules +* `tt`: a token tree (a single [token](#tokens) or a sequence of token trees surrounded + by matching `()`, `[]`, or `{}`) * `meta`: the contents of an [attribute](#attributes) In the transcriber, the diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8d863d7d9e9..d1e0e333b8f 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -12,35 +12,35 @@ //! Single-threaded reference-counting pointers. //! -//! The type [`Rc`][rc] provides shared ownership of a value of type `T`, -//! allocated in the heap. Invoking [`clone`][clone] on `Rc` produces a new -//! pointer to the same value in the heap. When the last `Rc` pointer to a +//! The type [`Rc`][`Rc`] provides shared ownership of a value of type `T`, +//! allocated in the heap. Invoking [`clone()`][clone] on [`Rc`] produces a new +//! pointer to the same value in the heap. When the last [`Rc`] pointer to a //! given value is destroyed, the pointed-to value is also destroyed. //! //! Shared references in Rust disallow mutation by default, and `Rc` is no -//! exception. If you need to mutate through an `Rc`, use [`Cell`][cell] or -//! [`RefCell`][refcell]. +//! exception. If you need to mutate through an [`Rc`], use [`Cell`] or +//! [`RefCell`]. //! -//! `Rc` uses non-atomic reference counting. This means that overhead is very -//! low, but an `Rc` cannot be sent between threads, and consequently `Rc` +//! [`Rc`] uses non-atomic reference counting. This means that overhead is very +//! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`] //! does not implement [`Send`][send]. As a result, the Rust compiler -//! will check *at compile time* that you are not sending `Rc`s between +//! will check *at compile time* that you are not sending [`Rc`]s between //! threads. If you need multi-threaded, atomic reference counting, use //! [`sync::Arc`][arc]. //! -//! The [`downgrade`][downgrade] method can be used to create a non-owning -//! [`Weak`][weak] pointer. A `Weak` pointer can be [`upgrade`][upgrade]d -//! to an `Rc`, but this will return [`None`][option] if the value has +//! The [`downgrade()`][downgrade] method can be used to create a non-owning +//! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d +//! to an [`Rc`], but this will return [`None`] if the value has //! already been dropped. //! -//! A cycle between `Rc` pointers will never be deallocated. For this reason, -//! `Weak` is used to break cycles. For example, a tree could have strong -//! `Rc` pointers from parent nodes to children, and `Weak` pointers from +//! A cycle between [`Rc`] pointers will never be deallocated. For this reason, +//! [`Weak`] is used to break cycles. For example, a tree could have strong +//! [`Rc`] pointers from parent nodes to children, and [`Weak`] pointers from //! children back to their parents. //! -//! `Rc` automatically dereferences to `T` (via the [`Deref`][deref] trait), -//! so you can call `T`'s methods on a value of type `Rc`. To avoid name -//! clashes with `T`'s methods, the methods of `Rc` itself are [associated +//! `Rc` automatically dereferences to `T` (via the [`Deref`] trait), +//! so you can call `T`'s methods on a value of type [`Rc`][`Rc`]. To avoid name +//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are [associated //! functions][assoc], called using function-like syntax: //! //! ``` @@ -50,28 +50,15 @@ //! Rc::downgrade(&my_rc); //! ``` //! -//! `Weak` does not auto-dereference to `T`, because the value may have +//! [`Weak`][`Weak`] does not auto-dereference to `T`, because the value may have //! already been destroyed. //! -//! [rc]: struct.Rc.html -//! [weak]: struct.Weak.html -//! [clone]: ../../std/clone/trait.Clone.html#tymethod.clone -//! [cell]: ../../std/cell/struct.Cell.html -//! [refcell]: ../../std/cell/struct.RefCell.html -//! [send]: ../../std/marker/trait.Send.html -//! [arc]: ../../std/sync/struct.Arc.html -//! [deref]: ../../std/ops/trait.Deref.html -//! [downgrade]: struct.Rc.html#method.downgrade -//! [upgrade]: struct.Weak.html#method.upgrade -//! [option]: ../../std/option/enum.Option.html -//! [assoc]: ../../book/method-syntax.html#associated-functions -//! //! # Examples //! //! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. //! We want to have our `Gadget`s point to their `Owner`. We can't do this with //! unique ownership, because more than one gadget may belong to the same -//! `Owner`. `Rc` allows us to share an `Owner` between multiple `Gadget`s, +//! `Owner`. [`Rc`] allows us to share an `Owner` between multiple `Gadget`s, //! and have the `Owner` remain allocated as long as any `Gadget` points at it. //! //! ``` @@ -127,20 +114,20 @@ //! ``` //! //! If our requirements change, and we also need to be able to traverse from -//! `Owner` to `Gadget`, we will run into problems. An `Rc` pointer from `Owner` +//! `Owner` to `Gadget`, we will run into problems. An [`Rc`] pointer from `Owner` //! to `Gadget` introduces a cycle between the values. This means that their //! reference counts can never reach 0, and the values will remain allocated -//! forever: a memory leak. In order to get around this, we can use `Weak` +//! forever: a memory leak. In order to get around this, we can use [`Weak`] //! pointers. //! //! Rust actually makes it somewhat difficult to produce this loop in the first //! place. In order to end up with two values that point at each other, one of -//! them needs to be mutable. This is difficult because `Rc` enforces +//! them needs to be mutable. This is difficult because [`Rc`] enforces //! memory safety by only giving out shared references to the value it wraps, //! and these don't allow direct mutation. We need to wrap the part of the -//! value we wish to mutate in a [`RefCell`][refcell], which provides *interior +//! value we wish to mutate in a [`RefCell`], which provides *interior //! mutability*: a method to achieve mutability through a shared reference. -//! `RefCell` enforces Rust's borrowing rules at runtime. +//! [`RefCell`] enforces Rust's borrowing rules at runtime. //! //! ``` //! use std::rc::Rc; @@ -214,6 +201,19 @@ //! // Gadget Man, so he gets destroyed as well. //! } //! ``` +//! +//! [`Rc`]: struct.Rc.html +//! [`Weak`]: struct.Weak.html +//! [clone]: ../../std/clone/trait.Clone.html#tymethod.clone +//! [`Cell`]: ../../std/cell/struct.Cell.html +//! [`RefCell`]: ../../std/cell/struct.RefCell.html +//! [send]: ../../std/marker/trait.Send.html +//! [arc]: ../../std/sync/struct.Arc.html +//! [`Deref`]: ../../std/ops/trait.Deref.html +//! [downgrade]: struct.Rc.html#method.downgrade +//! [upgrade]: struct.Weak.html#method.upgrade +//! [`None`]: ../../std/option/enum.Option.html#variant.None +//! [assoc]: ../../book/method-syntax.html#associated-functions #![stable(feature = "rust1", since = "1.0.0")] @@ -251,9 +251,11 @@ struct RcBox { /// See the [module-level documentation](./index.html) for more details. /// /// The inherent methods of `Rc` are all associated functions, which means -/// that you have to call them as e.g. `Rc::get_mut(&value)` instead of -/// `value.get_mut()`. This avoids conflicts with methods of the inner +/// that you have to call them as e.g. [`Rc::get_mut(&value)`][get_mut] instead of +/// `value.get_mut()`. This avoids conflicts with methods of the inner /// type `T`. +/// +/// [get_mut]: #method.get_mut #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc { ptr: Shared>, @@ -337,10 +339,10 @@ impl Rc { } /// Checks whether [`Rc::try_unwrap`][try_unwrap] would return - /// [`Ok`][result]. + /// [`Ok`]. /// /// [try_unwrap]: struct.Rc.html#method.try_unwrap - /// [result]: ../../std/result/enum.Result.html + /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok /// /// # Examples /// @@ -543,14 +545,14 @@ impl Rc { /// Returns a mutable reference to the inner value, if there are /// no other `Rc` or [`Weak`][weak] pointers to the same value. /// - /// Returns [`None`][option] otherwise, because it is not safe to + /// Returns [`None`] otherwise, because it is not safe to /// mutate a shared value. /// /// See also [`make_mut`][make_mut], which will [`clone`][clone] /// the inner value when it's shared. /// /// [weak]: struct.Weak.html - /// [option]: ../../std/option/enum.Option.html + /// [`None`]: ../../std/option/enum.Option.html#variant.None /// [make_mut]: struct.Rc.html#method.make_mut /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 492c5e695bb..5db622a4e7d 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -103,6 +103,12 @@ impl<'a, 'b> Visitor for UnusedImportCheckVisitor<'a, 'b> { } ViewPathList(_, ref list) => { + if list.len() == 0 { + self.unused_imports + .entry(item.id) + .or_insert_with(NodeMap) + .insert(item.id, item.span); + } for i in list { self.check_import(item.id, i.node.id, i.span); } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 368604ccb82..0b310eb2585 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2117,6 +2117,10 @@ impl DefaultHasher { #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] impl Default for DefaultHasher { + /// Creates a new `DefaultHasher` using [`DefaultHasher::new`]. See + /// [`DefaultHasher::new`] documentation for more information. + /// + /// [`DefaultHasher::new`]: #method.new fn default() -> DefaultHasher { DefaultHasher::new() } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 04050a5edc4..45a10d24528 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -159,6 +159,23 @@ pub fn take_hook() -> Box { } /// A struct providing information about a panic. +/// +/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook()`] +/// function. +/// +/// [`set_hook()`]: ../../std/panic/fn.set_hook.html +/// +/// # Examples +/// +/// ```should_panic +/// use std::panic; +/// +/// panic::set_hook(Box::new(|panic_info| { +/// println!("panic occured: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); +/// })); +/// +/// panic!("Normal panic"); +/// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub struct PanicInfo<'a> { payload: &'a (Any + Send), @@ -168,7 +185,21 @@ pub struct PanicInfo<'a> { impl<'a> PanicInfo<'a> { /// Returns the payload associated with the panic. /// - /// This will commonly, but not always, be a `&'static str` or `String`. + /// This will commonly, but not always, be a `&'static str` or [`String`]. + /// + /// [`String`]: ../../std/string/struct.String.html + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// println!("panic occured: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); + /// })); + /// + /// panic!("Normal panic"); + /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn payload(&self) -> &(Any + Send) { self.payload @@ -177,8 +208,26 @@ impl<'a> PanicInfo<'a> { /// Returns information about the location from which the panic originated, /// if available. /// - /// This method will currently always return `Some`, but this may change + /// This method will currently always return [`Some`], but this may change /// in future versions. + /// + /// [`Some`]: ../../std/option/enum.Option.html#variant.Some + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occured in file '{}' at line {}", location.file(), location.line()); + /// } else { + /// println!("panic occured but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn location(&self) -> Option<&Location> { Some(&self.location) @@ -186,6 +235,27 @@ impl<'a> PanicInfo<'a> { } /// A struct containing information about the location of a panic. +/// +/// This structure is created by the [`location()`] method of [`PanicInfo`]. +/// +/// [`location()`]: ../../std/panic/struct.PanicInfo.html#method.location +/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html +/// +/// # Examples +/// +/// ```should_panic +/// use std::panic; +/// +/// panic::set_hook(Box::new(|panic_info| { +/// if let Some(location) = panic_info.location() { +/// println!("panic occured in file '{}' at line {}", location.file(), location.line()); +/// } else { +/// println!("panic occured but can't get location information..."); +/// } +/// })); +/// +/// panic!("Normal panic"); +/// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub struct Location<'a> { file: &'a str, @@ -194,12 +264,44 @@ pub struct Location<'a> { impl<'a> Location<'a> { /// Returns the name of the source file from which the panic originated. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occured in file '{}'", location.file()); + /// } else { + /// println!("panic occured but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn file(&self) -> &str { self.file } /// Returns the line number from which the panic originated. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occured at line {}", location.line()); + /// } else { + /// println!("panic occured but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn line(&self) -> u32 { self.line diff --git a/src/libstd/process.rs b/src/libstd/process.rs index bfc36d5b21f..858537dd2de 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -827,6 +827,14 @@ impl Child { /// will be run. If a clean shutdown is needed it is recommended to only call /// this function at a known point where there are no more destructors left /// to run. +/// +/// # Examples +/// +/// ``` +/// use std::process; +/// +/// process::exit(0); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn exit(code: i32) -> ! { ::sys_common::cleanup(); diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs index 4163ede46af..296235e173d 100644 --- a/src/libstd/sys/unix/ext/io.rs +++ b/src/libstd/sys/unix/ext/io.rs @@ -43,7 +43,7 @@ pub trait AsRawFd { /// descriptor. #[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawFd { - /// Constructs a new instances of `Self` from the given raw file + /// Constructs a new instance of `Self` from the given raw file /// descriptor. /// /// This function **consumes ownership** of the specified file diff --git a/src/test/compile-fail/issue-28388-1.rs b/src/test/compile-fail/issue-28388-1.rs index bee05cd5313..ed7851ec0f1 100644 --- a/src/test/compile-fail/issue-28388-1.rs +++ b/src/test/compile-fail/issue-28388-1.rs @@ -10,6 +10,8 @@ // Prefix in imports with empty braces should be resolved and checked privacy, stability, etc. -use foo::{}; //~ ERROR failed to resolve. Maybe a missing `extern crate foo;`? +use foo::{}; +//~^ ERROR failed to resolve. Maybe a missing `extern crate foo;`? +//~| NOTE foo fn main() {} diff --git a/src/test/compile-fail/issue-28388-2.rs b/src/test/compile-fail/issue-28388-2.rs index 837dc67c804..4ed5bfab06f 100644 --- a/src/test/compile-fail/issue-28388-2.rs +++ b/src/test/compile-fail/issue-28388-2.rs @@ -14,6 +14,7 @@ mod m { mod n {} } -use m::n::{}; //~ ERROR module `n` is private +use m::n::{}; +//~^ ERROR module `n` is private fn main() {} diff --git a/src/test/compile-fail/issue-28388-3.rs b/src/test/compile-fail/issue-28388-3.rs index 0cb669f5f8f..4baaa16e772 100644 --- a/src/test/compile-fail/issue-28388-3.rs +++ b/src/test/compile-fail/issue-28388-3.rs @@ -14,7 +14,8 @@ extern crate lint_stability; -use lint_stability::UnstableStruct::{}; //~ ERROR use of unstable library feature 'test_feature' +use lint_stability::UnstableStruct::{}; +//~^ ERROR use of unstable library feature 'test_feature' use lint_stability::StableStruct::{}; // OK fn main() {} diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index 5b1c04946a4..f6f7c210f46 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -15,6 +15,8 @@ use bar::c::cc as cal; use std::mem::*; // shouldn't get errors for not using // everything imported +use std::fmt::{}; +//~^ ERROR unused import: `use std::fmt::{};` // Should get errors for both 'Some' and 'None' use std::option::Option::{Some, None};