Auto merge of #43529 - QuietMisdreavus:fn-docs, r=steveklabnik
add documentation for function pointers as a primitive This PR adds a new kind of primitive to the standard library documentation: Function pointers. It's useful to be able to discuss them separately from closure-trait-objects, and to have something to point to when discussing function pointers as a *type* and not a *trait*. Fixes #17104
This commit is contained in:
commit
dd53dd5f9e
@ -1548,6 +1548,7 @@ pub enum PrimitiveType {
|
|||||||
Tuple,
|
Tuple,
|
||||||
RawPointer,
|
RawPointer,
|
||||||
Reference,
|
Reference,
|
||||||
|
Fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
|
||||||
@ -1583,6 +1584,7 @@ pub fn primitive_type(&self) -> Option<PrimitiveType> {
|
|||||||
Tuple(..) => Some(PrimitiveType::Tuple),
|
Tuple(..) => Some(PrimitiveType::Tuple),
|
||||||
RawPointer(..) => Some(PrimitiveType::RawPointer),
|
RawPointer(..) => Some(PrimitiveType::RawPointer),
|
||||||
BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
|
BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
|
||||||
|
BareFunction(..) => Some(PrimitiveType::Fn),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1636,6 +1638,7 @@ fn from_str(s: &str) -> Option<PrimitiveType> {
|
|||||||
"tuple" => Some(PrimitiveType::Tuple),
|
"tuple" => Some(PrimitiveType::Tuple),
|
||||||
"pointer" => Some(PrimitiveType::RawPointer),
|
"pointer" => Some(PrimitiveType::RawPointer),
|
||||||
"reference" => Some(PrimitiveType::Reference),
|
"reference" => Some(PrimitiveType::Reference),
|
||||||
|
"fn" => Some(PrimitiveType::Fn),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1665,6 +1668,7 @@ pub fn as_str(&self) -> &'static str {
|
|||||||
Tuple => "tuple",
|
Tuple => "tuple",
|
||||||
RawPointer => "pointer",
|
RawPointer => "pointer",
|
||||||
Reference => "reference",
|
Reference => "reference",
|
||||||
|
Fn => "fn",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2561,6 +2565,7 @@ fn build_deref_target_impls(cx: &DocContext,
|
|||||||
Tuple => None,
|
Tuple => None,
|
||||||
RawPointer => tcx.lang_items.const_ptr_impl(),
|
RawPointer => tcx.lang_items.const_ptr_impl(),
|
||||||
Reference => None,
|
Reference => None,
|
||||||
|
Fn => None,
|
||||||
};
|
};
|
||||||
if let Some(did) = did {
|
if let Some(did) = did {
|
||||||
if !did.is_local() {
|
if !did.is_local() {
|
||||||
|
@ -607,11 +607,9 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
|
|||||||
decl.generics,
|
decl.generics,
|
||||||
decl.decl)
|
decl.decl)
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}{}fn{}{}",
|
write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
|
||||||
UnsafetySpace(decl.unsafety),
|
primitive_link(f, PrimitiveType::Fn, "fn")?;
|
||||||
AbiSpace(decl.abi),
|
write!(f, "{}{}", decl.generics, decl.decl)
|
||||||
decl.generics,
|
|
||||||
decl.decl)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean::Tuple(ref typs) => {
|
clean::Tuple(ref typs) => {
|
||||||
|
@ -839,3 +839,104 @@ mod prim_usize { }
|
|||||||
/// locally known.
|
/// locally known.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
mod prim_ref { }
|
mod prim_ref { }
|
||||||
|
|
||||||
|
#[doc(primitive = "fn")]
|
||||||
|
//
|
||||||
|
/// Function pointers, like `fn(usize) -> bool`.
|
||||||
|
///
|
||||||
|
/// *See also the traits [`Fn`], [`FnMut`], and [`FnOnce`].*
|
||||||
|
///
|
||||||
|
/// [`Fn`]: ops/trait.Fn.html
|
||||||
|
/// [`FnMut`]: ops/trait.FnMut.html
|
||||||
|
/// [`FnOnce`]: ops/trait.FnOnce.html
|
||||||
|
///
|
||||||
|
/// Plain function pointers are obtained by casting either plain functions, or closures that don't
|
||||||
|
/// capture an environment:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn add_one(x: usize) -> usize {
|
||||||
|
/// x + 1
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let ptr: fn(usize) -> usize = add_one;
|
||||||
|
/// assert_eq!(ptr(5), 6);
|
||||||
|
///
|
||||||
|
/// let clos: fn(usize) -> usize = |x| x + 5;
|
||||||
|
/// assert_eq!(clos(5), 10);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// In addition to varying based on their signature, function pointers come in two flavors: safe
|
||||||
|
/// and unsafe. Plain `fn()` function pointers can only point to safe functions,
|
||||||
|
/// while `unsafe fn()` function pointers can point to safe or unsafe functions.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn add_one(x: usize) -> usize {
|
||||||
|
/// x + 1
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// unsafe fn add_one_unsafely(x: usize) -> usize {
|
||||||
|
/// x + 1
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let safe_ptr: fn(usize) -> usize = add_one;
|
||||||
|
///
|
||||||
|
/// //ERROR: mismatched types: expected normal fn, found unsafe fn
|
||||||
|
/// //let bad_ptr: fn(usize) -> usize = add_one_unsafely;
|
||||||
|
///
|
||||||
|
/// let unsafe_ptr: unsafe fn(usize) -> usize = add_one_unsafely;
|
||||||
|
/// let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// On top of that, function pointers can vary based on what ABI they use. This is achieved by
|
||||||
|
/// adding the `extern` keyword to the type name, followed by the ABI in question. For example,
|
||||||
|
/// `fn()` is different from `extern "C" fn()`, which itself is different from `extern "stdcall"
|
||||||
|
/// fn()`, and so on for the various ABIs that Rust supports. Non-`extern` functions have an ABI
|
||||||
|
/// of `"Rust"`, and `extern` functions without an explicit ABI have an ABI of `"C"`. For more
|
||||||
|
/// information, see [the nomicon's section on foreign calling conventions][nomicon-abi].
|
||||||
|
///
|
||||||
|
/// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions
|
||||||
|
///
|
||||||
|
/// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them
|
||||||
|
/// to be called with a variable number of arguments. Normal rust functions, even those with an
|
||||||
|
/// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on
|
||||||
|
/// variadic functions][nomicon-variadic].
|
||||||
|
///
|
||||||
|
/// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions
|
||||||
|
///
|
||||||
|
/// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type.
|
||||||
|
///
|
||||||
|
/// Like references in rust, function pointers are assumed to not be null, so if you want to pass a
|
||||||
|
/// function pointer over FFI and be able to accomodate null pointers, make your type
|
||||||
|
/// `Option<fn()>` with your required signature.
|
||||||
|
///
|
||||||
|
/// Function pointers implement the following traits:
|
||||||
|
///
|
||||||
|
/// * [`Clone`]
|
||||||
|
/// * [`PartialEq`]
|
||||||
|
/// * [`Eq`]
|
||||||
|
/// * [`PartialOrd`]
|
||||||
|
/// * [`Ord`]
|
||||||
|
/// * [`Hash`]
|
||||||
|
/// * [`Pointer`]
|
||||||
|
/// * [`Debug`]
|
||||||
|
///
|
||||||
|
/// [`Clone`]: clone/trait.Clone.html
|
||||||
|
/// [`PartialEq`]: cmp/trait.PartialEq.html
|
||||||
|
/// [`Eq`]: cmp/trait.Eq.html
|
||||||
|
/// [`PartialOrd`]: cmp/trait.PartialOrd.html
|
||||||
|
/// [`Ord`]: cmp/trait.Ord.html
|
||||||
|
/// [`Hash`]: hash/trait.Hash.html
|
||||||
|
/// [`Pointer`]: fmt/trait.Pointer.html
|
||||||
|
/// [`Debug`]: fmt/trait.Debug.html
|
||||||
|
///
|
||||||
|
/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
|
||||||
|
/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
|
||||||
|
/// may change.
|
||||||
|
///
|
||||||
|
/// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe*
|
||||||
|
/// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits
|
||||||
|
/// are specially known to the compiler.
|
||||||
|
///
|
||||||
|
/// [`Copy`]: marker/trait.Copy.html
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
mod prim_fn { }
|
||||||
|
Loading…
Reference in New Issue
Block a user