Skip to content

add docs for references as a primitive #43560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,7 @@ pub enum PrimitiveType {
Array,
Tuple,
RawPointer,
Reference,
}

#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -1633,6 +1635,7 @@ impl PrimitiveType {
"slice" => Some(PrimitiveType::Slice),
"tuple" => Some(PrimitiveType::Tuple),
"pointer" => Some(PrimitiveType::RawPointer),
"reference" => Some(PrimitiveType::Reference),
_ => None,
}
}
Expand Down Expand Up @@ -1661,6 +1664,7 @@ impl PrimitiveType {
Slice => "slice",
Tuple => "tuple",
RawPointer => "pointer",
Reference => "reference",
}
}

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
};
Expand Down
36 changes: 17 additions & 19 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,50 +665,48 @@ 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, "]")
}
}
}
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)
}
}
}
Expand Down
117 changes: 117 additions & 0 deletions src/libstd/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { }