diff options
| author | bors <bors@rust-lang.org> | 2017-08-01 08:23:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-08-01 08:23:41 +0000 |
| commit | 0bf018c58815eed79a279ee6fa98992b8a3639ef (patch) | |
| tree | 856cffd54365d1a3aed113f76679dc6f38de7969 /src | |
| parent | 6e8452ee4f66ef8b3b1f7a33d873e102bf8603d0 (diff) | |
| parent | a2d55146938972d7eecc19f9315f86d7ecb8f94b (diff) | |
| download | rust-0bf018c58815eed79a279ee6fa98992b8a3639ef.tar.gz rust-0bf018c58815eed79a279ee6fa98992b8a3639ef.zip | |
Auto merge of #43560 - QuietMisdreavus:ref-docs, r=steveklabnik
add docs for references as a primitive Just like #43529 did for function pointers, here is a new primitive page for references. This PR will pull in impls on references if it's a reference to a generic type parameter. Initially i was only able to pull in impls that were re-exported from another crate; crate-local impls got a different representation in the AST, and i had to change how types were resolved when cleaning it. (This is the change at the bottom of `librustdoc/clean/mod.rs`, in `resolve_type`.) I'm unsure the full ramifications of the change, but from what it looks like, it shouldn't impact anything major. Likewise, references to generic type parameters also get the `&'a [mut]` linked to the new page. cc @rust-lang/docs: Is this sufficient information? The listing of trait impls kinda feels redundant (especially if we can get the automated impl listing sorted again), but i still think it's useful to point out that you can use these in a generic context. Fixes #15654
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustdoc/html/format.rs | 36 | ||||
| -rw-r--r-- | src/libstd/primitive_docs.rs | 117 |
3 files changed, 142 insertions, 19 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9d0b5b41a91..39258dd3a24 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1547,6 +1547,7 @@ pub enum PrimitiveType { Array, Tuple, RawPointer, + Reference, } #[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)] @@ -1581,6 +1582,7 @@ impl Type { Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array), Tuple(..) => Some(PrimitiveType::Tuple), RawPointer(..) => Some(PrimitiveType::RawPointer), + BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference), _ => None, } } @@ -1633,6 +1635,7 @@ impl PrimitiveType { "slice" => Some(PrimitiveType::Slice), "tuple" => Some(PrimitiveType::Tuple), "pointer" => Some(PrimitiveType::RawPointer), + "reference" => Some(PrimitiveType::Reference), _ => None, } } @@ -1661,6 +1664,7 @@ impl PrimitiveType { Slice => "slice", Tuple => "tuple", RawPointer => "pointer", + Reference => "reference", } } @@ -2556,6 +2560,7 @@ fn build_deref_target_impls(cx: &DocContext, Array => tcx.lang_items.slice_impl(), Tuple => None, RawPointer => tcx.lang_items.const_ptr_impl(), + Reference => None, }; if let Some(did) = did { if !did.is_local() { @@ -2777,6 +2782,9 @@ fn resolve_type(cx: &DocContext, Def::SelfTy(..) if path.segments.len() == 1 => { return Generic(keywords::SelfType.name().to_string()); } + Def::TyParam(..) if path.segments.len() == 1 => { + return Generic(format!("{:#}", path)); + } Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true, _ => false, }; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 766e76137ca..33ab5cf47de 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -665,26 +665,29 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: _ => "".to_string(), }; let m = MutableSpace(mutability); + let amp = if f.alternate() { + "&".to_string() + } else { + "&".to_string() + }; match **ty { clean::Slice(ref bt) => { // BorrowedRef{ ... Slice(T) } is &[T] match **bt { clean::Generic(_) => { if f.alternate() { primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[{:#}]", lt, m, **bt)) + &format!("{}{}{}[{:#}]", amp, lt, m, **bt)) } else { primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[{}]", lt, m, **bt)) + &format!("{}{}{}[{}]", amp, lt, m, **bt)) } } _ => { + primitive_link(f, PrimitiveType::Slice, + &format!("{}{}{}[", amp, lt, m))?; if f.alternate() { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[", lt, m))?; write!(f, "{:#}", **bt)?; } else { - primitive_link(f, PrimitiveType::Slice, - &format!("&{}{}[", lt, m))?; write!(f, "{}", **bt)?; } primitive_link(f, PrimitiveType::Slice, "]") @@ -692,23 +695,18 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: } } clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => { - if f.alternate() { - write!(f, "&{}{}", lt, m)?; - } else { - write!(f, "&{}{}", lt, m)?; - } - write!(f, "(")?; + write!(f, "{}{}{}(", amp, lt, m)?; fmt_type(&ty, f, use_absolute)?; write!(f, ")") } + clean::Generic(..) => { + primitive_link(f, PrimitiveType::Reference, + &format!("{}{}{}", amp, lt, m))?; + fmt_type(&ty, f, use_absolute) + } _ => { - if f.alternate() { - write!(f, "&{}{}", lt, m)?; - fmt_type(&ty, f, use_absolute) - } else { - write!(f, "&{}{}", lt, m)?; - fmt_type(&ty, f, use_absolute) - } + write!(f, "{}{}{}", amp, lt, m)?; + fmt_type(&ty, f, use_absolute) } } } diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 869299e2144..84dba274a2e 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -722,3 +722,120 @@ mod prim_isize { } /// #[stable(feature = "rust1", since = "1.0.0")] mod prim_usize { } + +#[doc(primitive = "reference")] +// +/// References, both shared and mutable. +/// +/// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` +/// operators on a value, or by using a `ref` or `ref mut` pattern. +/// +/// For those familiar with pointers, a reference is just a pointer that is assumed to not be null. +/// In fact, `Option<&T>` has the same memory representation as a nullable pointer, and can be +/// passed across FFI boundaries as such. +/// +/// In most cases, references can be used much like the original value. Field access, method +/// calling, and indexing work the same (save for mutability rules, of course). In addition, the +/// comparison operators transparently defer to the referent's implementation, allowing references +/// to be compared the same as owned values. +/// +/// References have a lifetime attached to them, which represents the scope for which the borrow is +/// valid. A lifetime is said to "outlive" another one if its representative scope is as long or +/// longer than the other. The `'static` lifetime is the longest lifetime, which represents the +/// total life of the program. For example, string literals have a `'static` lifetime because the +/// text data is embedded into the binary of the program, rather than in an allocation that needs +/// to be dynamically managed. +/// +/// `&mut T` references can be freely coerced into `&T` references with the same referent type, and +/// references with longer lifetimes can be freely coerced into references with shorter ones. +/// +/// For more information on how to use references, see [the book's section on "References and +/// Borrowing"][book-refs]. +/// +/// [book-refs]: ../book/second-edition/ch04-02-references-and-borrowing.html +/// +/// The following traits are implemented for all `&T`, regardless of the type of its referent: +/// +/// * [`Copy`] +/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!) +/// * [`Deref`] +/// * [`Borrow`] +/// * [`Pointer`] +/// +/// [`Copy`]: marker/trait.Copy.html +/// [`Clone`]: clone/trait.Clone.html +/// [`Deref`]: ops/trait.Deref.html +/// [`Borrow`]: borrow/trait.Borrow.html +/// [`Pointer`]: fmt/trait.Pointer.html +/// +/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating +/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its +/// referent: +/// +/// * [`DerefMut`] +/// * [`BorrowMut`] +/// +/// [`DerefMut`]: ops/trait.DerefMut.html +/// [`BorrowMut`]: borrow/trait.BorrowMut.html +/// +/// The following traits are implemented on `&T` references if the underlying `T` also implements +/// that trait: +/// +/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`] +/// * [`PartialOrd`] +/// * [`Ord`] +/// * [`PartialEq`] +/// * [`Eq`] +/// * [`AsRef`] +/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`) +/// * [`Hash`] +/// * [`ToSocketAddrs`] +/// +/// [`std::fmt`]: fmt/index.html +/// [`fmt::Write`]: fmt/trait.Write.html +/// [`PartialOrd`]: cmp/trait.PartialOrd.html +/// [`Ord`]: cmp/trait.Ord.html +/// [`PartialEq`]: cmp/trait.PartialEq.html +/// [`Eq`]: cmp/trait.Eq.html +/// [`AsRef`]: convert/trait.AsRef.html +/// [`Fn`]: ops/trait.Fn.html +/// [`FnMut`]: ops/trait.FnMut.html +/// [`FnOnce`]: ops/trait.FnOnce.html +/// [`Hash`]: hash/trait.Hash.html +/// [`ToSocketAddrs`]: net/trait.ToSocketAddrs.html +/// +/// `&mut T` references get all of the above except `ToSocketAddrs`, plus the following, if `T` +/// implements that trait: +/// +/// * [`AsMut`] +/// * [`FnMut`] \(in addition, `&mut T` references get [`FnOnce`] if `T: FnMut`) +/// * [`fmt::Write`] +/// * [`Iterator`] +/// * [`DoubleEndedIterator`] +/// * [`ExactSizeIterator`] +/// * [`FusedIterator`] +/// * [`TrustedLen`] +/// * [`Send`] \(note that `&T` references only get `Send` if `T: Sync`) +/// * [`io::Write`] +/// * [`Read`] +/// * [`Seek`] +/// * [`BufRead`] +/// +/// [`AsMut`]: convert/trait.AsMut.html +/// [`Iterator`]: iter/trait.Iterator.html +/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html +/// [`ExactSizeIterator`]: iter/trait.ExactSizeIterator.html +/// [`FusedIterator`]: iter/trait.FusedIterator.html +/// [`TrustedLen`]: iter/trait.TrustedLen.html +/// [`Send`]: marker/trait.Send.html +/// [`io::Write`]: io/trait.Write.html +/// [`Read`]: io/trait.Read.html +/// [`Seek`]: io/trait.Seek.html +/// [`BufRead`]: io/trait.BufRead.html +/// +/// Note that due to method call deref coercion, simply calling a trait method will act like they +/// work on references as well as they do on owned values! The implementations described here are +/// meant for generic contexts, where the final type `T` is a type parameter or otherwise not +/// locally known. +#[stable(feature = "rust1", since = "1.0.0")] +mod prim_ref { } |
