1
Fork 0

/** -> ///

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.
An interface for casting C-like enum to uint and back. /// A typically implementation is as below.
A typically implementation is as below. ///
/// ```{rust,ignore}
```{rust,ignore} /// #[repr(uint)]
#[repr(uint)] /// enum Foo {
enum Foo { /// A, B, C
A, B, C /// }
} ///
/// impl CLike for Foo {
impl CLike for Foo { /// fn to_uint(&self) -> uint {
fn to_uint(&self) -> uint { /// *self as uint
*self as uint /// }
} ///
/// fn from_uint(v: uint) -> Foo {
fn from_uint(v: uint) -> Foo { /// unsafe { mem::transmute(v) }
unsafe { mem::transmute(v) } /// }
} /// }
} /// ```
```
*/
pub trait CLike { pub trait CLike {
/// Converts a C-like enum to a `uint`. /// Converts a C-like enum to a `uint`.
fn to_uint(&self) -> 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
* The most general form of the `finally` functions. The function /// `try_fn` will be invoked first; whether or not it panics, the
* `try_fn` will be invoked first; whether or not it panics, the /// function `finally_fn` will be invoked next. The two parameters
* function `finally_fn` will be invoked next. The two parameters /// `mutate` and `drop` are used to thread state through the two
* `mutate` and `drop` are used to thread state through the two /// closures. `mutate` is used for any shared, mutable state that both
* closures. `mutate` is used for any shared, mutable state that both /// closures require access to; `drop` is used for any state that the
* closures require access to; `drop` is used for any state that the /// `try_fn` requires ownership of.
* `try_fn` requires ownership of. ///
* /// **WARNING:** While shared, mutable state between the try and finally
* **WARNING:** While shared, mutable state between the try and finally /// function is often necessary, one must be very careful; the `try`
* function is often necessary, one must be very careful; the `try` /// function could have panicked at any point, so the values of the shared
* function could have panicked at any point, so the values of the shared /// state may be inconsistent.
* state may be inconsistent. ///
* /// # Example
* # Example ///
* /// ```
* ``` /// use std::finally::try_finally;
* use std::finally::try_finally; ///
* /// struct State<'a> { buffer: &'a mut [u8], len: uint }
* struct State<'a> { buffer: &'a mut [u8], len: uint } /// # let mut buf = [];
* # let mut buf = []; /// let mut state = State { buffer: &mut buf, len: 0 };
* let mut state = State { buffer: &mut buf, len: 0 }; /// try_finally(
* try_finally( /// &mut state, (),
* &mut state, (), /// |state, ()| {
* |state, ()| { /// // use state.buffer, state.len
* // use state.buffer, state.len /// },
* }, /// |state| {
* |state| { /// // use state.buffer, state.len to cleanup
* // use state.buffer, state.len to cleanup /// })
* }) /// ```
* ```
*/
pub fn try_finally<T,U,R>(mutate: &mut T, pub fn try_finally<T,U,R>(mutate: &mut T,
drop: U, drop: U,
try_fn: |&mut T, U| -> R, 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; static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
/** /// Converts a number to its string representation as a byte vector.
* Converts a number to its string representation as a byte vector. /// This is meant to be a common base implementation for all numeric string
* This is meant to be a common base implementation for all numeric string /// conversion functions like `to_string()` or `to_str_radix()`.
* conversion functions like `to_string()` or `to_str_radix()`. ///
* /// # Arguments
* # Arguments ///
* - `num` - The number to convert. Accepts any number that /// - `num` - The number to convert. Accepts any number that
* implements the numeric traits. /// implements the numeric traits.
* - `radix` - Base to use. Accepts only the values 2-36. If the exponential notation /// - `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 /// is used, then this base is only used for the significand. The exponent
* itself always printed using a base of 10. /// itself always printed using a base of 10.
* - `negative_zero` - Whether to treat the special value `-0` as /// - `negative_zero` - Whether to treat the special value `-0` as
* `-0` or as `+0`. /// `-0` or as `+0`.
* - `sign` - How to emit the sign. See `SignFormat`. /// - `sign` - How to emit the sign. See `SignFormat`.
* - `digits` - The amount of digits to use for emitting the fractional /// - `digits` - The amount of digits to use for emitting the fractional
* part, if any. See `SignificantDigits`. /// part, if any. See `SignificantDigits`.
* - `exp_format` - Whether or not to use the exponential (scientific) notation. /// - `exp_format` - Whether or not to use the exponential (scientific) notation.
* See `ExponentFormat`. /// See `ExponentFormat`.
* - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if /// - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if
* exponential notation is desired. /// exponential notation is desired.
* - `f` - A closure to invoke with the bytes representing the /// - `f` - A closure to invoke with the bytes representing the
* float. /// float.
* ///
* # Panics /// # Panics
* - Panics if `radix` < 2 or `radix` > 36. ///
* - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict /// - Panics if `radix` < 2 or `radix` > 36.
* between digit and exponent sign `'e'`. /// - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
* - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict /// between digit and exponent sign `'e'`.
* between digit and exponent sign `'p'`. /// - 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>( pub fn float_to_str_bytes_common<T: Float, U>(
num: T, num: T,
radix: uint, radix: uint,

File diff suppressed because it is too large Load diff

View file

@ -1634,9 +1634,7 @@ impl BinarySearchResult {
// Free functions // 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"] #[unstable = "waiting for DST"]
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
unsafe { 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"] #[unstable = "waiting for DST"]
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
unsafe { unsafe {
@ -1710,10 +1706,8 @@ pub mod raw {
use raw::Slice; use raw::Slice;
use option::{None, Option, Some}; use option::{None, Option, Some};
/** /// Form a slice from a pointer and length (as a number of units,
* Form a slice from a pointer and length (as a number of units, /// not bytes).
* not bytes).
*/
#[inline] #[inline]
#[deprecated = "renamed to slice::from_raw_buf"] #[deprecated = "renamed to slice::from_raw_buf"]
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U) 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,
* Form a slice from a pointer and length (as a number of units, /// not bytes).
* not bytes).
*/
#[inline] #[inline]
#[deprecated = "renamed to slice::from_raw_mut_buf"] #[deprecated = "renamed to slice::from_raw_mut_buf"]
pub unsafe fn mut_buf_as_slice<T, pub unsafe fn mut_buf_as_slice<T,
@ -1742,11 +1734,9 @@ pub mod raw {
})) }))
} }
/** /// Returns a pointer to first element in slice and adjusts
* Returns a pointer to first element in slice and adjusts /// slice so it no longer contains that element. Returns None
* slice so it no longer contains that element. Returns None /// if the slice is empty. O(1).
* if the slice is empty. O(1).
*/
#[inline] #[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"] #[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> { pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
@ -1757,11 +1747,9 @@ pub mod raw {
Some(head) Some(head)
} }
/** /// Returns a pointer to last element in slice and adjusts
* Returns a pointer to last element in slice and adjusts /// slice so it no longer contains that element. Returns None
* slice so it no longer contains that element. Returns None /// if the slice is empty. O(1).
* if the slice is empty. O(1).
*/
#[inline] #[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"] #[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> { 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. // Standard types that are opaque or common, so are not per-target.
pub mod common { pub mod common {
pub mod c95 { pub mod c95 {
/** /// Type used to construct void pointers for use with C.
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
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
return type for FFI functions which have the `void` return type in /// C. Use the unit type `()` or omit the return type instead.
C. Use the unit type `()` or omit the return type instead. ///
/// For LLVM to recognize the void pointer type and by extension
For LLVM to recognize the void pointer type and by extension /// functions like malloc(), we need to have it represented as i8* in
functions like malloc(), we need to have it represented as i8* in /// LLVM bitcode. The enum used here ensures this and prevents misuse
LLVM bitcode. The enum used here ensures this and prevents misuse /// of the "raw" type by only having private variants.. We need two
of the "raw" type by only having private variants.. We need two /// variants, because the compiler complains about the repr attribute
variants, because the compiler complains about the repr attribute /// otherwise.
otherwise.
*/
#[repr(u8)] #[repr(u8)]
pub enum c_void { pub enum c_void {
__variant1, __variant1,

View file

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

View file

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

View file

@ -266,24 +266,22 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
pub type McResult<T> = Result<T, ()>; pub type McResult<T> = Result<T, ()>;
/** /// The `Typer` trait provides the interface for the mem-categorization
* The `Typer` trait provides the interface for the mem-categorization /// module to the results of the type check. It can be used to query
* 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,
* the type assigned to an expression node, to inquire after adjustments, /// and so on.
* and so on. ///
* /// This interface is needed because mem-categorization is used from
* This interface is needed because mem-categorization is used from /// two places: `regionck` and `borrowck`. `regionck` executes before
* two places: `regionck` and `borrowck`. `regionck` executes before /// type inference is complete, and hence derives types and so on from
* type inference is complete, and hence derives types and so on from /// intermediate tables. This also implies that type errors can occur,
* intermediate tables. This also implies that type errors can occur, /// and hence `node_ty()` and friends return a `Result` type -- any
* and hence `node_ty()` and friends return a `Result` type -- any /// error will propagate back up through the mem-categorization
* error will propagate back up through the mem-categorization /// routines.
* routines. ///
* /// In the borrow checker, in contrast, type checking is complete and we
* 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
* know that no errors have occurred, so we simply consult the tcx and we /// can be sure that only `Ok` results will occur.
* can be sure that only `Ok` results will occur.
*/
pub trait Typer<'tcx> { pub trait Typer<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>; fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'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. The region maps encode information about region relationships.
- `scope_map` maps from a scope id to the enclosing scope id; this is /// - `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 /// usually corresponding to the lexical nesting, though in the case of
closures the parent scope is the innermost conditional expression or repeating /// closures the parent scope is the innermost conditional expression or repeating
block /// block
///
- `var_map` maps from a variable or binding id to the block in which /// - `var_map` maps from a variable or binding id to the block in which
that variable is declared. /// that variable is declared.
///
- `free_region_map` maps from a free region `a` to a list of free /// - `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` /// regions `bs` such that `a <= b for all b in bs`
- the free region map is populated during type check as we check /// - the free region map is populated during type check as we check
each function. See the function `relate_free_regions` for /// each function. See the function `relate_free_regions` for
more information. /// more information.
///
- `rvalue_scopes` includes entries for those expressions whose cleanup /// - `rvalue_scopes` includes entries for those expressions whose cleanup
scope is larger than the default. The map goes from the expression /// 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, /// id to the cleanup scope id. For rvalues not present in this table,
the appropriate cleanup scope is the innermost enclosing statement, /// the appropriate cleanup scope is the innermost enclosing statement,
conditional expression, or repeating block (see `terminating_scopes`). /// conditional expression, or repeating block (see `terminating_scopes`).
///
- `terminating_scopes` is a set containing the ids of each statement, /// - `terminating_scopes` is a set containing the ids of each statement,
or conditional/repeating expression. These scopes are calling "terminating /// or conditional/repeating expression. These scopes are calling "terminating
scopes" because, when attempting to find the scope of a temporary, by /// scopes" because, when attempting to find the scope of a temporary, by
default we search up the enclosing scopes until we encounter the /// default we search up the enclosing scopes until we encounter the
terminating scope. A conditional/repeating /// terminating scope. A conditional/repeating
expression is one which is not guaranteed to execute exactly once /// expression is one which is not guaranteed to execute exactly once
upon entering the parent scope. This could be because the expression /// upon entering the parent scope. This could be because the expression
only executes conditionally, such as the expression `b` in `a && b`, /// only executes conditionally, such as the expression `b` in `a && b`,
or because the expression may execute many times, such as a loop /// or because the expression may execute many times, such as a loop
body. The reason that we distinguish such expressions is that, upon /// body. The reason that we distinguish such expressions is that, upon
exiting the parent scope, we cannot statically know how many times /// exiting the parent scope, we cannot statically know how many times
the expression executed, and thus if the expression creates /// the expression executed, and thus if the expression creates
temporaries we cannot know statically how many such temporaries we /// temporaries we cannot know statically how many such temporaries we
would have to cleanup. Therefore we ensure that the temporaries never /// would have to cleanup. Therefore we ensure that the temporaries never
outlast the conditional/repeating expression, preventing the need /// outlast the conditional/repeating expression, preventing the need
for dynamic checks and/or arbitrary amounts of stack space. /// for dynamic checks and/or arbitrary amounts of stack space.
*/
pub struct RegionMaps { pub struct RegionMaps {
scope_map: RefCell<FnvHashMap<CodeExtent, CodeExtent>>, scope_map: RefCell<FnvHashMap<CodeExtent, CodeExtent>>,
var_map: RefCell<NodeMap<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
* Returns the module node. Panics if this node does not have a module /// definition.
* definition.
*/
fn get_module(&self) -> Rc<Module> { fn get_module(&self) -> Rc<Module> {
match self.get_module_if_available() { match self.get_module_if_available() {
None => { None => {
@ -1098,18 +1096,16 @@ impl<'a> Resolver<'a> {
visit::walk_crate(&mut visitor, krate); visit::walk_crate(&mut visitor, krate);
} }
/** /// Adds a new child item to the module definition of the parent node and
* 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.
* returns its corresponding name bindings as well as the current parent. /// Or, if we're inside a block, creates (or reuses) an anonymous module
* Or, if we're inside a block, creates (or reuses) an anonymous module /// corresponding to the innermost block ID and returns the name bindings
* corresponding to the innermost block ID and returns the name bindings /// as well as the newly-created parent.
* as well as the newly-created parent. ///
* /// # Panics
* # Panics ///
* /// Panics if this node does not have a module definition and we are not inside
* Panics if this node does not have a module definition and we are not inside /// a block.
* a block.
*/
fn add_child(&self, fn add_child(&self,
name: Name, name: Name,
reduced_graph_parent: ReducedGraphParent, 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
* A substitution mapping type/region parameters to new values. We /// identify each in-scope parameter by an *index* and a *parameter
* identify each in-scope parameter by an *index* and a *parameter /// space* (which indices where the parameter is defined; see
* space* (which indices where the parameter is defined; see /// `ParamSpace`).
* `ParamSpace`).
*/
#[deriving(Clone, PartialEq, Eq, Hash, Show)] #[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct Substs<'tcx> { pub struct Substs<'tcx> {
pub types: VecPerParamSpace<Ty<'tcx>>, pub types: VecPerParamSpace<Ty<'tcx>>,
pub regions: RegionSubsts, pub regions: RegionSubsts,
} }
/** /// Represents the values to use when substituting lifetime parameters.
* Represents the values to use when substituting lifetime parameters. /// If the value is `ErasedRegions`, then this subst is occurring during
* If the value is `ErasedRegions`, then this subst is occurring during /// trans, and all region parameters will be replaced with `ty::ReStatic`.
* trans, and all region parameters will be replaced with `ty::ReStatic`. */
#[deriving(Clone, PartialEq, Eq, Hash, Show)] #[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum RegionSubsts { pub enum RegionSubsts {
ErasedRegions, ErasedRegions,
@ -226,11 +223,9 @@ impl ParamSpace {
} }
} }
/** /// Vector of things sorted by param space. Used to keep
* Vector of things sorted by param space. Used to keep /// the set of things declared on the type, self, or method
* the set of things declared on the type, self, or method /// distinct.
* distinct.
*/
#[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)] #[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)]
pub struct VecPerParamSpace<T> { pub struct VecPerParamSpace<T> {
// This was originally represented as a tuple with one Vec<T> for // This was originally represented as a tuple with one Vec<T> for
@ -250,10 +245,8 @@ pub struct VecPerParamSpace<T> {
content: Vec<T>, content: Vec<T>,
} }
/** /// The `split` function converts one `VecPerParamSpace` into this
* The `split` function converts one `VecPerParamSpace` into this /// `SeparateVecsPerParamSpace` structure.
* `SeparateVecsPerParamSpace` structure.
*/
pub struct SeparateVecsPerParamSpace<T> { pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>, pub types: Vec<T>,
pub selfs: Vec<T>, pub selfs: Vec<T>,

View file

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

View file

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

View file

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

View file

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

View file

@ -701,9 +701,7 @@ pub fn super_fold_obligation<'tcx, T:TypeFolder<'tcx>>(this: &mut T,
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Higher-ranked things // Higher-ranked things
/** /// Designates a "binder" for late-bound regions.
* Designates a "binder" for late-bound regions.
*/
pub trait HigherRankedFoldable<'tcx>: Repr<'tcx> { pub trait HigherRankedFoldable<'tcx>: Repr<'tcx> {
/// Folds the contents of `self`, ignoring the region binder created /// Folds the contents of `self`, ignoring the region binder created
/// by `self`. /// 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
* Checks that a method from an impl conforms to the signature of /// the same method as declared in the trait.
* the same method as declared in the trait. ///
* /// # Parameters
* # Parameters ///
* /// - impl_generics: the generics declared on the impl itself (not the method!)
* - impl_generics: the generics declared on the impl itself (not the method!) /// - impl_m: type of the method we are checking
* - impl_m: type of the method we are checking /// - impl_m_span: span to use for reporting errors
* - impl_m_span: span to use for reporting errors /// - impl_m_body_id: id of the method body
* - impl_m_body_id: id of the method body /// - trait_m: the method in the trait
* - trait_m: the method in the trait /// - trait_to_impl_substs: the substitutions used on the type of the trait
* - trait_to_impl_substs: the substitutions used on the type of the trait
*/
fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_m: &ty::Method<'tcx>, impl_m: &ty::Method<'tcx>,
impl_m_span: Span, 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
This function performs the actual region resolution. It must be /// called after all constraints have been added. It performs a
called after all constraints have been added. It performs a /// fixed-point iteration to find region values which satisfy all
fixed-point iteration to find region values which satisfy all /// constraints, assuming such values can be found; if they cannot,
constraints, assuming such values can be found; if they cannot, /// errors are reported.
errors are reported.
*/
pub fn resolve_regions(&self) -> Vec<RegionResolutionError<'tcx>> { pub fn resolve_regions(&self) -> Vec<RegionResolutionError<'tcx>> {
debug!("RegionVarBindings: resolve_regions()"); debug!("RegionVarBindings: resolve_regions()");
let mut errors = vec!(); let mut errors = vec!();

View file

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

View file

@ -219,18 +219,16 @@ pub fn infer_variance(tcx: &ty::ctxt) {
tcx.variance_computed.set(true); tcx.variance_computed.set(true);
} }
/************************************************************************** // Representing terms
* Representing terms //
* // Terms are structured as a straightforward tree. Rather than rely on
* Terms are structured as a straightforward tree. Rather than rely on // GC, we allocate terms out of a bounded arena (the lifetime of this
* GC, we allocate terms out of a bounded arena (the lifetime of this // arena is the lifetime 'a that is threaded around).
* arena is the lifetime 'a that is threaded around). //
* // We assign a unique index to each type/region parameter whose variance
* We assign a unique index to each type/region parameter whose variance // is to be inferred. We refer to such variables as "inferreds". An
* is to be inferred. We refer to such variables as "inferreds". An // `InferredIndex` is a newtype'd int representing the index of such
* `InferredIndex` is a newtype'd int representing the index of such // a variable.
* a variable.
*/
type VarianceTermPtr<'a> = &'a VarianceTerm<'a>; 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> { struct TermsContext<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
@ -399,12 +395,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
} }
} }
/************************************************************************** // Constraint construction and representation
* Constraint construction and representation //
* // The second pass over the AST determines the set of constraints.
* The second pass over the AST determines the set of constraints. // We walk the set of items and, for each member, generate new constraints.
* We walk the set of items and, for each member, generate new constraints.
*/
struct ConstraintContext<'a, 'tcx: 'a> { struct ConstraintContext<'a, 'tcx: 'a> {
terms_cx: TermsContext<'a, 'tcx>, terms_cx: TermsContext<'a, 'tcx>,
@ -944,14 +938,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
} }
} }
/************************************************************************** // Constraint solving
* Constraint solving //
* // The final phase iterates over the constraints, refining the variance
* The final phase iterates over the constraints, refining the variance // for each inferred until a fixed point is reached. This will be the
* for each inferred until a fixed point is reached. This will be the // optimal solution to the constraints. The final variance for each
* optimal solution to the constraints. The final variance for each // inferred is then written into the `variance_map` in the tcx.
* inferred is then written into the `variance_map` in the tcx.
*/
struct SolveContext<'a, 'tcx: 'a> { struct SolveContext<'a, 'tcx: 'a> {
terms_cx: TermsContext<'a, 'tcx>, 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 { trait Xform {
fn xform(self, v: Self) -> Self; 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); assert!(self.undo_log.len() == snapshot.length);
} }
/** /// Commits all changes since the last snapshot. Of course, they
* Commits all changes since the last snapshot. Of course, they /// can still be undone if there is a snapshot further out.
* can still be undone if there is a snapshot further out.
*/
pub fn commit(&mut self, snapshot: Snapshot) { pub fn commit(&mut self, snapshot: Snapshot) {
debug!("commit({})", snapshot.length); debug!("commit({})", snapshot.length);

View file

@ -520,24 +520,24 @@ extern {
pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef; pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
pub fn LLVMDisposeModule(M: ModuleRef); 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 LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *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 LLVMGetTarget(M: ModuleRef) -> *const c_char;
pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char); pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
/** See Module::dump. */ /// See Module::dump.
pub fn LLVMDumpModule(M: ModuleRef); pub fn LLVMDumpModule(M: ModuleRef);
/** See Module::setModuleInlineAsm. */ /// See Module::setModuleInlineAsm.
pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char); pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
/** See llvm::LLVMTypeKind::getTypeID. */ /// See llvm::LLVMTypeKind::getTypeID.
pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind; pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
/** See llvm::LLVMType::getContext. */ /// See llvm::LLVMType::getContext.
pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef; pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
/* Operations on integer types */ /* Operations on integer types */
@ -1460,30 +1460,29 @@ extern {
pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef; pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
pub fn LLVMIsAStoreInst(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; 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; pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
/// Adds the target data to the given pass manager. The pass manager /// Adds the target data to the given pass manager. The pass manager
/// references the target data only weakly. /// references the target data only weakly.
pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef); 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) pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong; -> 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) pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong; -> c_ulonglong;
/** Distance between successive elements in an array of T. /// Distance between successive elements in an array of T. Includes ABI padding.
Includes ABI padding. */
pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong; 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) pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint; -> c_uint;
/** Returns the minimum alignment of a type. */ /// Returns the minimum alignment of a type.
pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef) pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint; -> c_uint;
@ -1494,41 +1493,39 @@ extern {
Element: c_uint) Element: c_uint)
-> c_ulonglong; -> 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) pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_uint; -> c_uint;
/** Disposes target data. */ /// Disposes target data.
pub fn LLVMDisposeTargetData(TD: TargetDataRef); pub fn LLVMDisposeTargetData(TD: TargetDataRef);
/** Creates a pass manager. */ /// Creates a pass manager.
pub fn LLVMCreatePassManager() -> PassManagerRef; pub fn LLVMCreatePassManager() -> PassManagerRef;
/** Creates a function-by-function pass manager */ /// Creates a function-by-function pass manager
pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef) pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
-> PassManagerRef; -> PassManagerRef;
/** Disposes a pass manager. */ /// Disposes a pass manager.
pub fn LLVMDisposePassManager(PM: PassManagerRef); 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; 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) pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
-> Bool; -> 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; 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 LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
pub fn LLVMInitializePasses(); pub fn LLVMInitializePasses();
/** Adds a verification pass. */ /// Adds a verification pass.
pub fn LLVMAddVerifierPass(PM: PassManagerRef); pub fn LLVMAddVerifierPass(PM: PassManagerRef);
pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef); pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
@ -1598,38 +1595,38 @@ extern {
Internalize: Bool, Internalize: Bool,
RunInliner: Bool); RunInliner: Bool);
/** Destroys a memory buffer. */ /// Destroys a memory buffer.
pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef); pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
/* Stuff that's in rustllvm/ because it's not upstream yet. */ /* 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; pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
/** Closes an object file. */ /// Closes an object file.
pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef); 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; pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
/** Destroys a section iterator. */ /// Destroys a section iterator.
pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef); pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
/** Returns true if the section iterator is at the end of the section /// Returns true if the section iterator is at the end of the section
list: */ /// list:
pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef, pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
SI: SectionIteratorRef) SI: SectionIteratorRef)
-> Bool; -> 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); pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
/** Returns the current section size. */ /// Returns the current section size.
pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong; 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; pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
/** Reads the given file and returns it as a memory buffer. Use /// Reads the given file and returns it as a memory buffer. Use
LLVMDisposeMemoryBuffer() to get rid of it. */ /// LLVMDisposeMemoryBuffer() to get rid of it.
pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char) pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
-> MemoryBufferRef; -> 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, pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
InputDataLength: size_t, InputDataLength: size_t,
BufferName: *const c_char, BufferName: *const c_char,
@ -1643,8 +1640,7 @@ extern {
pub fn LLVMIsMultithreaded() -> Bool; pub fn LLVMIsMultithreaded() -> Bool;
pub fn LLVMStartMultithreaded() -> Bool; pub fn LLVMStartMultithreaded() -> Bool;
/** Returns a string describing the last error caused by an LLVMRust* /// Returns a string describing the last error caused by an LLVMRust* call.
call. */
pub fn LLVMRustGetLastError() -> *const c_char; pub fn LLVMRustGetLastError() -> *const c_char;
/// Print the pass timings since static dtors aren't picking them up. /// Print the pass timings since static dtors aren't picking them up.
@ -1662,10 +1658,10 @@ extern {
Count: c_uint) Count: c_uint)
-> ValueRef; -> ValueRef;
/** Enables LLVM debug output. */ /// Enables LLVM debug output.
pub fn LLVMSetDebug(Enabled: c_int); pub fn LLVMSetDebug(Enabled: c_int);
/** Prepares inline assembly. */ /// Prepares inline assembly.
pub fn LLVMInlineAsm(Ty: TypeRef, pub fn LLVMInlineAsm(Ty: TypeRef,
AsmString: *const c_char, AsmString: *const c_char,
Constraints: *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); phase_6_link_output(&sess, &trans, &outputs);
} }
/** /// The name used for source code that doesn't originate in a file
* The name used for source code that doesn't originate in a file /// (e.g. source from stdin or a string)
* (e.g. source from stdin or a string)
*/
pub fn anon_src() -> String { pub fn anon_src() -> String {
"<anon>".to_string() "<anon>".to_string()
} }

View file

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

View file

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

View file

@ -31,12 +31,10 @@ use util::ppaux::{ty_to_string};
use std::fmt; use std::fmt;
use syntax::ast; use syntax::ast;
/** /// A `Datum` encapsulates the result of evaluating an expression. It
* A `Datum` encapsulates the result of evaluating an expression. It /// describes where the value is stored, what Rust type the value has,
* describes where the value is stored, what Rust type the value has, /// whether it is addressed by reference, and so forth. Please refer
* whether it is addressed by reference, and so forth. Please refer /// the section on datums in `doc.rs` for more details.
* the section on datums in `doc.rs` for more details.
*/
#[deriving(Clone)] #[deriving(Clone)]
pub struct Datum<'tcx, K> { pub struct Datum<'tcx, K> {
/// The llvm value. This is either a pointer to the Rust value or /// 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 { pub trait KindOps {
/** /// Take appropriate action after the value in `datum` has been
* Take appropriate action after the value in `datum` has been /// stored to a new location.
* stored to a new location.
*/
fn post_store<'blk, 'tcx>(&self, fn post_store<'blk, 'tcx>(&self,
bcx: Block<'blk, 'tcx>, bcx: Block<'blk, 'tcx>,
val: ValueRef, val: ValueRef,
ty: Ty<'tcx>) ty: Ty<'tcx>)
-> Block<'blk, 'tcx>; -> Block<'blk, 'tcx>;
/** /// True if this mode is a reference mode, meaning that the datum's
* True if this mode is a reference mode, meaning that the datum's /// val field is a pointer to the actual value
* val field is a pointer to the actual value
*/
fn is_by_ref(&self) -> bool; fn is_by_ref(&self) -> bool;
/** /// Converts to an Expr kind
* Converts to an Expr kind
*/
fn to_expr_kind(self) -> Expr; 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
* Methods suitable for "expr" datums that could be either lvalues or /// rvalues. These include coercions into lvalues/rvalues but also a number
* rvalues. These include coercions into lvalues/rvalues but also a number /// of more general operations. (Some of those operations could be moved to
* 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
* 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
* here since we can `match self.kind` rather than having to implement /// generic methods in `KindOps`.)
* generic methods in `KindOps`.)
*/
impl<'tcx> Datum<'tcx, Expr> { impl<'tcx> Datum<'tcx, Expr> {
fn match_kind<R>(self, fn match_kind<R>(self,
if_lvalue: |Datum<'tcx, Lvalue>| -> R, if_lvalue: |Datum<'tcx, Lvalue>| -> R,
@ -494,12 +484,10 @@ impl<'tcx> Datum<'tcx, Expr> {
} }
/** /// Methods suitable only for lvalues. These include the various
* Methods suitable only for lvalues. These include the various /// operations to extract components out of compound data structures,
* operations to extract components out of compound data structures, /// such as extracting the field from a struct or a particular element
* such as extracting the field from a struct or a particular element /// from an array.
* from an array.
*/
impl<'tcx> Datum<'tcx, Lvalue> { impl<'tcx> Datum<'tcx, Lvalue> {
pub fn to_llref(self) -> ValueRef { 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> { impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> {
pub fn new(val: ValueRef, ty: Ty<'tcx>, kind: K) -> Datum<'tcx, K> { pub fn new(val: ValueRef, ty: Ty<'tcx>, kind: K) -> Datum<'tcx, K> {
Datum { val: val, ty: ty, kind: kind } 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
* 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
* of a struct copied from a base struct (e.g., from an expression /// like `Foo { a: b, ..base }`.
* like `Foo { a: b, ..base }`. ///
* /// Note that `fields` may be empty; the base expression must always be
* Note that `fields` may be empty; the base expression must always be /// evaluated for side-effects.
* evaluated for side-effects.
*/
pub struct StructBaseInfo<'a, 'tcx> { pub struct StructBaseInfo<'a, 'tcx> {
/// The base expression; will be evaluated after all explicit fields. /// The base expression; will be evaluated after all explicit fields.
expr: &'a ast::Expr, expr: &'a ast::Expr,
@ -1392,16 +1390,14 @@ pub struct StructBaseInfo<'a, 'tcx> {
fields: Vec<(uint, Ty<'tcx>)> fields: Vec<(uint, Ty<'tcx>)>
} }
/** /// Constructs an ADT instance:
* Constructs an ADT instance: ///
* /// - `fields` should be a list of field indices paired with the
* - `fields` should be a list of field indices paired with the /// expression to store into that field. The initializers will be
* expression to store into that field. The initializers will be /// evaluated in the order specified by `fields`.
* evaluated in the order specified by `fields`. ///
* /// - `optbase` contains information on the base struct (if any) from
* - `optbase` contains information on the base struct (if any) from /// which remaining fields are copied; see comments on `StructBaseInfo`.
* which remaining fields are copied; see comments on `StructBaseInfo`.
*/
pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
discr: ty::Disr, discr: ty::Disr,

View file

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

View file

@ -35,9 +35,7 @@ macro_rules! ty (
($e:expr) => ( Type::from_ref(unsafe { $e })) ($e:expr) => ( Type::from_ref(unsafe { $e }))
) )
/** /// Wrapper for LLVM TypeRef
* Wrapper for LLVM TypeRef
*/
impl Type { impl Type {
#[inline(always)] #[inline(always)]
pub fn from_ref(r: TypeRef) -> Type { 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 { impl Value {
/// Returns the native ValueRef /// Returns the native ValueRef
pub fn get(&self) -> ValueRef { pub fn get(&self) -> ValueRef {
@ -127,9 +125,7 @@ impl Value {
pub struct Use(UseRef); pub struct Use(UseRef);
/** /// Wrapper for LLVM UseRef
* Wrapper for LLVM UseRef
*/
impl Use { impl Use {
pub fn get(&self) -> UseRef { pub fn get(&self) -> UseRef {
let Use(v) = *self; v let Use(v) = *self; v

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -33,13 +33,11 @@ use string::String;
pub use sys_common::ProcessConfig; pub use sys_common::ProcessConfig;
/** /// A value representing a child process.
* A value representing a child process. ///
* /// The lifetime of this value is linked to the lifetime of the actual
* The lifetime of this value is linked to the lifetime of the actual /// process - the Process destructor calls self.finish() which waits
* process - the Process destructor calls self.finish() which waits /// for the process to terminate.
* for the process to terminate.
*/
pub struct Process { pub struct Process {
/// The unique id of the process (this should never be negative). /// The unique id of the process (this should never be negative).
pid: pid_t, pid: pid_t,
@ -263,16 +261,14 @@ impl Process {
} }
} }
/** /// Waits for a process to exit and returns the exit code, failing
* Waits for a process to exit and returns the exit code, failing /// if there is no process with the specified id.
* if there is no process with the specified id. ///
* /// Note that this is private to avoid race conditions on unix where if
* 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()
* a user calls waitpid(some_process.get_id()) then some_process.finish() /// and some_process.destroy() and some_process.finalize() will then either
* and some_process.destroy() and some_process.finalize() will then either /// operate on a none-existent process or, even worse, on a newer process
* operate on a none-existent process or, even worse, on a newer process /// with the same id.
* with the same id.
*/
pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> { pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
use libc::types::os::arch::extra::DWORD; use libc::types::os::arch::extra::DWORD;
use libc::consts::os::extra::{ 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
Spans represent a region of code, used for error reporting. Positions in spans /// are *absolute* positions from the beginning of the codemap, not positions
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
relative to FileMaps. Methods on the CodeMap can be used to relate spans back /// to the original source.
to the original source.
*/
#[deriving(Clone, Show, Hash)] #[deriving(Clone, Show, Hash)]
pub struct Span { pub struct Span {
pub lo: BytePos, pub lo: BytePos,

View file

@ -17,16 +17,12 @@ use parse::token::*;
use parse::token; use parse::token;
use ptr::P; use ptr::P;
/** //! Quasiquoting works via token trees.
* //!
* 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
* This is registered as a set of expression syntax extension called quote! //! construction of the same token tree, with token::SubstNt interpreted
* that lifts its argument token-tree to an AST representing the //! as antiquotes (splices).
* construction of the same token tree, with token::SubstNt interpreted
* as antiquotes (splices).
*
*/
pub mod rt { pub mod rt {
use ast; 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.
* All the valid words that have meaning in the Rust language. ///
* /// Rust keywords are either 'strict' or 'reserved'. Strict keywords may not
* Rust keywords are either 'strict' or 'reserved'. Strict keywords may not /// appear as identifiers at all. Reserved keywords are not used anywhere in
* appear as identifiers at all. Reserved keywords are not used anywhere in /// the language and may not appear as identifiers.
* the language and may not appear as identifiers.
*/
pub mod keywords { pub mod keywords {
pub use self::Keyword::*; pub use self::Keyword::*;
use ast; use ast;

View file

@ -80,17 +80,15 @@ impl Variables {
} }
} }
/** /// Expand a parameterized capability
Expand a parameterized capability ///
/// # Arguments
# Arguments /// * `cap` - string to expand
* `cap` - string to expand /// * `params` - vector of params for %p1 etc
* `params` - vector of params for %p1 etc /// * `vars` - Variables struct for %Pa etc
* `vars` - Variables struct for %Pa etc ///
/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
To be compatible with ncurses, `vars` should be the same between calls to `expand` for /// multiple capabilities for the same terminal.
multiple capabilities for the same terminal.
*/
pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
-> Result<Vec<u8> , String> { -> Result<Vec<u8> , String> {
let mut state = Nothing; 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
* Returns the current time as a `timespec` containing the seconds and /// nanoseconds since 1970-01-01T00:00:00Z.
* nanoseconds since 1970-01-01T00:00:00Z.
*/
pub fn get_time() -> Timespec { pub fn get_time() -> Timespec {
unsafe { unsafe {
let (sec, nsec) = os_get_time(); 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
* Returns the current value of a high-resolution performance counter /// in nanoseconds since an unspecified epoch.
* in nanoseconds since an unspecified epoch.
*/
pub fn precise_time_ns() -> u64 { pub fn precise_time_ns() -> u64 {
return os_precise_time_ns(); 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
* Returns the current value of a high-resolution performance counter /// in seconds since an unspecified epoch.
* in seconds since an unspecified epoch.
*/
pub fn precise_time_s() -> f64 { pub fn precise_time_s() -> f64 {
return (precise_time_ns() as f64) / 1000000000.; return (precise_time_ns() as f64) / 1000000000.;
} }
@ -346,12 +340,10 @@ impl Tm {
at_utc(self.to_timespec()) at_utc(self.to_timespec())
} }
/** /// Returns a TmFmt that outputs according to the `asctime` format in ISO
* Returns a TmFmt that outputs according to the `asctime` format in ISO /// C, in the local timezone.
* C, in the local timezone. ///
* /// Example: "Thu Jan 1 00:00:00 1970"
* Example: "Thu Jan 1 00:00:00 1970"
*/
pub fn ctime(&self) -> TmFmt { pub fn ctime(&self) -> TmFmt {
TmFmt { TmFmt {
tm: self, tm: self,
@ -359,12 +351,10 @@ impl Tm {
} }
} }
/** /// Returns a TmFmt that outputs according to the `asctime` format in ISO
* Returns a TmFmt that outputs according to the `asctime` format in ISO /// C.
* C. ///
* /// Example: "Thu Jan 1 00:00:00 1970"
* Example: "Thu Jan 1 00:00:00 1970"
*/
pub fn asctime(&self) -> TmFmt { pub fn asctime(&self) -> TmFmt {
TmFmt { TmFmt {
tm: self, tm: self,
@ -380,12 +370,10 @@ impl Tm {
}) })
} }
/** /// Returns a TmFmt that outputs according to RFC 822.
* Returns a TmFmt that outputs according to RFC 822. ///
* /// local: "Thu, 22 Mar 2012 07:53:18 PST"
* local: "Thu, 22 Mar 2012 07:53:18 PST" /// utc: "Thu, 22 Mar 2012 14:53:18 GMT"
* utc: "Thu, 22 Mar 2012 14:53:18 GMT"
*/
pub fn rfc822(&self) -> TmFmt { pub fn rfc822(&self) -> TmFmt {
if self.tm_gmtoff == 0_i32 { if self.tm_gmtoff == 0_i32 {
TmFmt { TmFmt {
@ -400,12 +388,10 @@ impl Tm {
} }
} }
/** /// Returns a TmFmt that outputs according to RFC 822 with Zulu time.
* Returns a TmFmt that outputs according to RFC 822 with Zulu time. ///
* /// local: "Thu, 22 Mar 2012 07:53:18 -0700"
* local: "Thu, 22 Mar 2012 07:53:18 -0700" /// utc: "Thu, 22 Mar 2012 14:53:18 -0000"
* utc: "Thu, 22 Mar 2012 14:53:18 -0000"
*/
pub fn rfc822z(&self) -> TmFmt { pub fn rfc822z(&self) -> TmFmt {
TmFmt { TmFmt {
tm: self, tm: self,
@ -413,13 +399,11 @@ impl Tm {
} }
} }
/** /// Returns a TmFmt that outputs according to RFC 3339. RFC 3339 is
* Returns a TmFmt that outputs according to RFC 3339. RFC 3339 is /// compatible with ISO 8601.
* compatible with ISO 8601. ///
* /// local: "2012-02-22T07:53:18-07:00"
* local: "2012-02-22T07:53:18-07:00" /// utc: "2012-02-22T14:53:18Z"
* utc: "2012-02-22T14:53:18Z"
*/
pub fn rfc3339<'a>(&'a self) -> TmFmt { pub fn rfc3339<'a>(&'a self) -> TmFmt {
TmFmt { TmFmt {
tm: self, tm: self,