/** -> ///

This is considered good convention.
This commit is contained in:
Steve Klabnik 2014-11-24 20:06:06 -05:00
parent 689ef2dabf
commit f38e4e6d97
45 changed files with 1361 additions and 1658 deletions

View File

@ -42,27 +42,25 @@ impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
}
}
/**
An interface for casting C-like enum to uint and back.
A typically implementation is as below.
```{rust,ignore}
#[repr(uint)]
enum Foo {
A, B, C
}
impl CLike for Foo {
fn to_uint(&self) -> uint {
*self as uint
}
fn from_uint(v: uint) -> Foo {
unsafe { mem::transmute(v) }
}
}
```
*/
/// An interface for casting C-like enum to uint and back.
/// A typically implementation is as below.
///
/// ```{rust,ignore}
/// #[repr(uint)]
/// enum Foo {
/// A, B, C
/// }
///
/// impl CLike for Foo {
/// fn to_uint(&self) -> uint {
/// *self as uint
/// }
///
/// fn from_uint(v: uint) -> Foo {
/// unsafe { mem::transmute(v) }
/// }
/// }
/// ```
pub trait CLike {
/// Converts a C-like enum to a `uint`.
fn to_uint(&self) -> uint;

View File

@ -58,38 +58,36 @@ impl<T> Finally<T> for fn() -> T {
}
}
/**
* The most general form of the `finally` functions. The function
* `try_fn` will be invoked first; whether or not it panics, the
* function `finally_fn` will be invoked next. The two parameters
* `mutate` and `drop` are used to thread state through the two
* closures. `mutate` is used for any shared, mutable state that both
* closures require access to; `drop` is used for any state that the
* `try_fn` requires ownership of.
*
* **WARNING:** While shared, mutable state between the try and finally
* function is often necessary, one must be very careful; the `try`
* function could have panicked at any point, so the values of the shared
* state may be inconsistent.
*
* # Example
*
* ```
* use std::finally::try_finally;
*
* struct State<'a> { buffer: &'a mut [u8], len: uint }
* # let mut buf = [];
* let mut state = State { buffer: &mut buf, len: 0 };
* try_finally(
* &mut state, (),
* |state, ()| {
* // use state.buffer, state.len
* },
* |state| {
* // use state.buffer, state.len to cleanup
* })
* ```
*/
/// The most general form of the `finally` functions. The function
/// `try_fn` will be invoked first; whether or not it panics, the
/// function `finally_fn` will be invoked next. The two parameters
/// `mutate` and `drop` are used to thread state through the two
/// closures. `mutate` is used for any shared, mutable state that both
/// closures require access to; `drop` is used for any state that the
/// `try_fn` requires ownership of.
///
/// **WARNING:** While shared, mutable state between the try and finally
/// function is often necessary, one must be very careful; the `try`
/// function could have panicked at any point, so the values of the shared
/// state may be inconsistent.
///
/// # Example
///
/// ```
/// use std::finally::try_finally;
///
/// struct State<'a> { buffer: &'a mut [u8], len: uint }
/// # let mut buf = [];
/// let mut state = State { buffer: &mut buf, len: 0 };
/// try_finally(
/// &mut state, (),
/// |state, ()| {
/// // use state.buffer, state.len
/// },
/// |state| {
/// // use state.buffer, state.len to cleanup
/// })
/// ```
pub fn try_finally<T,U,R>(mutate: &mut T,
drop: U,
try_fn: |&mut T, U| -> R,

View File

@ -54,36 +54,36 @@ pub enum SignFormat {
static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
/**
* Converts a number to its string representation as a byte vector.
* This is meant to be a common base implementation for all numeric string
* conversion functions like `to_string()` or `to_str_radix()`.
*
* # Arguments
* - `num` - The number to convert. Accepts any number that
* implements the numeric traits.
* - `radix` - Base to use. Accepts only the values 2-36. If the exponential notation
* is used, then this base is only used for the significand. The exponent
* itself always printed using a base of 10.
* - `negative_zero` - Whether to treat the special value `-0` as
* `-0` or as `+0`.
* - `sign` - How to emit the sign. See `SignFormat`.
* - `digits` - The amount of digits to use for emitting the fractional
* part, if any. See `SignificantDigits`.
* - `exp_format` - Whether or not to use the exponential (scientific) notation.
* See `ExponentFormat`.
* - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if
* exponential notation is desired.
* - `f` - A closure to invoke with the bytes representing the
* float.
*
* # Panics
* - Panics if `radix` < 2 or `radix` > 36.
* - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
* between digit and exponent sign `'e'`.
* - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
* between digit and exponent sign `'p'`.
*/
/// Converts a number to its string representation as a byte vector.
/// This is meant to be a common base implementation for all numeric string
/// conversion functions like `to_string()` or `to_str_radix()`.
///
/// # Arguments
///
/// - `num` - The number to convert. Accepts any number that
/// implements the numeric traits.
/// - `radix` - Base to use. Accepts only the values 2-36. If the exponential notation
/// is used, then this base is only used for the significand. The exponent
/// itself always printed using a base of 10.
/// - `negative_zero` - Whether to treat the special value `-0` as
/// `-0` or as `+0`.
/// - `sign` - How to emit the sign. See `SignFormat`.
/// - `digits` - The amount of digits to use for emitting the fractional
/// part, if any. See `SignificantDigits`.
/// - `exp_format` - Whether or not to use the exponential (scientific) notation.
/// See `ExponentFormat`.
/// - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if
/// exponential notation is desired.
/// - `f` - A closure to invoke with the bytes representing the
/// float.
///
/// # Panics
///
/// - Panics if `radix` < 2 or `radix` > 36.
/// - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
/// between digit and exponent sign `'e'`.
/// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
/// between digit and exponent sign `'p'`.
pub fn float_to_str_bytes_common<T: Float, U>(
num: T,
radix: uint,

File diff suppressed because it is too large Load Diff

View File

@ -1634,9 +1634,7 @@ impl BinarySearchResult {
// Free functions
//
/**
* Converts a pointer to A into a slice of length 1 (without copying).
*/
/// Converts a pointer to A into a slice of length 1 (without copying).
#[unstable = "waiting for DST"]
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
unsafe {
@ -1644,9 +1642,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
}
}
/**
* Converts a pointer to A into a slice of length 1 (without copying).
*/
/// Converts a pointer to A into a slice of length 1 (without copying).
#[unstable = "waiting for DST"]
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
unsafe {
@ -1710,10 +1706,8 @@ pub mod raw {
use raw::Slice;
use option::{None, Option, Some};
/**
* Form a slice from a pointer and length (as a number of units,
* not bytes).
*/
/// Form a slice from a pointer and length (as a number of units,
/// not bytes).
#[inline]
#[deprecated = "renamed to slice::from_raw_buf"]
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
@ -1724,10 +1718,8 @@ pub mod raw {
}))
}
/**
* Form a slice from a pointer and length (as a number of units,
* not bytes).
*/
/// Form a slice from a pointer and length (as a number of units,
/// not bytes).
#[inline]
#[deprecated = "renamed to slice::from_raw_mut_buf"]
pub unsafe fn mut_buf_as_slice<T,
@ -1742,12 +1734,10 @@ pub mod raw {
}))
}
/**
* Returns a pointer to first element in slice and adjusts
* slice so it no longer contains that element. Returns None
* if the slice is empty. O(1).
*/
#[inline]
/// Returns a pointer to first element in slice and adjusts
/// slice so it no longer contains that element. Returns None
/// if the slice is empty. O(1).
#[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
if slice.len == 0 { return None; }
@ -1757,11 +1747,9 @@ pub mod raw {
Some(head)
}
/**
* Returns a pointer to last element in slice and adjusts
* slice so it no longer contains that element. Returns None
* if the slice is empty. O(1).
*/
/// Returns a pointer to last element in slice and adjusts
/// slice so it no longer contains that element. Returns None
/// if the slice is empty. O(1).
#[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {

View File

@ -329,20 +329,18 @@ pub mod types {
// Standard types that are opaque or common, so are not per-target.
pub mod common {
pub mod c95 {
/**
Type used to construct void pointers for use with C.
This type is only useful as a pointer target. Do not use it as a
return type for FFI functions which have the `void` return type in
C. Use the unit type `()` or omit the return type instead.
For LLVM to recognize the void pointer type and by extension
functions like malloc(), we need to have it represented as i8* in
LLVM bitcode. The enum used here ensures this and prevents misuse
of the "raw" type by only having private variants.. We need two
variants, because the compiler complains about the repr attribute
otherwise.
*/
/// Type used to construct void pointers for use with C.
///
/// This type is only useful as a pointer target. Do not use it as a
/// return type for FFI functions which have the `void` return type in
/// C. Use the unit type `()` or omit the return type instead.
///
/// For LLVM to recognize the void pointer type and by extension
/// functions like malloc(), we need to have it represented as i8* in
/// LLVM bitcode. The enum used here ensures this and prevents misuse
/// of the "raw" type by only having private variants.. We need two
/// variants, because the compiler complains about the repr attribute
/// otherwise.
#[repr(u8)]
pub enum c_void {
__variant1,

View File

@ -464,11 +464,9 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
self.lookup_and_emit(lint, Some(span), msg);
}
/**
* Merge the lints specified by any lint attributes into the
* current lint context, call the provided function, then reset the
* lints in effect to their previous state.
*/
/// Merge the lints specified by any lint attributes into the
/// current lint context, call the provided function, then reset the
/// lints in effect to their previous state.
fn with_lint_attrs(&mut self,
attrs: &[ast::Attribute],
f: |&mut Context|) {

View File

@ -13,7 +13,7 @@ use syntax::ast;
use self::SimplifiedType::*;
/** See `simplify_type */
/// See `simplify_type
#[deriving(Clone, PartialEq, Eq, Hash)]
pub enum SimplifiedType {
BoolSimplifiedType,

View File

@ -266,24 +266,22 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
pub type McResult<T> = Result<T, ()>;
/**
* The `Typer` trait provides the interface for the mem-categorization
* module to the results of the type check. It can be used to query
* the type assigned to an expression node, to inquire after adjustments,
* and so on.
*
* This interface is needed because mem-categorization is used from
* two places: `regionck` and `borrowck`. `regionck` executes before
* type inference is complete, and hence derives types and so on from
* intermediate tables. This also implies that type errors can occur,
* and hence `node_ty()` and friends return a `Result` type -- any
* error will propagate back up through the mem-categorization
* routines.
*
* In the borrow checker, in contrast, type checking is complete and we
* know that no errors have occurred, so we simply consult the tcx and we
* can be sure that only `Ok` results will occur.
*/
/// The `Typer` trait provides the interface for the mem-categorization
/// module to the results of the type check. It can be used to query
/// the type assigned to an expression node, to inquire after adjustments,
/// and so on.
///
/// This interface is needed because mem-categorization is used from
/// two places: `regionck` and `borrowck`. `regionck` executes before
/// type inference is complete, and hence derives types and so on from
/// intermediate tables. This also implies that type errors can occur,
/// and hence `node_ty()` and friends return a `Result` type -- any
/// error will propagate back up through the mem-categorization
/// routines.
///
/// In the borrow checker, in contrast, type checking is complete and we
/// know that no errors have occurred, so we simply consult the tcx and we
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;

View File

@ -72,46 +72,44 @@ impl CodeExtent {
}
}
/**
The region maps encode information about region relationships.
- `scope_map` maps from a scope id to the enclosing scope id; this is
usually corresponding to the lexical nesting, though in the case of
closures the parent scope is the innermost conditional expression or repeating
block
- `var_map` maps from a variable or binding id to the block in which
that variable is declared.
- `free_region_map` maps from a free region `a` to a list of free
regions `bs` such that `a <= b for all b in bs`
- the free region map is populated during type check as we check
each function. See the function `relate_free_regions` for
more information.
- `rvalue_scopes` includes entries for those expressions whose cleanup
scope is larger than the default. The map goes from the expression
id to the cleanup scope id. For rvalues not present in this table,
the appropriate cleanup scope is the innermost enclosing statement,
conditional expression, or repeating block (see `terminating_scopes`).
- `terminating_scopes` is a set containing the ids of each statement,
or conditional/repeating expression. These scopes are calling "terminating
scopes" because, when attempting to find the scope of a temporary, by
default we search up the enclosing scopes until we encounter the
terminating scope. A conditional/repeating
expression is one which is not guaranteed to execute exactly once
upon entering the parent scope. This could be because the expression
only executes conditionally, such as the expression `b` in `a && b`,
or because the expression may execute many times, such as a loop
body. The reason that we distinguish such expressions is that, upon
exiting the parent scope, we cannot statically know how many times
the expression executed, and thus if the expression creates
temporaries we cannot know statically how many such temporaries we
would have to cleanup. Therefore we ensure that the temporaries never
outlast the conditional/repeating expression, preventing the need
for dynamic checks and/or arbitrary amounts of stack space.
*/
/// - `scope_map` maps from a scope id to the enclosing scope id; this is
/// usually corresponding to the lexical nesting, though in the case of
/// closures the parent scope is the innermost conditional expression or repeating
/// block
///
/// - `var_map` maps from a variable or binding id to the block in which
/// that variable is declared.
///
/// - `free_region_map` maps from a free region `a` to a list of free
/// regions `bs` such that `a <= b for all b in bs`
/// - the free region map is populated during type check as we check
/// each function. See the function `relate_free_regions` for
/// more information.
///
/// - `rvalue_scopes` includes entries for those expressions whose cleanup
/// scope is larger than the default. The map goes from the expression
/// id to the cleanup scope id. For rvalues not present in this table,
/// the appropriate cleanup scope is the innermost enclosing statement,
/// conditional expression, or repeating block (see `terminating_scopes`).
///
/// - `terminating_scopes` is a set containing the ids of each statement,
/// or conditional/repeating expression. These scopes are calling "terminating
/// scopes" because, when attempting to find the scope of a temporary, by
/// default we search up the enclosing scopes until we encounter the
/// terminating scope. A conditional/repeating
/// expression is one which is not guaranteed to execute exactly once
/// upon entering the parent scope. This could be because the expression
/// only executes conditionally, such as the expression `b` in `a && b`,
/// or because the expression may execute many times, such as a loop
/// body. The reason that we distinguish such expressions is that, upon
/// exiting the parent scope, we cannot statically know how many times
/// the expression executed, and thus if the expression creates
/// temporaries we cannot know statically how many such temporaries we
/// would have to cleanup. Therefore we ensure that the temporaries never
/// outlast the conditional/repeating expression, preventing the need
/// for dynamic checks and/or arbitrary amounts of stack space.
pub struct RegionMaps {
scope_map: RefCell<FnvHashMap<CodeExtent, CodeExtent>>,
var_map: RefCell<NodeMap<CodeExtent>>,

View File

@ -761,10 +761,8 @@ impl NameBindings {
}
}
/**
* Returns the module node. Panics if this node does not have a module
* definition.
*/
/// Returns the module node. Panics if this node does not have a module
/// definition.
fn get_module(&self) -> Rc<Module> {
match self.get_module_if_available() {
None => {
@ -1098,18 +1096,16 @@ impl<'a> Resolver<'a> {
visit::walk_crate(&mut visitor, krate);
}
/**
* Adds a new child item to the module definition of the parent node and
* returns its corresponding name bindings as well as the current parent.
* Or, if we're inside a block, creates (or reuses) an anonymous module
* corresponding to the innermost block ID and returns the name bindings
* as well as the newly-created parent.
*
* # Panics
*
* Panics if this node does not have a module definition and we are not inside
* a block.
*/
/// Adds a new child item to the module definition of the parent node and
/// returns its corresponding name bindings as well as the current parent.
/// Or, if we're inside a block, creates (or reuses) an anonymous module
/// corresponding to the innermost block ID and returns the name bindings
/// as well as the newly-created parent.
///
/// # Panics
///
/// Panics if this node does not have a module definition and we are not inside
/// a block.
fn add_child(&self,
name: Name,
reduced_graph_parent: ReducedGraphParent,

View File

@ -24,22 +24,19 @@ use syntax::codemap::{Span, DUMMY_SP};
///////////////////////////////////////////////////////////////////////////
/**
* A substitution mapping type/region parameters to new values. We
* identify each in-scope parameter by an *index* and a *parameter
* space* (which indices where the parameter is defined; see
* `ParamSpace`).
*/
/// A substitution mapping type/region parameters to new values. We
/// identify each in-scope parameter by an *index* and a *parameter
/// space* (which indices where the parameter is defined; see
/// `ParamSpace`).
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct Substs<'tcx> {
pub types: VecPerParamSpace<Ty<'tcx>>,
pub regions: RegionSubsts,
}
/**
* Represents the values to use when substituting lifetime parameters.
* If the value is `ErasedRegions`, then this subst is occurring during
* trans, and all region parameters will be replaced with `ty::ReStatic`. */
/// Represents the values to use when substituting lifetime parameters.
/// If the value is `ErasedRegions`, then this subst is occurring during
/// trans, and all region parameters will be replaced with `ty::ReStatic`.
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum RegionSubsts {
ErasedRegions,
@ -226,11 +223,9 @@ impl ParamSpace {
}
}
/**
* Vector of things sorted by param space. Used to keep
* the set of things declared on the type, self, or method
* distinct.
*/
/// Vector of things sorted by param space. Used to keep
/// the set of things declared on the type, self, or method
/// distinct.
#[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)]
pub struct VecPerParamSpace<T> {
// This was originally represented as a tuple with one Vec<T> for
@ -250,10 +245,8 @@ pub struct VecPerParamSpace<T> {
content: Vec<T>,
}
/**
* The `split` function converts one `VecPerParamSpace` into this
* `SeparateVecsPerParamSpace` structure.
*/
/// The `split` function converts one `VecPerParamSpace` into this
/// `SeparateVecsPerParamSpace` structure.
pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>,
pub selfs: Vec<T>,

View File

@ -19,18 +19,16 @@ use super::FulfillmentError;
use super::CodeSelectionError;
use super::select::SelectionContext;
/**
* The fulfillment context is used to drive trait resolution. It
* consists of a list of obligations that must be (eventually)
* satisfied. The job is to track which are satisfied, which yielded
* errors, and which are still pending. At any point, users can call
* `select_where_possible`, and the fulfilment context will try to do
* selection, retaining only those obligations that remain
* ambiguous. This may be helpful in pushing type inference
* along. Once all type inference constraints have been generated, the
* method `select_all_or_error` can be used to report any remaining
* ambiguous cases as errors.
*/
/// The fulfillment context is used to drive trait resolution. It
/// consists of a list of obligations that must be (eventually)
/// satisfied. The job is to track which are satisfied, which yielded
/// errors, and which are still pending. At any point, users can call
/// `select_where_possible`, and the fulfilment context will try to do
/// selection, retaining only those obligations that remain
/// ambiguous. This may be helpful in pushing type inference
/// along. Once all type inference constraints have been generated, the
/// method `select_all_or_error` can be used to report any remaining
/// ambiguous cases as errors.
pub struct FulfillmentContext<'tcx> {
// A list of all obligations that have been registered with this
// fulfillment context.

View File

@ -42,14 +42,12 @@ mod fulfill;
mod select;
mod util;
/**
* An `Obligation` represents some trait reference (e.g. `int:Eq`) for
* which the vtable must be found. The process of finding a vtable is
* called "resolving" the `Obligation`. This process consists of
* either identifying an `impl` (e.g., `impl Eq for int`) that
* provides the required vtable, or else finding a bound that is in
* scope. The eventual result is usually a `Selection` (defined below).
*/
/// An `Obligation` represents some trait reference (e.g. `int:Eq`) for
/// which the vtable must be found. The process of finding a vtable is
/// called "resolving" the `Obligation`. This process consists of
/// either identifying an `impl` (e.g., `impl Eq for int`) that
/// provides the required vtable, or else finding a bound that is in
/// scope. The eventual result is usually a `Selection` (defined below).
#[deriving(Clone)]
pub struct Obligation<'tcx> {
pub cause: ObligationCause<'tcx>,
@ -57,9 +55,7 @@ pub struct Obligation<'tcx> {
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
}
/**
* Why did we incur this obligation? Used for error reporting.
*/
/// Why did we incur this obligation? Used for error reporting.
#[deriving(Clone)]
pub struct ObligationCause<'tcx> {
pub span: Span,
@ -121,57 +117,53 @@ pub enum FulfillmentErrorCode<'tcx> {
CodeAmbiguity,
}
/**
* When performing resolution, it is typically the case that there
* can be one of three outcomes:
*
* - `Ok(Some(r))`: success occurred with result `r`
* - `Ok(None)`: could not definitely determine anything, usually due
* to inconclusive type inference.
* - `Err(e)`: error `e` occurred
*/
/// When performing resolution, it is typically the case that there
/// can be one of three outcomes:
///
/// - `Ok(Some(r))`: success occurred with result `r`
/// - `Ok(None)`: could not definitely determine anything, usually due
/// to inconclusive type inference.
/// - `Err(e)`: error `e` occurred
pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
/**
* Given the successful resolution of an obligation, the `Vtable`
* indicates where the vtable comes from. Note that while we call this
* a "vtable", it does not necessarily indicate dynamic dispatch at
* runtime. `Vtable` instances just tell the compiler where to find
* methods, but in generic code those methods are typically statically
* dispatched -- only when an object is constructed is a `Vtable`
* instance reified into an actual vtable.
*
* For example, the vtable may be tied to a specific impl (case A),
* or it may be relative to some bound that is in scope (case B).
*
*
* ```
* impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
* impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
* impl Clone for int { ... } // Impl_3
*
* fn foo<T:Clone>(concrete: Option<Box<int>>,
* param: T,
* mixed: Option<T>) {
*
* // Case A: Vtable points at a specific impl. Only possible when
* // type is concretely known. If the impl itself has bounded
* // type parameters, Vtable will carry resolutions for those as well:
* concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
*
* // Case B: Vtable must be provided by caller. This applies when
* // type is a type parameter.
* param.clone(); // VtableParam(Oblig_1)
*
* // Case C: A mix of cases A and B.
* mixed.clone(); // Vtable(Impl_1, [VtableParam(Oblig_1)])
* }
* ```
*
* ### The type parameter `N`
*
* See explanation on `VtableImplData`.
*/
/// Given the successful resolution of an obligation, the `Vtable`
/// indicates where the vtable comes from. Note that while we call this
/// a "vtable", it does not necessarily indicate dynamic dispatch at
/// runtime. `Vtable` instances just tell the compiler where to find
/// methods, but in generic code those methods are typically statically
/// dispatched -- only when an object is constructed is a `Vtable`
/// instance reified into an actual vtable.
///
/// For example, the vtable may be tied to a specific impl (case A),
/// or it may be relative to some bound that is in scope (case B).
///
///
/// ```
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
/// impl Clone for int { ... } // Impl_3
///
/// fn foo<T:Clone>(concrete: Option<Box<int>>,
/// param: T,
/// mixed: Option<T>) {
///
/// // Case A: Vtable points at a specific impl. Only possible when
/// // type is concretely known. If the impl itself has bounded
/// // type parameters, Vtable will carry resolutions for those as well:
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
///
/// // Case B: Vtable must be provided by caller. This applies when
/// // type is a type parameter.
/// param.clone(); // VtableParam(Oblig_1)
///
/// // Case C: A mix of cases A and B.
/// mixed.clone(); // Vtable(Impl_1, [VtableParam(Oblig_1)])
/// }
/// ```
///
/// ### The type parameter `N`
///
/// See explanation on `VtableImplData`.
#[deriving(Show,Clone)]
pub enum Vtable<'tcx, N> {
/// Vtable identifying a particular impl.
@ -191,18 +183,16 @@ pub enum Vtable<'tcx, N> {
VtableBuiltin(VtableBuiltinData<N>),
}
/**
* Identifies a particular impl in the source, along with a set of
* substitutions from the impl's type/lifetime parameters. The
* `nested` vector corresponds to the nested obligations attached to
* the impl's type parameters.
*
* The type parameter `N` indicates the type used for "nested
* obligations" that are required by the impl. During type check, this
* is `Obligation`, as one might expect. During trans, however, this
* is `()`, because trans only requires a shallow resolution of an
* impl, and nested obligations are satisfied later.
*/
/// Identifies a particular impl in the source, along with a set of
/// substitutions from the impl's type/lifetime parameters. The
/// `nested` vector corresponds to the nested obligations attached to
/// the impl's type parameters.
///
/// The type parameter `N` indicates the type used for "nested
/// obligations" that are required by the impl. During type check, this
/// is `Obligation`, as one might expect. During trans, however, this
/// is `()`, because trans only requires a shallow resolution of an
/// impl, and nested obligations are satisfied later.
#[deriving(Clone)]
pub struct VtableImplData<'tcx, N> {
pub impl_def_id: ast::DefId,
@ -215,11 +205,9 @@ pub struct VtableBuiltinData<N> {
pub nested: subst::VecPerParamSpace<N>
}
/**
* A vtable provided as a parameter by the caller. For example, in a
* function like `fn foo<T:Eq>(...)`, if the `eq()` method is invoked
* on an instance of `T`, the vtable would be of type `VtableParam`.
*/
/// A vtable provided as a parameter by the caller. For example, in a
/// function like `fn foo<T:Eq>(...)`, if the `eq()` method is invoked
/// on an instance of `T`, the vtable would be of type `VtableParam`.
#[deriving(PartialEq,Eq,Clone)]
pub struct VtableParamData<'tcx> {
// In the above example, this would `Eq`

View File

@ -102,32 +102,30 @@ pub enum MethodMatchedData {
CoerciveMethodMatch(/* impl we matched */ ast::DefId)
}
/**
* The selection process begins by considering all impls, where
* clauses, and so forth that might resolve an obligation. Sometimes
* we'll be able to say definitively that (e.g.) an impl does not
* apply to the obligation: perhaps it is defined for `uint` but the
* obligation is for `int`. In that case, we drop the impl out of the
* list. But the other cases are considered *candidates*.
*
* Candidates can either be definitive or ambiguous. An ambiguous
* candidate is one that might match or might not, depending on how
* type variables wind up being resolved. This only occurs during inference.
*
* For selection to suceed, there must be exactly one non-ambiguous
* candidate. Usually, it is not possible to have more than one
* definitive candidate, due to the coherence rules. However, there is
* one case where it could occur: if there is a blanket impl for a
* trait (that is, an impl applied to all T), and a type parameter
* with a where clause. In that case, we can have a candidate from the
* where clause and a second candidate from the impl. This is not a
* problem because coherence guarantees us that the impl which would
* be used to satisfy the where clause is the same one that we see
* now. To resolve this issue, therefore, we ignore impls if we find a
* matching where clause. Part of the reason for this is that where
* clauses can give additional information (like, the types of output
* parameters) that would have to be inferred from the impl.
*/
/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes
/// we'll be able to say definitively that (e.g.) an impl does not
/// apply to the obligation: perhaps it is defined for `uint` but the
/// obligation is for `int`. In that case, we drop the impl out of the
/// list. But the other cases are considered *candidates*.
///
/// Candidates can either be definitive or ambiguous. An ambiguous
/// candidate is one that might match or might not, depending on how
/// type variables wind up being resolved. This only occurs during inference.
///
/// For selection to suceed, there must be exactly one non-ambiguous
/// candidate. Usually, it is not possible to have more than one
/// definitive candidate, due to the coherence rules. However, there is
/// one case where it could occur: if there is a blanket impl for a
/// trait (that is, an impl applied to all T), and a type parameter
/// with a where clause. In that case, we can have a candidate from the
/// where clause and a second candidate from the impl. This is not a
/// problem because coherence guarantees us that the impl which would
/// be used to satisfy the where clause is the same one that we see
/// now. To resolve this issue, therefore, we ignore impls if we find a
/// matching where clause. Part of the reason for this is that where
/// clauses can give additional information (like, the types of output
/// parameters) that would have to be inferred from the impl.
#[deriving(PartialEq,Eq,Show,Clone)]
enum Candidate<'tcx> {
BuiltinCandidate(ty::BuiltinBound),

View File

@ -743,18 +743,16 @@ impl<'tcx> FnOutput<'tcx> {
}
}
/**
* Signature of a function type, which I have arbitrarily
* decided to use to refer to the input/output types.
*
* - `inputs` is the list of arguments and their modes.
* - `output` is the return type.
* - `variadic` indicates whether this is a varidic function. (only true for foreign fns)
*
* Note that a `FnSig` introduces a level of region binding, to
* account for late-bound parameters that appear in the types of the
* fn's arguments or the fn's return type.
*/
/// Signature of a function type, which I have arbitrarily
/// decided to use to refer to the input/output types.
///
/// - `inputs` is the list of arguments and their modes.
/// - `output` is the return type.
/// - `variadic` indicates whether this is a varidic function. (only true for foreign fns)
///
/// Note that a `FnSig` introduces a level of region binding, to
/// account for late-bound parameters that appear in the types of the
/// fn's arguments or the fn's return type.
#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct FnSig<'tcx> {
pub inputs: Vec<Ty<'tcx>>,
@ -769,47 +767,45 @@ pub struct ParamTy {
pub def_id: DefId
}
/**
* A [De Bruijn index][dbi] is a standard means of representing
* regions (and perhaps later types) in a higher-ranked setting. In
* particular, imagine a type like this:
*
* for<'a> fn(for<'b> fn(&'b int, &'a int), &'a char)
* ^ ^ | | |
* | | | | |
* | +------------+ 1 | |
* | | |
* +--------------------------------+ 2 |
* | |
* +------------------------------------------+ 1
*
* In this type, there are two binders (the outer fn and the inner
* fn). We need to be able to determine, for any given region, which
* fn type it is bound by, the inner or the outer one. There are
* various ways you can do this, but a De Bruijn index is one of the
* more convenient and has some nice properties. The basic idea is to
* count the number of binders, inside out. Some examples should help
* clarify what I mean.
*
* Let's start with the reference type `&'b int` that is the first
* argument to the inner function. This region `'b` is assigned a De
* Bruijn index of 1, meaning "the innermost binder" (in this case, a
* fn). The region `'a` that appears in the second argument type (`&'a
* int`) would then be assigned a De Bruijn index of 2, meaning "the
* second-innermost binder". (These indices are written on the arrays
* in the diagram).
*
* What is interesting is that De Bruijn index attached to a particular
* variable will vary depending on where it appears. For example,
* the final type `&'a char` also refers to the region `'a` declared on
* the outermost fn. But this time, this reference is not nested within
* any other binders (i.e., it is not an argument to the inner fn, but
* rather the outer one). Therefore, in this case, it is assigned a
* De Bruijn index of 1, because the innermost binder in that location
* is the outer fn.
*
* [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
*/
/// A [De Bruijn index][dbi] is a standard means of representing
/// regions (and perhaps later types) in a higher-ranked setting. In
/// particular, imagine a type like this:
///
/// for<'a> fn(for<'b> fn(&'b int, &'a int), &'a char)
/// ^ ^ | | |
/// | | | | |
/// | +------------+ 1 | |
/// | | |
/// +--------------------------------+ 2 |
/// | |
/// +------------------------------------------+ 1
///
/// In this type, there are two binders (the outer fn and the inner
/// fn). We need to be able to determine, for any given region, which
/// fn type it is bound by, the inner or the outer one. There are
/// various ways you can do this, but a De Bruijn index is one of the
/// more convenient and has some nice properties. The basic idea is to
/// count the number of binders, inside out. Some examples should help
/// clarify what I mean.
///
/// Let's start with the reference type `&'b int` that is the first
/// argument to the inner function. This region `'b` is assigned a De
/// Bruijn index of 1, meaning "the innermost binder" (in this case, a
/// fn). The region `'a` that appears in the second argument type (`&'a
/// int`) would then be assigned a De Bruijn index of 2, meaning "the
/// second-innermost binder". (These indices are written on the arrays
/// in the diagram).
///
/// What is interesting is that De Bruijn index attached to a particular
/// variable will vary depending on where it appears. For example,
/// the final type `&'a char` also refers to the region `'a` declared on
/// the outermost fn. But this time, this reference is not nested within
/// any other binders (i.e., it is not an argument to the inner fn, but
/// rather the outer one). Therefore, in this case, it is assigned a
/// De Bruijn index of 1, because the innermost binder in that location
/// is the outer fn.
///
/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
#[deriving(Clone, PartialEq, Eq, Hash, Encodable, Decodable, Show)]
pub struct DebruijnIndex {
// We maintain the invariant that this is never 0. So 1 indicates
@ -856,11 +852,9 @@ pub enum Region {
ReEmpty,
}
/**
* Upvars do not get their own node-id. Instead, we use the pair of
* the original var id (that is, the root variable that is referenced
* by the upvar) and the id of the closure expression.
*/
/// Upvars do not get their own node-id. Instead, we use the pair of
/// the original var id (that is, the root variable that is referenced
/// by the upvar) and the id of the closure expression.
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct UpvarId {
pub var_id: ast::NodeId,
@ -913,55 +907,53 @@ pub enum BorrowKind {
MutBorrow
}
/**
* Information describing the borrowing of an upvar. This is computed
* during `typeck`, specifically by `regionck`. The general idea is
* that the compiler analyses treat closures like:
*
* let closure: &'e fn() = || {
* x = 1; // upvar x is assigned to
* use(y); // upvar y is read
* foo(&z); // upvar z is borrowed immutably
* };
*
* as if they were "desugared" to something loosely like:
*
* struct Vars<'x,'y,'z> { x: &'x mut int,
* y: &'y const int,
* z: &'z int }
* let closure: &'e fn() = {
* fn f(env: &Vars) {
* *env.x = 1;
* use(*env.y);
* foo(env.z);
* }
* let env: &'e mut Vars<'x,'y,'z> = &mut Vars { x: &'x mut x,
* y: &'y const y,
* z: &'z z };
* (env, f)
* };
*
* This is basically what happens at runtime. The closure is basically
* an existentially quantified version of the `(env, f)` pair.
*
* This data structure indicates the region and mutability of a single
* one of the `x...z` borrows.
*
* It may not be obvious why each borrowed variable gets its own
* lifetime (in the desugared version of the example, these are indicated
* by the lifetime parameters `'x`, `'y`, and `'z` in the `Vars` definition).
* Each such lifetime must encompass the lifetime `'e` of the closure itself,
* but need not be identical to it. The reason that this makes sense:
*
* - Callers are only permitted to invoke the closure, and hence to
* use the pointers, within the lifetime `'e`, so clearly `'e` must
* be a sublifetime of `'x...'z`.
* - The closure creator knows which upvars were borrowed by the closure
* and thus `x...z` will be reserved for `'x...'z` respectively.
* - Through mutation, the borrowed upvars can actually escape
* the closure, so sometimes it is necessary for them to be larger
* than the closure lifetime itself.
*/
/// Information describing the borrowing of an upvar. This is computed
/// during `typeck`, specifically by `regionck`. The general idea is
/// that the compiler analyses treat closures like:
///
/// let closure: &'e fn() = || {
/// x = 1; // upvar x is assigned to
/// use(y); // upvar y is read
/// foo(&z); // upvar z is borrowed immutably
/// };
///
/// as if they were "desugared" to something loosely like:
///
/// struct Vars<'x,'y,'z> { x: &'x mut int,
/// y: &'y const int,
/// z: &'z int }
/// let closure: &'e fn() = {
/// fn f(env: &Vars) {
/// *env.x = 1;
/// use(*env.y);
/// foo(env.z);
/// }
/// let env: &'e mut Vars<'x,'y,'z> = &mut Vars { x: &'x mut x,
/// y: &'y const y,
/// z: &'z z };
/// (env, f)
/// };
///
/// This is basically what happens at runtime. The closure is basically
/// an existentially quantified version of the `(env, f)` pair.
///
/// This data structure indicates the region and mutability of a single
/// one of the `x...z` borrows.
///
/// It may not be obvious why each borrowed variable gets its own
/// lifetime (in the desugared version of the example, these are indicated
/// by the lifetime parameters `'x`, `'y`, and `'z` in the `Vars` definition).
/// Each such lifetime must encompass the lifetime `'e` of the closure itself,
/// but need not be identical to it. The reason that this makes sense:
///
/// - Callers are only permitted to invoke the closure, and hence to
/// use the pointers, within the lifetime `'e`, so clearly `'e` must
/// be a sublifetime of `'x...'z`.
/// - The closure creator knows which upvars were borrowed by the closure
/// and thus `x...z` will be reserved for `'x...'z` respectively.
/// - Through mutation, the borrowed upvars can actually escape
/// the closure, so sometimes it is necessary for them to be larger
/// than the closure lifetime itself.
#[deriving(PartialEq, Clone, Encodable, Decodable, Show)]
pub struct UpvarBorrow {
pub kind: BorrowKind,
@ -1111,37 +1103,33 @@ pub struct TyTrait<'tcx> {
pub bounds: ExistentialBounds
}
/**
* A complete reference to a trait. These take numerous guises in syntax,
* but perhaps the most recognizable form is in a where clause:
*
* T : Foo<U>
*
* This would be represented by a trait-reference where the def-id is the
* def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
* `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
*
* Trait references also appear in object types like `Foo<U>`, but in
* that case the `Self` parameter is absent from the substitutions.
*
* Note that a `TraitRef` introduces a level of region binding, to
* account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
* U>` or higher-ranked object types.
*/
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause:
///
/// T : Foo<U>
///
/// This would be represented by a trait-reference where the def-id is the
/// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
/// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
///
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
/// U>` or higher-ranked object types.
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub substs: Substs<'tcx>,
}
/**
* Binder serves as a synthetic binder for lifetimes. It is used when
* we wish to replace the escaping higher-ranked lifetimes in a type
* or something else that is not itself a binder (this is because the
* `replace_late_bound_regions` function replaces all lifetimes bound
* by the binder supplied to it; but a type is not a binder, so you
* must introduce an artificial one).
*/
/// Binder serves as a synthetic binder for lifetimes. It is used when
/// we wish to replace the escaping higher-ranked lifetimes in a type
/// or something else that is not itself a binder (this is because the
/// `replace_late_bound_regions` function replaces all lifetimes bound
/// by the binder supplied to it; but a type is not a binder, so you
/// must introduce an artificial one).
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct Binder<T> {
pub value: T
@ -1425,27 +1413,25 @@ impl<'tcx> Generics<'tcx> {
}
}
/**
* Represents the bounds declared on a particular set of type
* parameters. Should eventually be generalized into a flag list of
* where clauses. You can obtain a `GenericBounds` list from a
* `Generics` by using the `to_bounds` method. Note that this method
* reflects an important semantic invariant of `GenericBounds`: while
* the bounds in a `Generics` are expressed in terms of the bound type
* parameters of the impl/trait/whatever, a `GenericBounds` instance
* represented a set of bounds for some particular instantiation,
* meaning that the generic parameters have been substituted with
* their values.
*
* Example:
*
* struct Foo<T,U:Bar<T>> { ... }
*
* Here, the `Generics` for `Foo` would contain a list of bounds like
* `[[], [U:Bar<T>]]`. Now if there were some particular reference
* like `Foo<int,uint>`, then the `GenericBounds` would be `[[],
* [uint:Bar<int>]]`.
*/
/// Represents the bounds declared on a particular set of type
/// parameters. Should eventually be generalized into a flag list of
/// where clauses. You can obtain a `GenericBounds` list from a
/// `Generics` by using the `to_bounds` method. Note that this method
/// reflects an important semantic invariant of `GenericBounds`: while
/// the bounds in a `Generics` are expressed in terms of the bound type
/// parameters of the impl/trait/whatever, a `GenericBounds` instance
/// represented a set of bounds for some particular instantiation,
/// meaning that the generic parameters have been substituted with
/// their values.
///
/// Example:
///
/// struct Foo<T,U:Bar<T>> { ... }
///
/// Here, the `Generics` for `Foo` would contain a list of bounds like
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
/// like `Foo<int,uint>`, then the `GenericBounds` would be `[[],
/// [uint:Bar<int>]]`.
#[deriving(Clone, Show)]
pub struct GenericBounds<'tcx> {
pub types: VecPerParamSpace<ParamBounds<'tcx>>,
@ -2455,18 +2441,16 @@ pub fn type_needs_unwind_cleanup<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
}
}
/**
* Type contents is how the type checker reasons about kinds.
* They track what kinds of things are found within a type. You can
* think of them as kind of an "anti-kind". They track the kinds of values
* and thinks that are contained in types. Having a larger contents for
* a type tends to rule that type *out* from various kinds. For example,
* a type that contains a reference is not sendable.
*
* The reason we compute type contents and not kinds is that it is
* easier for me (nmatsakis) to think about what is contained within
* a type than to think about what is *not* contained within a type.
*/
/// Type contents is how the type checker reasons about kinds.
/// They track what kinds of things are found within a type. You can
/// think of them as kind of an "anti-kind". They track the kinds of values
/// and thinks that are contained in types. Having a larger contents for
/// a type tends to rule that type *out* from various kinds. For example,
/// a type that contains a reference is not sendable.
///
/// The reason we compute type contents and not kinds is that it is
/// easier for me (nmatsakis) to think about what is contained within
/// a type than to think about what is *not* contained within a type.
#[deriving(Clone)]
pub struct TypeContents {
pub bits: u64

View File

@ -701,9 +701,7 @@ pub fn super_fold_obligation<'tcx, T:TypeFolder<'tcx>>(this: &mut T,
///////////////////////////////////////////////////////////////////////////
// Higher-ranked things
/**
* Designates a "binder" for late-bound regions.
*/
/// Designates a "binder" for late-bound regions.
pub trait HigherRankedFoldable<'tcx>: Repr<'tcx> {
/// Folds the contents of `self`, ignoring the region binder created
/// by `self`.

View File

@ -897,19 +897,17 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}
/**
* Checks that a method from an impl conforms to the signature of
* the same method as declared in the trait.
*
* # Parameters
*
* - impl_generics: the generics declared on the impl itself (not the method!)
* - impl_m: type of the method we are checking
* - impl_m_span: span to use for reporting errors
* - impl_m_body_id: id of the method body
* - trait_m: the method in the trait
* - trait_to_impl_substs: the substitutions used on the type of the trait
*/
/// Checks that a method from an impl conforms to the signature of
/// the same method as declared in the trait.
///
/// # Parameters
///
/// - impl_generics: the generics declared on the impl itself (not the method!)
/// - impl_m: type of the method we are checking
/// - impl_m_span: span to use for reporting errors
/// - impl_m_body_id: id of the method body
/// - trait_m: the method in the trait
/// - trait_to_impl_substs: the substitutions used on the type of the trait
fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_m: &ty::Method<'tcx>,
impl_m_span: Span,

View File

@ -694,13 +694,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
}
}
/**
This function performs the actual region resolution. It must be
called after all constraints have been added. It performs a
fixed-point iteration to find region values which satisfy all
constraints, assuming such values can be found; if they cannot,
errors are reported.
*/
/// This function performs the actual region resolution. It must be
/// called after all constraints have been added. It performs a
/// fixed-point iteration to find region values which satisfy all
/// constraints, assuming such values can be found; if they cannot,
/// errors are reported.
pub fn resolve_regions(&self) -> Vec<RegionResolutionError<'tcx>> {
debug!("RegionVarBindings: resolve_regions()");
let mut errors = vec!();

View File

@ -22,85 +22,68 @@ use syntax::ast;
use util::ppaux::Repr;
use util::snapshot_vec as sv;
/**
* This trait is implemented by any type that can serve as a type
* variable. We call such variables *unification keys*. For example,
* this trait is implemented by `IntVid`, which represents integral
* variables.
*
* Each key type has an associated value type `V`. For example, for
* `IntVid`, this is `Option<IntVarValue>`, representing some
* (possibly not yet known) sort of integer.
*
* Implementations of this trait are at the end of this file.
*/
/// This trait is implemented by any type that can serve as a type
/// variable. We call such variables *unification keys*. For example,
/// this trait is implemented by `IntVid`, which represents integral
/// variables.
///
/// Each key type has an associated value type `V`. For example, for
/// `IntVid`, this is `Option<IntVarValue>`, representing some
/// (possibly not yet known) sort of integer.
///
/// Implementations of this trait are at the end of this file.
pub trait UnifyKey<'tcx, V> : Clone + Show + PartialEq + Repr<'tcx> {
fn index(&self) -> uint;
fn from_index(u: uint) -> Self;
/**
* Given an inference context, returns the unification table
* appropriate to this key type.
*/
// Given an inference context, returns the unification table
// appropriate to this key type.
fn unification_table<'v>(infcx: &'v InferCtxt)
-> &'v RefCell<UnificationTable<Self,V>>;
fn tag(k: Option<Self>) -> &'static str;
}
/**
* Trait for valid types that a type variable can be set to. Note that
* this is typically not the end type that the value will take on, but
* rather an `Option` wrapper (where `None` represents a variable
* whose value is not yet set).
*
* Implementations of this trait are at the end of this file.
*/
/// Trait for valid types that a type variable can be set to. Note that
/// this is typically not the end type that the value will take on, but
/// rather an `Option` wrapper (where `None` represents a variable
/// whose value is not yet set).
///
/// Implementations of this trait are at the end of this file.
pub trait UnifyValue<'tcx> : Clone + Repr<'tcx> + PartialEq {
}
/**
* Value of a unification key. We implement Tarjan's union-find
* algorithm: when two keys are unified, one of them is converted
* into a "redirect" pointing at the other. These redirects form a
* DAG: the roots of the DAG (nodes that are not redirected) are each
* associated with a value of type `V` and a rank. The rank is used
* to keep the DAG relatively balanced, which helps keep the running
* time of the algorithm under control. For more information, see
* <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
*/
/// Value of a unification key. We implement Tarjan's union-find
/// algorithm: when two keys are unified, one of them is converted
/// into a "redirect" pointing at the other. These redirects form a
/// DAG: the roots of the DAG (nodes that are not redirected) are each
/// associated with a value of type `V` and a rank. The rank is used
/// to keep the DAG relatively balanced, which helps keep the running
/// time of the algorithm under control. For more information, see
/// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
#[deriving(PartialEq,Clone)]
pub enum VarValue<K,V> {
Redirect(K),
Root(V, uint),
}
/**
* Table of unification keys and their values.
*/
/// Table of unification keys and their values.
pub struct UnificationTable<K,V> {
/**
* Indicates the current value of each key.
*/
/// Indicates the current value of each key.
values: sv::SnapshotVec<VarValue<K,V>,(),Delegate>,
}
/**
* At any time, users may snapshot a unification table. The changes
* made during the snapshot may either be *committed* or *rolled back*.
*/
/// At any time, users may snapshot a unification table. The changes
/// made during the snapshot may either be *committed* or *rolled back*.
pub struct Snapshot<K> {
// Link snapshot to the key type `K` of the table.
marker: marker::CovariantType<K>,
snapshot: sv::Snapshot,
}
/**
* Internal type used to represent the result of a `get()` operation.
* Conveys the current root and value of the key.
*/
/// Internal type used to represent the result of a `get()` operation.
/// Conveys the current root and value of the key.
pub struct Node<K,V> {
pub key: K,
pub value: V,
@ -121,28 +104,22 @@ impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K
}
}
/**
* Starts a new snapshot. Each snapshot must be either
* rolled back or committed in a "LIFO" (stack) order.
*/
/// Starts a new snapshot. Each snapshot must be either
/// rolled back or committed in a "LIFO" (stack) order.
pub fn snapshot(&mut self) -> Snapshot<K> {
Snapshot { marker: marker::CovariantType::<K>,
snapshot: self.values.start_snapshot() }
}
/**
* Reverses all changes since the last snapshot. Also
* removes any keys that have been created since then.
*/
/// Reverses all changes since the last snapshot. Also
/// removes any keys that have been created since then.
pub fn rollback_to(&mut self, snapshot: Snapshot<K>) {
debug!("{}: rollback_to()", UnifyKey::tag(None::<K>));
self.values.rollback_to(snapshot.snapshot);
}
/**
* Commits all changes since the last snapshot. Of course, they
* can still be undone if there is a snapshot further out.
*/
/// Commits all changes since the last snapshot. Of course, they
/// can still be undone if there is a snapshot further out.
pub fn commit(&mut self, snapshot: Snapshot<K>) {
debug!("{}: commit()", UnifyKey::tag(None::<K>));
self.values.commit(snapshot.snapshot);
@ -255,10 +232,8 @@ impl<K,V> sv::SnapshotVecDelegate<VarValue<K,V>,()> for Delegate {
// Code to handle simple keys like ints, floats---anything that
// doesn't have a subtyping relationship we need to worry about.
/**
* Indicates a type that does not have any kind of subtyping
* relationship.
*/
/// Indicates a type that does not have any kind of subtyping
/// relationship.
pub trait SimplyUnifiable<'tcx> : Clone + PartialEq + Repr<'tcx> {
fn to_type(&self) -> Ty<'tcx>;
fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;

View File

@ -150,20 +150,18 @@ pub struct MethodCallee<'tcx> {
pub substs: subst::Substs<'tcx>
}
/**
* With method calls, we store some extra information in
* side tables (i.e method_map). We use
* MethodCall as a key to index into these tables instead of
* just directly using the expression's NodeId. The reason
* for this being that we may apply adjustments (coercions)
* with the resulting expression also needing to use the
* side tables. The problem with this is that we don't
* assign a separate NodeId to this new expression
* and so it would clash with the base expression if both
* needed to add to the side tables. Thus to disambiguate
* we also keep track of whether there's an adjustment in
* our key.
*/
/// With method calls, we store some extra information in
/// side tables (i.e method_map). We use
/// MethodCall as a key to index into these tables instead of
/// just directly using the expression's NodeId. The reason
/// for this being that we may apply adjustments (coercions)
/// with the resulting expression also needing to use the
/// side tables. The problem with this is that we don't
/// assign a separate NodeId to this new expression
/// and so it would clash with the base expression if both
/// needed to add to the side tables. Thus to disambiguate
/// we also keep track of whether there's an adjustment in
/// our key.
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct MethodCall {
pub expr_id: ast::NodeId,

View File

@ -219,18 +219,16 @@ pub fn infer_variance(tcx: &ty::ctxt) {
tcx.variance_computed.set(true);
}
/**************************************************************************
* Representing terms
*
* Terms are structured as a straightforward tree. Rather than rely on
* GC, we allocate terms out of a bounded arena (the lifetime of this
* arena is the lifetime 'a that is threaded around).
*
* We assign a unique index to each type/region parameter whose variance
* is to be inferred. We refer to such variables as "inferreds". An
* `InferredIndex` is a newtype'd int representing the index of such
* a variable.
*/
// Representing terms
//
// Terms are structured as a straightforward tree. Rather than rely on
// GC, we allocate terms out of a bounded arena (the lifetime of this
// arena is the lifetime 'a that is threaded around).
//
// We assign a unique index to each type/region parameter whose variance
// is to be inferred. We refer to such variables as "inferreds". An
// `InferredIndex` is a newtype'd int representing the index of such
// a variable.
type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
@ -253,9 +251,7 @@ impl<'a> fmt::Show for VarianceTerm<'a> {
}
}
/**************************************************************************
* The first pass over the crate simply builds up the set of inferreds.
*/
// The first pass over the crate simply builds up the set of inferreds.
struct TermsContext<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
@ -399,12 +395,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
}
}
/**************************************************************************
* Constraint construction and representation
*
* The second pass over the AST determines the set of constraints.
* We walk the set of items and, for each member, generate new constraints.
*/
// Constraint construction and representation
//
// The second pass over the AST determines the set of constraints.
// We walk the set of items and, for each member, generate new constraints.
struct ConstraintContext<'a, 'tcx: 'a> {
terms_cx: TermsContext<'a, 'tcx>,
@ -944,14 +938,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}
/**************************************************************************
* Constraint solving
*
* The final phase iterates over the constraints, refining the variance
* for each inferred until a fixed point is reached. This will be the
* optimal solution to the constraints. The final variance for each
* inferred is then written into the `variance_map` in the tcx.
*/
// Constraint solving
//
// The final phase iterates over the constraints, refining the variance
// for each inferred until a fixed point is reached. This will be the
// optimal solution to the constraints. The final variance for each
// inferred is then written into the `variance_map` in the tcx.
struct SolveContext<'a, 'tcx: 'a> {
terms_cx: TermsContext<'a, 'tcx>,
@ -1086,9 +1078,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
}
}
/**************************************************************************
* Miscellany transformations on variance
*/
// Miscellany transformations on variance
trait Xform {
fn xform(self, v: Self) -> Self;

View File

@ -177,10 +177,8 @@ impl<T,U,D:SnapshotVecDelegate<T,U>> SnapshotVec<T,U,D> {
assert!(self.undo_log.len() == snapshot.length);
}
/**
* Commits all changes since the last snapshot. Of course, they
* can still be undone if there is a snapshot further out.
*/
/// Commits all changes since the last snapshot. Of course, they
/// can still be undone if there is a snapshot further out.
pub fn commit(&mut self, snapshot: Snapshot) {
debug!("commit({})", snapshot.length);

View File

@ -520,24 +520,24 @@ extern {
pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
pub fn LLVMDisposeModule(M: ModuleRef);
/** Data layout. See Module::getDataLayout. */
/// Data layout. See Module::getDataLayout.
pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
/** Target triple. See Module::getTargetTriple. */
/// Target triple. See Module::getTargetTriple.
pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
/** See Module::dump. */
/// See Module::dump.
pub fn LLVMDumpModule(M: ModuleRef);
/** See Module::setModuleInlineAsm. */
/// See Module::setModuleInlineAsm.
pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
/** See llvm::LLVMTypeKind::getTypeID. */
/// See llvm::LLVMTypeKind::getTypeID.
pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
/** See llvm::LLVMType::getContext. */
/// See llvm::LLVMType::getContext.
pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
/* Operations on integer types */
@ -1460,30 +1460,29 @@ extern {
pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
/** Writes a module to the specified path. Returns 0 on success. */
/// Writes a module to the specified path. Returns 0 on success.
pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
/** Creates target data from a target layout string. */
/// Creates target data from a target layout string.
pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
/// Adds the target data to the given pass manager. The pass manager
/// references the target data only weakly.
pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
/** Number of bytes clobbered when doing a Store to *T. */
/// Number of bytes clobbered when doing a Store to *T.
pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong;
/** Number of bytes clobbered when doing a Store to *T. */
/// Number of bytes clobbered when doing a Store to *T.
pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong;
/** Distance between successive elements in an array of T.
Includes ABI padding. */
/// Distance between successive elements in an array of T. Includes ABI padding.
pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
/** Returns the preferred alignment of a type. */
/// Returns the preferred alignment of a type.
pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint;
/** Returns the minimum alignment of a type. */
/// Returns the minimum alignment of a type.
pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint;
@ -1494,41 +1493,39 @@ extern {
Element: c_uint)
-> c_ulonglong;
/**
* Returns the minimum alignment of a type when part of a call frame.
*/
/// Returns the minimum alignment of a type when part of a call frame.
pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint;
/** Disposes target data. */
/// Disposes target data.
pub fn LLVMDisposeTargetData(TD: TargetDataRef);
/** Creates a pass manager. */
/// Creates a pass manager.
pub fn LLVMCreatePassManager() -> PassManagerRef;
/** Creates a function-by-function pass manager */
/// Creates a function-by-function pass manager
pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
-> PassManagerRef;
/** Disposes a pass manager. */
/// Disposes a pass manager.
pub fn LLVMDisposePassManager(PM: PassManagerRef);
/** Runs a pass manager on a module. */
/// Runs a pass manager on a module.
pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
/** Runs the function passes on the provided function. */
/// Runs the function passes on the provided function.
pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
-> Bool;
/** Initializes all the function passes scheduled in the manager */
/// Initializes all the function passes scheduled in the manager
pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
/** Finalizes all the function passes scheduled in the manager */
/// Finalizes all the function passes scheduled in the manager
pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
pub fn LLVMInitializePasses();
/** Adds a verification pass. */
/// Adds a verification pass.
pub fn LLVMAddVerifierPass(PM: PassManagerRef);
pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
@ -1598,38 +1595,38 @@ extern {
Internalize: Bool,
RunInliner: Bool);
/** Destroys a memory buffer. */
/// Destroys a memory buffer.
pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
/* Stuff that's in rustllvm/ because it's not upstream yet. */
/** Opens an object file. */
/// Opens an object file.
pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
/** Closes an object file. */
/// Closes an object file.
pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
/** Enumerates the sections in an object file. */
/// Enumerates the sections in an object file.
pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
/** Destroys a section iterator. */
/// Destroys a section iterator.
pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
/** Returns true if the section iterator is at the end of the section
list: */
/// Returns true if the section iterator is at the end of the section
/// list:
pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
SI: SectionIteratorRef)
-> Bool;
/** Moves the section iterator to point to the next section. */
/// Moves the section iterator to point to the next section.
pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
/** Returns the current section size. */
/// Returns the current section size.
pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
/** Returns the current section contents as a string buffer. */
/// Returns the current section contents as a string buffer.
pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
/** Reads the given file and returns it as a memory buffer. Use
LLVMDisposeMemoryBuffer() to get rid of it. */
/// Reads the given file and returns it as a memory buffer. Use
/// LLVMDisposeMemoryBuffer() to get rid of it.
pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
-> MemoryBufferRef;
/** Borrows the contents of the memory buffer (doesn't copy it) */
/// Borrows the contents of the memory buffer (doesn't copy it)
pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
InputDataLength: size_t,
BufferName: *const c_char,
@ -1643,8 +1640,7 @@ extern {
pub fn LLVMIsMultithreaded() -> Bool;
pub fn LLVMStartMultithreaded() -> Bool;
/** Returns a string describing the last error caused by an LLVMRust*
call. */
/// Returns a string describing the last error caused by an LLVMRust* call.
pub fn LLVMRustGetLastError() -> *const c_char;
/// Print the pass timings since static dtors aren't picking them up.
@ -1662,10 +1658,10 @@ extern {
Count: c_uint)
-> ValueRef;
/** Enables LLVM debug output. */
/// Enables LLVM debug output.
pub fn LLVMSetDebug(Enabled: c_int);
/** Prepares inline assembly. */
/// Prepares inline assembly.
pub fn LLVMInlineAsm(Ty: TypeRef,
AsmString: *const c_char,
Constraints: *const c_char,

View File

@ -98,10 +98,8 @@ pub fn compile_input(sess: Session,
phase_6_link_output(&sess, &trans, &outputs);
}
/**
* The name used for source code that doesn't originate in a file
* (e.g. source from stdin or a string)
*/
/// The name used for source code that doesn't originate in a file
/// (e.g. source from stdin or a string)
pub fn anon_src() -> String {
"<anon>".to_string()
}

View File

@ -325,15 +325,14 @@ pub enum TransBindingMode {
TrByRef,
}
/**
* Information about a pattern binding:
* - `llmatch` is a pointer to a stack slot. The stack slot contains a
* pointer into the value being matched. Hence, llmatch has type `T**`
* where `T` is the value being matched.
* - `trmode` is the trans binding mode
* - `id` is the node id of the binding
* - `ty` is the Rust type of the binding */
#[deriving(Clone)]
/// Information about a pattern binding:
/// - `llmatch` is a pointer to a stack slot. The stack slot contains a
/// pointer into the value being matched. Hence, llmatch has type `T**`
/// where `T` is the value being matched.
/// - `trmode` is the trans binding mode
/// - `id` is the node id of the binding
/// - `ty` is the Rust type of the binding
#[deriving(Clone)]
pub struct BindingInfo<'tcx> {
pub llmatch: ValueRef,
pub trmode: TransBindingMode,
@ -350,12 +349,10 @@ struct ArmData<'p, 'blk, 'tcx: 'blk> {
bindings_map: BindingsMap<'tcx>
}
/**
* Info about Match.
* If all `pats` are matched then arm `data` will be executed.
* As we proceed `bound_ptrs` are filled with pointers to values to be bound,
* these pointers are stored in llmatch variables just before executing `data` arm.
*/
/// Info about Match.
/// If all `pats` are matched then arm `data` will be executed.
/// As we proceed `bound_ptrs` are filled with pointers to values to be bound,
/// these pointers are stored in llmatch variables just before executing `data` arm.
struct Match<'a, 'p: 'a, 'blk: 'a, 'tcx: 'blk> {
pats: Vec<&'p ast::Pat>,
data: &'a ArmData<'p, 'blk, 'tcx>,

View File

@ -79,46 +79,38 @@ type Hint = attr::ReprAttr;
pub enum Repr<'tcx> {
/// C-like enums; basically an int.
CEnum(IntType, Disr, Disr), // discriminant range (signedness based on the IntType)
/**
* Single-case variants, and structs/tuples/records.
*
* Structs with destructors need a dynamic destroyedness flag to
* avoid running the destructor too many times; this is included
* in the `Struct` if present.
*/
/// Single-case variants, and structs/tuples/records.
///
/// Structs with destructors need a dynamic destroyedness flag to
/// avoid running the destructor too many times; this is included
/// in the `Struct` if present.
Univariant(Struct<'tcx>, bool),
/**
* General-case enums: for each case there is a struct, and they
* all start with a field for the discriminant.
*
* Types with destructors need a dynamic destroyedness flag to
* avoid running the destructor too many times; the last argument
* indicates whether such a flag is present.
*/
/// General-case enums: for each case there is a struct, and they
/// all start with a field for the discriminant.
///
/// Types with destructors need a dynamic destroyedness flag to
/// avoid running the destructor too many times; the last argument
/// indicates whether such a flag is present.
General(IntType, Vec<Struct<'tcx>>, bool),
/**
* Two cases distinguished by a nullable pointer: the case with discriminant
* `nndiscr` must have single field which is known to be nonnull due to its type.
* The other case is known to be zero sized. Hence we represent the enum
* as simply a nullable pointer: if not null it indicates the `nndiscr` variant,
* otherwise it indicates the other case.
*/
/// Two cases distinguished by a nullable pointer: the case with discriminant
/// `nndiscr` must have single field which is known to be nonnull due to its type.
/// The other case is known to be zero sized. Hence we represent the enum
/// as simply a nullable pointer: if not null it indicates the `nndiscr` variant,
/// otherwise it indicates the other case.
RawNullablePointer {
nndiscr: Disr,
nnty: Ty<'tcx>,
nullfields: Vec<Ty<'tcx>>
},
/**
* Two cases distinguished by a nullable pointer: the case with discriminant
* `nndiscr` is represented by the struct `nonnull`, where the `ptrfield`th
* field is known to be nonnull due to its type; if that field is null, then
* it represents the other case, which is inhabited by at most one value
* (and all other fields are undefined/unused).
*
* For example, `std::option::Option` instantiated at a safe pointer type
* is represented such that `None` is a null pointer and `Some` is the
* identity function.
*/
/// Two cases distinguished by a nullable pointer: the case with discriminant
/// `nndiscr` is represented by the struct `nonnull`, where the `ptrfield`th
/// field is known to be nonnull due to its type; if that field is null, then
/// it represents the other case, which is inhabited by at most one value
/// (and all other fields are undefined/unused).
///
/// For example, `std::option::Option` instantiated at a safe pointer type
/// is represented such that `None` is a null pointer and `Some` is the
/// identity function.
StructWrappedNullablePointer {
nonnull: Struct<'tcx>,
nndiscr: Disr,
@ -139,11 +131,9 @@ pub struct Struct<'tcx> {
pub fields: Vec<Ty<'tcx>>
}
/**
* Convenience for `represent_type`. There should probably be more or
* these, for places in trans where the `Ty` isn't directly
* available.
*/
/// Convenience for `represent_type`. There should probably be more or
/// these, for places in trans where the `Ty` isn't directly
/// available.
pub fn represent_node<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
node: ast::NodeId) -> Rc<Repr<'tcx>> {
represent_type(bcx.ccx(), node_id_type(bcx, node))
@ -514,16 +504,14 @@ fn ensure_enum_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
/**
* LLVM-level types are a little complicated.
*
* C-like enums need to be actual ints, not wrapped in a struct,
* because that changes the ABI on some platforms (see issue #10308).
*
* For nominal types, in some cases, we need to use LLVM named structs
* and fill in the actual contents in a second pass to prevent
* unbounded recursion; see also the comments in `trans::type_of`.
*/
/// LLVM-level types are a little complicated.
///
/// C-like enums need to be actual ints, not wrapped in a struct,
/// because that changes the ABI on some platforms (see issue #10308).
///
/// For nominal types, in some cases, we need to use LLVM named structs
/// and fill in the actual contents in a second pass to prevent
/// unbounded recursion; see also the comments in `trans::type_of`.
pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>) -> Type {
generic_type_of(cx, r, None, false, false)
}
@ -620,12 +608,10 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
}
}
/**
* Obtain a representation of the discriminant sufficient to translate
* destructuring; this may or may not involve the actual discriminant.
*
* This should ideally be less tightly tied to `_match`.
*/
/// Obtain a representation of the discriminant sufficient to translate
/// destructuring; this may or may not involve the actual discriminant.
///
/// This should ideally be less tightly tied to `_match`.
pub fn trans_switch<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
r: &Repr<'tcx>, scrutinee: ValueRef)
-> (_match::BranchKind, Option<ValueRef>) {
@ -713,12 +699,10 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
}
}
/**
* Yield information about how to dispatch a case of the
* discriminant-like value returned by `trans_switch`.
*
* This should ideally be less tightly tied to `_match`.
*/
/// Yield information about how to dispatch a case of the
/// discriminant-like value returned by `trans_switch`.
///
/// This should ideally be less tightly tied to `_match`.
pub fn trans_case<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr, discr: Disr)
-> _match::OptResult<'blk, 'tcx> {
match *r {
@ -741,10 +725,8 @@ pub fn trans_case<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr, discr: Disr)
}
}
/**
* Set the discriminant for a new value of the given case of the given
* representation.
*/
/// Set the discriminant for a new value of the given case of the given
/// representation.
pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
val: ValueRef, discr: Disr) {
match *r {
@ -799,10 +781,8 @@ fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
}
}
/**
* The number of fields in a given case; for use when obtaining this
* information from the type or definition is less convenient.
*/
/// The number of fields in a given case; for use when obtaining this
/// information from the type or definition is less convenient.
pub fn num_args(r: &Repr, discr: Disr) -> uint {
match *r {
CEnum(..) => 0,
@ -946,27 +926,25 @@ pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, r: &Repr<'tcx
}
}
/**
* Construct a constant value, suitable for initializing a
* GlobalVariable, given a case and constant values for its fields.
* Note that this may have a different LLVM type (and different
* alignment!) from the representation's `type_of`, so it needs a
* pointer cast before use.
*
* The LLVM type system does not directly support unions, and only
* pointers can be bitcast, so a constant (and, by extension, the
* GlobalVariable initialized by it) will have a type that can vary
* depending on which case of an enum it is.
*
* To understand the alignment situation, consider `enum E { V64(u64),
* V32(u32, u32) }` on Windows. The type has 8-byte alignment to
* accommodate the u64, but `V32(x, y)` would have LLVM type `{i32,
* i32, i32}`, which is 4-byte aligned.
*
* Currently the returned value has the same size as the type, but
* this could be changed in the future to avoid allocating unnecessary
* space after values of shorter-than-maximum cases.
*/
/// Construct a constant value, suitable for initializing a
/// GlobalVariable, given a case and constant values for its fields.
/// Note that this may have a different LLVM type (and different
/// alignment!) from the representation's `type_of`, so it needs a
/// pointer cast before use.
///
/// The LLVM type system does not directly support unions, and only
/// pointers can be bitcast, so a constant (and, by extension, the
/// GlobalVariable initialized by it) will have a type that can vary
/// depending on which case of an enum it is.
///
/// To understand the alignment situation, consider `enum E { V64(u64),
/// V32(u32, u32) }` on Windows. The type has 8-byte alignment to
/// accommodate the u64, but `V32(x, y)` would have LLVM type `{i32,
/// i32, i32}`, which is 4-byte aligned.
///
/// Currently the returned value has the same size as the type, but
/// this could be changed in the future to avoid allocating unnecessary
/// space after values of shorter-than-maximum cases.
pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr: Disr,
vals: &[ValueRef]) -> ValueRef {
match *r {
@ -1019,9 +997,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
}
}
/**
* Compute struct field offsets relative to struct begin.
*/
/// Compute struct field offsets relative to struct begin.
fn compute_struct_field_offsets<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
st: &Struct<'tcx>) -> Vec<u64> {
let mut offsets = vec!();
@ -1040,16 +1016,14 @@ fn compute_struct_field_offsets<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
offsets
}
/**
* Building structs is a little complicated, because we might need to
* insert padding if a field's value is less aligned than its type.
*
* Continuing the example from `trans_const`, a value of type `(u32,
* E)` should have the `E` at offset 8, but if that field's
* initializer is 4-byte aligned then simply translating the tuple as
* a two-element struct will locate it at offset 4, and accesses to it
* will read the wrong memory.
*/
/// Building structs is a little complicated, because we might need to
/// insert padding if a field's value is less aligned than its type.
///
/// Continuing the example from `trans_const`, a value of type `(u32,
/// E)` should have the `E` at offset 8, but if that field's
/// initializer is 4-byte aligned then simply translating the tuple as
/// a two-element struct will locate it at offset 4, and accesses to it
/// will read the wrong memory.
fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
st: &Struct<'tcx>, vals: &[ValueRef])
-> Vec<ValueRef> {
@ -1130,13 +1104,11 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
}
}
/**
* Extract a field of a constant value, as appropriate for its
* representation.
*
* (Not to be confused with `common::const_get_elt`, which operates on
* raw LLVM-level structs and arrays.)
*/
/// Extract a field of a constant value, as appropriate for its
/// representation.
///
/// (Not to be confused with `common::const_get_elt`, which operates on
/// raw LLVM-level structs and arrays.)
pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
_discr: Disr, ix: uint) -> ValueRef {
match *r {

View File

@ -17,9 +17,7 @@ pub struct BasicBlock(pub BasicBlockRef);
pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
/**
* Wrapper for LLVM BasicBlockRef
*/
/// Wrapper for LLVM BasicBlockRef
impl BasicBlock {
pub fn get(&self) -> BasicBlockRef {
let BasicBlock(v) = *self; v

View File

@ -31,12 +31,10 @@ use util::ppaux::{ty_to_string};
use std::fmt;
use syntax::ast;
/**
* A `Datum` encapsulates the result of evaluating an expression. It
* describes where the value is stored, what Rust type the value has,
* whether it is addressed by reference, and so forth. Please refer
* the section on datums in `doc.rs` for more details.
*/
/// A `Datum` encapsulates the result of evaluating an expression. It
/// describes where the value is stored, what Rust type the value has,
/// whether it is addressed by reference, and so forth. Please refer
/// the section on datums in `doc.rs` for more details.
#[deriving(Clone)]
pub struct Datum<'tcx, K> {
/// The llvm value. This is either a pointer to the Rust value or
@ -190,25 +188,19 @@ fn add_rvalue_clean<'a, 'tcx>(mode: RvalueMode,
pub trait KindOps {
/**
* Take appropriate action after the value in `datum` has been
* stored to a new location.
*/
/// Take appropriate action after the value in `datum` has been
/// stored to a new location.
fn post_store<'blk, 'tcx>(&self,
bcx: Block<'blk, 'tcx>,
val: ValueRef,
ty: Ty<'tcx>)
-> Block<'blk, 'tcx>;
/**
* True if this mode is a reference mode, meaning that the datum's
* val field is a pointer to the actual value
*/
/// True if this mode is a reference mode, meaning that the datum's
/// val field is a pointer to the actual value
fn is_by_ref(&self) -> bool;
/**
* Converts to an Expr kind
*/
/// Converts to an Expr kind
fn to_expr_kind(self) -> Expr;
}
@ -361,14 +353,12 @@ impl<'tcx> Datum<'tcx, Rvalue> {
}
}
/**
* Methods suitable for "expr" datums that could be either lvalues or
* rvalues. These include coercions into lvalues/rvalues but also a number
* of more general operations. (Some of those operations could be moved to
* the more general `impl<K> Datum<K>`, but it's convenient to have them
* here since we can `match self.kind` rather than having to implement
* generic methods in `KindOps`.)
*/
/// Methods suitable for "expr" datums that could be either lvalues or
/// rvalues. These include coercions into lvalues/rvalues but also a number
/// of more general operations. (Some of those operations could be moved to
/// the more general `impl<K> Datum<K>`, but it's convenient to have them
/// here since we can `match self.kind` rather than having to implement
/// generic methods in `KindOps`.)
impl<'tcx> Datum<'tcx, Expr> {
fn match_kind<R>(self,
if_lvalue: |Datum<'tcx, Lvalue>| -> R,
@ -494,12 +484,10 @@ impl<'tcx> Datum<'tcx, Expr> {
}
/**
* Methods suitable only for lvalues. These include the various
* operations to extract components out of compound data structures,
* such as extracting the field from a struct or a particular element
* from an array.
*/
/// Methods suitable only for lvalues. These include the various
/// operations to extract components out of compound data structures,
/// such as extracting the field from a struct or a particular element
/// from an array.
impl<'tcx> Datum<'tcx, Lvalue> {
pub fn to_llref(self) -> ValueRef {
/*!
@ -542,9 +530,7 @@ impl<'tcx> Datum<'tcx, Lvalue> {
}
}
/**
* Generic methods applicable to any sort of datum.
*/
/// Generic methods applicable to any sort of datum.
impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> {
pub fn new(val: ValueRef, ty: Ty<'tcx>, kind: K) -> Datum<'tcx, K> {
Datum { val: val, ty: ty, kind: kind }

View File

@ -1377,14 +1377,12 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
})
}
/**
* Information that `trans_adt` needs in order to fill in the fields
* of a struct copied from a base struct (e.g., from an expression
* like `Foo { a: b, ..base }`.
*
* Note that `fields` may be empty; the base expression must always be
* evaluated for side-effects.
*/
/// Information that `trans_adt` needs in order to fill in the fields
/// of a struct copied from a base struct (e.g., from an expression
/// like `Foo { a: b, ..base }`.
///
/// Note that `fields` may be empty; the base expression must always be
/// evaluated for side-effects.
pub struct StructBaseInfo<'a, 'tcx> {
/// The base expression; will be evaluated after all explicit fields.
expr: &'a ast::Expr,
@ -1392,16 +1390,14 @@ pub struct StructBaseInfo<'a, 'tcx> {
fields: Vec<(uint, Ty<'tcx>)>
}
/**
* Constructs an ADT instance:
*
* - `fields` should be a list of field indices paired with the
* expression to store into that field. The initializers will be
* evaluated in the order specified by `fields`.
*
* - `optbase` contains information on the base struct (if any) from
* which remaining fields are copied; see comments on `StructBaseInfo`.
*/
/// Constructs an ADT instance:
///
/// - `fields` should be a list of field indices paired with the
/// expression to store into that field. The initializers will be
/// evaluated in the order specified by `fields`.
///
/// - `optbase` contains information on the base struct (if any) from
/// which remaining fields are copied; see comments on `StructBaseInfo`.
pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
ty: Ty<'tcx>,
discr: ty::Disr,

View File

@ -46,12 +46,10 @@ use syntax::codemap::DUMMY_SP;
// drop_glue pointer, size, align.
static VTABLE_OFFSET: uint = 3;
/**
The main "translation" pass for methods. Generates code
for non-monomorphized methods only. Other methods will
be generated once they are invoked with specific type parameters,
see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/
/// The main "translation" pass for methods. Generates code
/// for non-monomorphized methods only. Other methods will
/// be generated once they are invoked with specific type parameters,
/// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
pub fn trans_impl(ccx: &CrateContext,
name: ast::Ident,
impl_items: &[ast::ImplItem],

View File

@ -35,9 +35,7 @@ macro_rules! ty (
($e:expr) => ( Type::from_ref(unsafe { $e }))
)
/**
* Wrapper for LLVM TypeRef
*/
/// Wrapper for LLVM TypeRef
impl Type {
#[inline(always)]
pub fn from_ref(r: TypeRef) -> Type {

View File

@ -25,9 +25,7 @@ macro_rules! opt_val ( ($e:expr) => (
}
))
/**
* Wrapper for LLVM ValueRef
*/
/// Wrapper for LLVM ValueRef
impl Value {
/// Returns the native ValueRef
pub fn get(&self) -> ValueRef {
@ -127,9 +125,7 @@ impl Value {
pub struct Use(UseRef);
/**
* Wrapper for LLVM UseRef
*/
/// Wrapper for LLVM UseRef
impl Use {
pub fn get(&self) -> UseRef {
let Use(v) = *self; v

View File

@ -64,21 +64,19 @@ pub trait ToBase64 for Sized? {
}
impl ToBase64 for [u8] {
/**
* Turn a vector of `u8` bytes into a base64 string.
*
* # Example
*
* ```rust
* extern crate serialize;
* use serialize::base64::{ToBase64, STANDARD};
*
* fn main () {
* let str = [52,32].to_base64(STANDARD);
* println!("base 64 output: {}", str);
* }
* ```
*/
/// Turn a vector of `u8` bytes into a base64 string.
///
/// # Example
///
/// ```rust
/// extern crate serialize;
/// use serialize::base64::{ToBase64, STANDARD};
///
/// fn main () {
/// let str = [52,32].to_base64(STANDARD);
/// println!("base 64 output: {}", str);
/// }
/// ```
fn to_base64(&self, config: Config) -> String {
let bytes = match config.char_set {
Standard => STANDARD_CHARS,
@ -194,34 +192,32 @@ impl error::Error for FromBase64Error {
}
impl FromBase64 for str {
/**
* Convert any base64 encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `String::from_utf8` function to turn a `Vec<u8>` into a
* string with characters corresponding to those values.
*
* # Example
*
* This converts a string literal to base64 and back.
*
* ```rust
* extern crate serialize;
* use serialize::base64::{ToBase64, FromBase64, STANDARD};
*
* fn main () {
* let hello_str = b"Hello, World".to_base64(STANDARD);
* println!("base64 output: {}", hello_str);
* let res = hello_str.as_slice().from_base64();
* if res.is_ok() {
* let opt_bytes = String::from_utf8(res.unwrap());
* if opt_bytes.is_ok() {
* println!("decoded from base64: {}", opt_bytes.unwrap());
* }
* }
* }
* ```
*/
/// Convert any base64 encoded string (literal, `@`, `&`, or `~`)
/// to the byte values it encodes.
///
/// You can use the `String::from_utf8` function to turn a `Vec<u8>` into a
/// string with characters corresponding to those values.
///
/// # Example
///
/// This converts a string literal to base64 and back.
///
/// ```rust
/// extern crate serialize;
/// use serialize::base64::{ToBase64, FromBase64, STANDARD};
///
/// fn main () {
/// let hello_str = b"Hello, World".to_base64(STANDARD);
/// println!("base64 output: {}", hello_str);
/// let res = hello_str.as_slice().from_base64();
/// if res.is_ok() {
/// let opt_bytes = String::from_utf8(res.unwrap());
/// if opt_bytes.is_ok() {
/// println!("decoded from base64: {}", opt_bytes.unwrap());
/// }
/// }
/// }
/// ```
#[inline]
fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
self.as_bytes().from_base64()

View File

@ -27,21 +27,19 @@ pub trait ToHex for Sized? {
static CHARS: &'static[u8] = b"0123456789abcdef";
impl ToHex for [u8] {
/**
* Turn a vector of `u8` bytes into a hexadecimal string.
*
* # Example
*
* ```rust
* extern crate serialize;
* use serialize::hex::ToHex;
*
* fn main () {
* let str = [52,32].to_hex();
* println!("{}", str);
* }
* ```
*/
/// Turn a vector of `u8` bytes into a hexadecimal string.
///
/// # Example
///
/// ```rust
/// extern crate serialize;
/// use serialize::hex::ToHex;
///
/// fn main () {
/// let str = [52,32].to_hex();
/// println!("{}", str);
/// }
/// ```
fn to_hex(&self) -> String {
let mut v = Vec::with_capacity(self.len() * 2);
for &byte in self.iter() {
@ -95,31 +93,29 @@ impl error::Error for FromHexError {
impl FromHex for str {
/**
* Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `String::from_utf8` function to turn a
* `Vec<u8>` into a string with characters corresponding to those values.
*
* # Example
*
* This converts a string literal to hexadecimal and back.
*
* ```rust
* extern crate serialize;
* use serialize::hex::{FromHex, ToHex};
*
* fn main () {
* let hello_str = "Hello, World".as_bytes().to_hex();
* println!("{}", hello_str);
* let bytes = hello_str.as_slice().from_hex().unwrap();
* println!("{}", bytes);
* let result_str = String::from_utf8(bytes).unwrap();
* println!("{}", result_str);
* }
* ```
*/
/// Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`)
/// to the byte values it encodes.
///
/// You can use the `String::from_utf8` function to turn a
/// `Vec<u8>` into a string with characters corresponding to those values.
///
/// # Example
///
/// This converts a string literal to hexadecimal and back.
///
/// ```rust
/// extern crate serialize;
/// use serialize::hex::{FromHex, ToHex};
///
/// fn main () {
/// let hello_str = "Hello, World".as_bytes().to_hex();
/// println!("{}", hello_str);
/// let bytes = hello_str.as_slice().from_hex().unwrap();
/// println!("{}", bytes);
/// let result_str = String::from_utf8(bytes).unwrap();
/// println!("{}", result_str);
/// }
/// ```
fn from_hex(&self) -> Result<Vec<u8>, FromHexError> {
// This may be an overestimate if there is any whitespace
let mut b = Vec::with_capacity(self.len() / 2);

View File

@ -67,31 +67,32 @@ pub enum SignFormat {
SignAll,
}
/**
* Converts an integral number to its string representation as a byte vector.
* This is meant to be a common base implementation for all integral string
* conversion functions like `to_string()` or `to_str_radix()`.
*
* # Arguments
* - `num` - The number to convert. Accepts any number that
* implements the numeric traits.
* - `radix` - Base to use. Accepts only the values 2-36.
* - `sign` - How to emit the sign. Options are:
* - `SignNone`: No sign at all. Basically emits `abs(num)`.
* - `SignNeg`: Only `-` on negative values.
* - `SignAll`: Both `+` on positive, and `-` on negative numbers.
* - `f` - a callback which will be invoked for each ascii character
* which composes the string representation of this integer
*
* # Return value
* A tuple containing the byte vector, and a boolean flag indicating
* whether it represents a special value like `inf`, `-inf`, `NaN` or not.
* It returns a tuple because there can be ambiguity between a special value
* and a number representation at higher bases.
*
* # Panics
* - Panics if `radix` < 2 or `radix` > 36.
*/
/// Converts an integral number to its string representation as a byte vector.
/// This is meant to be a common base implementation for all integral string
/// conversion functions like `to_string()` or `to_str_radix()`.
///
/// # Arguments
///
/// - `num` - The number to convert. Accepts any number that
/// implements the numeric traits.
/// - `radix` - Base to use. Accepts only the values 2-36.
/// - `sign` - How to emit the sign. Options are:
/// - `SignNone`: No sign at all. Basically emits `abs(num)`.
/// - `SignNeg`: Only `-` on negative values.
/// - `SignAll`: Both `+` on positive, and `-` on negative numbers.
/// - `f` - a callback which will be invoked for each ascii character
/// which composes the string representation of this integer
///
/// # Return value
///
/// A tuple containing the byte vector, and a boolean flag indicating
/// whether it represents a special value like `inf`, `-inf`, `NaN` or not.
/// It returns a tuple because there can be ambiguity between a special value
/// and a number representation at higher bases.
///
/// # Panics
///
/// - Panics if `radix` < 2 or `radix` > 36.
fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
assert!(2 <= radix && radix <= 36);

View File

@ -788,18 +788,16 @@ pub fn homedir() -> Option<Path> {
_homedir()
}
/**
* Returns the path to a temporary directory.
*
* On Unix, returns the value of the 'TMPDIR' environment variable if it is
* set, otherwise for non-Android it returns '/tmp'. If Android, since there
* is no global temporary folder (it is usually allocated per-app), we return
* '/data/local/tmp'.
*
* On Windows, returns the value of, in order, the 'TMP', 'TEMP',
* 'USERPROFILE' environment variable if any are set and not the empty
* string. Otherwise, tmpdir returns the path to the Windows directory.
*/
/// Returns the path to a temporary directory.
///
/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
/// is no global temporary folder (it is usually allocated per-app), we return
/// '/data/local/tmp'.
///
/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
/// 'USERPROFILE' environment variable if any are set and not the empty
/// string. Otherwise, tmpdir returns the path to the Windows directory.
pub fn tmpdir() -> Path {
return lookup();
@ -933,16 +931,14 @@ pub fn last_os_error() -> String {
static EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
/**
* Sets the process exit code
*
* Sets the exit code returned by the process if all supervised tasks
* terminate successfully (without panicking). If the current root task panics
* and is supervised by the scheduler then any user-specified exit status is
* ignored and the process exits with the default panic status.
*
* Note that this is not synchronized against modifications of other threads.
*/
/// Sets the process exit code
///
/// Sets the exit code returned by the process if all supervised tasks
/// terminate successfully (without panicking). If the current root task panics
/// and is supervised by the scheduler then any user-specified exit status is
/// ignored and the process exits with the default panic status.
///
/// Note that this is not synchronized against modifications of other threads.
pub fn set_exit_status(code: int) {
EXIT_STATUS.store(code, SeqCst)
}
@ -963,11 +959,9 @@ unsafe fn load_argc_and_argv(argc: int,
})
}
/**
* Returns the command line arguments
*
* Returns a list of the command line arguments.
*/
/// Returns the command line arguments
///
/// Returns a list of the command line arguments.
#[cfg(target_os = "macos")]
fn real_args_as_bytes() -> Vec<Vec<u8>> {
unsafe {

View File

@ -29,9 +29,7 @@ use rustrt::task::Task;
use super::raw;
/****************************************************************************
* Poisoning helpers
****************************************************************************/
// Poisoning helpers
struct PoisonOnFail<'a> {
flag: &'a mut bool,
@ -67,9 +65,7 @@ impl<'a> Drop for PoisonOnFail<'a> {
}
}
/****************************************************************************
* Condvar
****************************************************************************/
// Condvar
enum Inner<'a> {
InnerMutex(raw::MutexGuard<'a>),
@ -147,10 +143,6 @@ impl<'a> Condvar<'a> {
}
}
/****************************************************************************
* Mutex
****************************************************************************/
/// A wrapper type which provides synchronized access to the underlying data, of
/// type `T`. A mutex always provides exclusive access, and concurrent requests
/// will block while the mutex is already locked.
@ -249,10 +241,6 @@ impl<'a, T: Send> DerefMut<T> for MutexGuard<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
}
/****************************************************************************
* R/W lock protected lock
****************************************************************************/
/// A dual-mode reader-writer lock. The data can be accessed mutably or
/// immutably, and immutably-accessing tasks may run concurrently.
///
@ -387,10 +375,6 @@ impl<'a, T: Send + Sync> DerefMut<T> for RWLockWriteGuard<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
}
/****************************************************************************
* Barrier
****************************************************************************/
/// A barrier enables multiple tasks to synchronize the beginning
/// of some computation.
///
@ -452,10 +436,6 @@ impl Barrier {
}
}
/****************************************************************************
* Tests
****************************************************************************/
#[cfg(test)]
mod tests {
use prelude::*;
@ -795,9 +775,6 @@ mod tests {
}
}
/************************************************************************
* Barrier tests
************************************************************************/
#[test]
fn test_barrier() {
let barrier = Arc::new(Barrier::new(10));

View File

@ -32,10 +32,6 @@ use vec::Vec;
use super::mutex;
use comm::{Receiver, Sender, channel};
/****************************************************************************
* Internals
****************************************************************************/
// Each waiting task receives on one of these.
type WaitEnd = Receiver<()>;
type SignalEnd = Sender<()>;
@ -353,10 +349,6 @@ struct SemCondGuard<'a> {
cvar: Condvar<'a>,
}
/****************************************************************************
* Semaphores
****************************************************************************/
/// A counting, blocking, bounded-waiting semaphore.
pub struct Semaphore {
sem: Sem<()>,
@ -394,10 +386,6 @@ impl Semaphore {
}
}
/****************************************************************************
* Mutexes
****************************************************************************/
/// A blocking, bounded-waiting, mutual exclusion lock with an associated
/// FIFO condition variable.
///
@ -441,10 +429,6 @@ impl Mutex {
}
}
/****************************************************************************
* Reader-writer locks
****************************************************************************/
// NB: Wikipedia - Readers-writers_problem#The_third_readers-writers_problem
/// A blocking, no-starvation, reader-writer lock with an associated condvar.
@ -618,10 +602,6 @@ impl<'a> Drop for RWLockReadGuard<'a> {
}
}
/****************************************************************************
* Tests
****************************************************************************/
#[cfg(test)]
mod tests {
pub use self::RWLockMode::*;
@ -634,9 +614,6 @@ mod tests {
use result;
use task;
/************************************************************************
* Semaphore tests
************************************************************************/
#[test]
fn test_sem_acquire_release() {
let s = Semaphore::new(1);
@ -644,16 +621,19 @@ mod tests {
s.release();
s.acquire();
}
#[test]
fn test_sem_basic() {
let s = Semaphore::new(1);
let _g = s.access();
}
#[test]
#[should_fail]
fn test_sem_basic2() {
Semaphore::new(-1);
}
#[test]
fn test_sem_as_mutex() {
let s = Arc::new(Semaphore::new(1));
@ -665,6 +645,7 @@ mod tests {
let _g = s.access();
for _ in range(0u, 5) { task::deschedule(); }
}
#[test]
fn test_sem_as_cvar() {
/* Child waits and parent signals */
@ -691,6 +672,7 @@ mod tests {
s.acquire();
tx.send(());
}
#[test]
fn test_sem_multi_resource() {
// Parent and child both get in the critical section at the same
@ -708,6 +690,7 @@ mod tests {
tx2.send(());
let _ = rx1.recv();
}
#[test]
fn test_sem_runtime_friendly_blocking() {
// Force the runtime to schedule two threads on the same sched_loop.
@ -727,9 +710,7 @@ mod tests {
}
rx.recv(); // wait for child to be done
}
/************************************************************************
* Mutex tests
************************************************************************/
#[test]
fn test_mutex_lock() {
// Unsafely achieve shared state, and do the textbook
@ -761,6 +742,7 @@ mod tests {
}
}
}
#[test]
fn test_mutex_cond_wait() {
let m = Arc::new(Mutex::new());
@ -820,14 +802,17 @@ mod tests {
// wait until all children wake up
for rx in rxs.iter_mut() { rx.recv(); }
}
#[test]
fn test_mutex_cond_broadcast() {
test_mutex_cond_broadcast_helper(12);
}
#[test]
fn test_mutex_cond_broadcast_none() {
test_mutex_cond_broadcast_helper(0);
}
#[test]
fn test_mutex_cond_no_waiter() {
let m = Arc::new(Mutex::new());
@ -838,6 +823,7 @@ mod tests {
let lock = m2.lock();
assert!(!lock.cond.signal());
}
#[test]
fn test_mutex_killed_simple() {
use any::Any;
@ -854,6 +840,7 @@ mod tests {
// child task must have finished by the time try returns
drop(m.lock());
}
#[test]
fn test_mutex_cond_signal_on_0() {
// Tests that signal_on(0) is equivalent to signal().
@ -866,6 +853,7 @@ mod tests {
});
lock.cond.wait();
}
#[test]
fn test_mutex_no_condvars() {
let result = task::try(proc() {
@ -884,11 +872,10 @@ mod tests {
});
assert!(result.is_err());
}
/************************************************************************
* Reader/writer lock tests
************************************************************************/
#[cfg(test)]
pub enum RWLockMode { Read, Write, Downgrade, DowngradeRead }
#[cfg(test)]
fn lock_rwlock_in_mode(x: &Arc<RWLock>, mode: RWLockMode, blk: ||) {
match mode {
@ -898,6 +885,7 @@ mod tests {
DowngradeRead => { let _g = x.write().downgrade(); blk() }
}
}
#[cfg(test)]
fn test_rwlock_exclusion(x: Arc<RWLock>,
mode1: RWLockMode,
@ -934,6 +922,7 @@ mod tests {
}
}
}
#[test]
fn test_rwlock_readers_wont_modify_the_data() {
test_rwlock_exclusion(Arc::new(RWLock::new()), Read, Write);
@ -943,6 +932,7 @@ mod tests {
test_rwlock_exclusion(Arc::new(RWLock::new()), Write, DowngradeRead);
test_rwlock_exclusion(Arc::new(RWLock::new()), DowngradeRead, Write);
}
#[test]
fn test_rwlock_writers_and_writers() {
test_rwlock_exclusion(Arc::new(RWLock::new()), Write, Write);
@ -950,6 +940,7 @@ mod tests {
test_rwlock_exclusion(Arc::new(RWLock::new()), Downgrade, Write);
test_rwlock_exclusion(Arc::new(RWLock::new()), Downgrade, Downgrade);
}
#[cfg(test)]
fn test_rwlock_handshake(x: Arc<RWLock>,
mode1: RWLockMode,
@ -982,6 +973,7 @@ mod tests {
rx1.recv();
})
}
#[test]
fn test_rwlock_readers_and_readers() {
test_rwlock_handshake(Arc::new(RWLock::new()), Read, Read, false);
@ -991,6 +983,7 @@ mod tests {
test_rwlock_handshake(Arc::new(RWLock::new()), Read, DowngradeRead, true);
// Two downgrade_reads can never both end up reading at the same time.
}
#[test]
fn test_rwlock_downgrade_unlock() {
// Tests that downgrade can unlock the lock in both modes
@ -1001,12 +994,14 @@ mod tests {
lock_rwlock_in_mode(&y, DowngradeRead, || { });
test_rwlock_exclusion(y, Write, Write);
}
#[test]
fn test_rwlock_read_recursive() {
let x = RWLock::new();
let _g1 = x.read();
let _g2 = x.read();
}
#[test]
fn test_rwlock_cond_wait() {
// As test_mutex_cond_wait above.
@ -1040,6 +1035,7 @@ mod tests {
rx.recv(); // Wait until child wakes up
drop(x.read()); // Just for good measure
}
#[cfg(test)]
fn test_rwlock_cond_broadcast_helper(num_waiters: uint) {
// Much like the mutex broadcast test. Downgrade-enabled.
@ -1073,11 +1069,13 @@ mod tests {
// wait until all children wake up
for rx in rxs.iter_mut() { let _ = rx.recv(); }
}
#[test]
fn test_rwlock_cond_broadcast() {
test_rwlock_cond_broadcast_helper(0);
test_rwlock_cond_broadcast_helper(12);
}
#[cfg(test)]
fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
use any::Any;
@ -1095,22 +1093,27 @@ mod tests {
// child task must have finished by the time try returns
lock_rwlock_in_mode(&x, mode2, || { })
}
#[test]
fn test_rwlock_reader_killed_writer() {
rwlock_kill_helper(Read, Write);
}
#[test]
fn test_rwlock_writer_killed_reader() {
rwlock_kill_helper(Write, Read);
}
#[test]
fn test_rwlock_reader_killed_reader() {
rwlock_kill_helper(Read, Read);
}
#[test]
fn test_rwlock_writer_killed_writer() {
rwlock_kill_helper(Write, Write);
}
#[test]
fn test_rwlock_kill_downgrader() {
rwlock_kill_helper(Downgrade, Read);

View File

@ -33,13 +33,11 @@ use string::String;
pub use sys_common::ProcessConfig;
/**
* A value representing a child process.
*
* The lifetime of this value is linked to the lifetime of the actual
* process - the Process destructor calls self.finish() which waits
* for the process to terminate.
*/
/// A value representing a child process.
///
/// The lifetime of this value is linked to the lifetime of the actual
/// process - the Process destructor calls self.finish() which waits
/// for the process to terminate.
pub struct Process {
/// The unique id of the process (this should never be negative).
pid: pid_t,
@ -263,16 +261,14 @@ impl Process {
}
}
/**
* Waits for a process to exit and returns the exit code, failing
* if there is no process with the specified id.
*
* Note that this is private to avoid race conditions on unix where if
* a user calls waitpid(some_process.get_id()) then some_process.finish()
* and some_process.destroy() and some_process.finalize() will then either
* operate on a none-existent process or, even worse, on a newer process
* with the same id.
*/
/// Waits for a process to exit and returns the exit code, failing
/// if there is no process with the specified id.
///
/// Note that this is private to avoid race conditions on unix where if
/// a user calls waitpid(some_process.get_id()) then some_process.finish()
/// and some_process.destroy() and some_process.finalize() will then either
/// operate on a none-existent process or, even worse, on a newer process
/// with the same id.
pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
use libc::types::os::arch::extra::DWORD;
use libc::consts::os::extra::{

View File

@ -83,12 +83,10 @@ impl Sub<CharPos,CharPos> for CharPos {
}
}
/**
Spans represent a region of code, used for error reporting. Positions in spans
are *absolute* positions from the beginning of the codemap, not positions
relative to FileMaps. Methods on the CodeMap can be used to relate spans back
to the original source.
*/
/// Spans represent a region of code, used for error reporting. Positions in spans
/// are *absolute* positions from the beginning of the codemap, not positions
/// relative to FileMaps. Methods on the CodeMap can be used to relate spans back
/// to the original source.
#[deriving(Clone, Show, Hash)]
pub struct Span {
pub lo: BytePos,

View File

@ -17,16 +17,12 @@ use parse::token::*;
use parse::token;
use ptr::P;
/**
*
* Quasiquoting works via token trees.
*
* This is registered as a set of expression syntax extension called quote!
* that lifts its argument token-tree to an AST representing the
* construction of the same token tree, with token::SubstNt interpreted
* as antiquotes (splices).
*
*/
//! Quasiquoting works via token trees.
//!
//! This is registered as a set of expression syntax extension called quote!
//! that lifts its argument token-tree to an AST representing the
//! construction of the same token tree, with token::SubstNt interpreted
//! as antiquotes (splices).
pub mod rt {
use ast;

View File

@ -421,13 +421,11 @@ macro_rules! declare_special_idents_and_keywords {(
)*
}
/**
* All the valid words that have meaning in the Rust language.
*
* Rust keywords are either 'strict' or 'reserved'. Strict keywords may not
* appear as identifiers at all. Reserved keywords are not used anywhere in
* the language and may not appear as identifiers.
*/
/// All the valid words that have meaning in the Rust language.
///
/// Rust keywords are either 'strict' or 'reserved'. Strict keywords may not
/// appear as identifiers at all. Reserved keywords are not used anywhere in
/// the language and may not appear as identifiers.
pub mod keywords {
pub use self::Keyword::*;
use ast;

View File

@ -80,17 +80,15 @@ impl Variables {
}
}
/**
Expand a parameterized capability
# Arguments
* `cap` - string to expand
* `params` - vector of params for %p1 etc
* `vars` - Variables struct for %Pa etc
To be compatible with ncurses, `vars` should be the same between calls to `expand` for
multiple capabilities for the same terminal.
*/
/// Expand a parameterized capability
///
/// # Arguments
/// * `cap` - string to expand
/// * `params` - vector of params for %p1 etc
/// * `vars` - Variables struct for %Pa etc
///
/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
/// multiple capabilities for the same terminal.
pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
-> Result<Vec<u8> , String> {
let mut state = Nothing;

View File

@ -123,10 +123,8 @@ impl Sub<Timespec, Duration> for Timespec {
}
}
/**
* Returns the current time as a `timespec` containing the seconds and
* nanoseconds since 1970-01-01T00:00:00Z.
*/
/// Returns the current time as a `timespec` containing the seconds and
/// nanoseconds since 1970-01-01T00:00:00Z.
pub fn get_time() -> Timespec {
unsafe {
let (sec, nsec) = os_get_time();
@ -171,10 +169,8 @@ pub fn get_time() -> Timespec {
}
/**
* Returns the current value of a high-resolution performance counter
* in nanoseconds since an unspecified epoch.
*/
/// Returns the current value of a high-resolution performance counter
/// in nanoseconds since an unspecified epoch.
pub fn precise_time_ns() -> u64 {
return os_precise_time_ns();
@ -218,10 +214,8 @@ pub fn precise_time_ns() -> u64 {
}
/**
* Returns the current value of a high-resolution performance counter
* in seconds since an unspecified epoch.
*/
/// Returns the current value of a high-resolution performance counter
/// in seconds since an unspecified epoch.
pub fn precise_time_s() -> f64 {
return (precise_time_ns() as f64) / 1000000000.;
}
@ -346,12 +340,10 @@ impl Tm {
at_utc(self.to_timespec())
}
/**
* Returns a TmFmt that outputs according to the `asctime` format in ISO
* C, in the local timezone.
*
* Example: "Thu Jan 1 00:00:00 1970"
*/
/// Returns a TmFmt that outputs according to the `asctime` format in ISO
/// C, in the local timezone.
///
/// Example: "Thu Jan 1 00:00:00 1970"
pub fn ctime(&self) -> TmFmt {
TmFmt {
tm: self,
@ -359,12 +351,10 @@ impl Tm {
}
}
/**
* Returns a TmFmt that outputs according to the `asctime` format in ISO
* C.
*
* Example: "Thu Jan 1 00:00:00 1970"
*/
/// Returns a TmFmt that outputs according to the `asctime` format in ISO
/// C.
///
/// Example: "Thu Jan 1 00:00:00 1970"
pub fn asctime(&self) -> TmFmt {
TmFmt {
tm: self,
@ -380,12 +370,10 @@ impl Tm {
})
}
/**
* Returns a TmFmt that outputs according to RFC 822.
*
* local: "Thu, 22 Mar 2012 07:53:18 PST"
* utc: "Thu, 22 Mar 2012 14:53:18 GMT"
*/
/// Returns a TmFmt that outputs according to RFC 822.
///
/// local: "Thu, 22 Mar 2012 07:53:18 PST"
/// utc: "Thu, 22 Mar 2012 14:53:18 GMT"
pub fn rfc822(&self) -> TmFmt {
if self.tm_gmtoff == 0_i32 {
TmFmt {
@ -400,12 +388,10 @@ impl Tm {
}
}
/**
* Returns a TmFmt that outputs according to RFC 822 with Zulu time.
*
* local: "Thu, 22 Mar 2012 07:53:18 -0700"
* utc: "Thu, 22 Mar 2012 14:53:18 -0000"
*/
/// Returns a TmFmt that outputs according to RFC 822 with Zulu time.
///
/// local: "Thu, 22 Mar 2012 07:53:18 -0700"
/// utc: "Thu, 22 Mar 2012 14:53:18 -0000"
pub fn rfc822z(&self) -> TmFmt {
TmFmt {
tm: self,
@ -413,13 +399,11 @@ impl Tm {
}
}
/**
* Returns a TmFmt that outputs according to RFC 3339. RFC 3339 is
* compatible with ISO 8601.
*
* local: "2012-02-22T07:53:18-07:00"
* utc: "2012-02-22T14:53:18Z"
*/
/// Returns a TmFmt that outputs according to RFC 3339. RFC 3339 is
/// compatible with ISO 8601.
///
/// local: "2012-02-22T07:53:18-07:00"
/// utc: "2012-02-22T14:53:18Z"
pub fn rfc3339<'a>(&'a self) -> TmFmt {
TmFmt {
tm: self,