diff --git a/doc/po/rust.md.pot b/doc/po/rust.md.pot index 789b396153c0c..516ca32104adf 100644 --- a/doc/po/rust.md.pot +++ b/doc/po/rust.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:47+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,7 +24,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" @@ -456,9 +456,9 @@ msgstr "" #. type: Plain text #: doc/rust.md:223 msgid "" -"~~~~~~~~ {.keyword} as break copy do drop else enum extern false fn for if " -"impl let loop match mod mut priv pub ref return self static struct super " -"true trait type unsafe use while ~~~~~~~~" +"~~~~~~~~ {.keyword} as break copy do else enum extern false fn for if impl " +"let loop match mod mut priv pub ref return self static struct super true " +"trait type unsafe use while ~~~~~~~~" msgstr "" #. type: Plain text @@ -1637,7 +1637,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:807 -msgid "~~~~ use std::float::sin; use std::option::{Some, None};" +msgid "~~~~ use std::num::sin; use std::option::{Some, None};" msgstr "" #. type: Plain text @@ -1645,7 +1645,7 @@ msgstr "" #, no-wrap msgid "" "fn main() {\n" -" // Equivalent to 'info!(std::float::sin(1.0));'\n" +" // Equivalent to 'info!(std::num::sin(1.0));'\n" " info!(sin(1.0));\n" msgstr "" @@ -2423,7 +2423,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1231 doc/tutorial.md:2179 +#: doc/rust.md:1231 doc/tutorial.md:2177 msgid "" "In type-parameterized functions, methods of the supertrait may be called on " "values of subtrait-bound type parameters. Refering to the previous example " @@ -2431,7 +2431,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1240 doc/tutorial.md:2188 +#: doc/rust.md:1240 doc/tutorial.md:2186 #, no-wrap msgid "" "~~~\n" @@ -2445,7 +2445,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1242 doc/tutorial.md:2190 +#: doc/rust.md:1242 doc/tutorial.md:2188 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" @@ -2792,15 +2792,25 @@ msgstr "" msgid "The `test` attribute, for marking functions as unit tests." msgstr "" -#. type: Plain text +#. type: Bullet: '* ' #: doc/rust.md:1425 -#, no-wrap msgid "" -"* The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint checks. Lint checks supported\n" -"by the compiler can be found via `rustc -W help`.\n" -"* The `deriving` attribute, for automatically generating\n" -" implementations of certain traits.\n" -"* The `static_assert` attribute, for asserting that a static bool is true at compiletime\n" +"The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint " +"checks (see [Lint check attributes](#lint-check-attributes))." +msgstr "" + +#. type: Bullet: '* ' +#: doc/rust.md:1425 +msgid "" +"The `deriving` attribute, for automatically generating implementations of " +"certain traits." +msgstr "" + +#. type: Bullet: '* ' +#: doc/rust.md:1425 +msgid "" +"The `static_assert` attribute, for asserting that a static bool is true at " +"compiletime" msgstr "" #. type: Plain text @@ -2811,11 +2821,150 @@ msgstr "" #. type: Plain text #: doc/rust.md:1429 -msgid "### Language items" +msgid "### Lint check attributes" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1433 +msgid "" +"A lint check names a potentially undesirable coding pattern, such as " +"unreachable code or omitted documentation, for the static entity to which " +"the attribute applies." msgstr "" #. type: Plain text #: doc/rust.md:1435 +msgid "For any lint check `C`:" +msgstr "" + +#. type: Bullet: ' * ' +#: doc/rust.md:1442 +msgid "`warn(C)` warns about violations of `C` but continues compilation," +msgstr "" + +#. type: Bullet: ' * ' +#: doc/rust.md:1442 +msgid "`deny(C)` signals an error after encountering a violation of `C`," +msgstr "" + +#. type: Plain text +#: doc/rust.md:1442 +#, no-wrap +msgid "" +" * `allow(C)` overrides the check for `C` so that violations will go\n" +" unreported,\n" +" * `forbid(C)` is the same as `deny(C)`, but also forbids uses of\n" +" `allow(C)` within the entity.\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1445 +msgid "" +"The lint checks supported by the compiler can be found via `rustc -W help`, " +"along with their default settings." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1451 +#, no-wrap +msgid "" +"~~~{.xfail-test}\n" +"mod m1 {\n" +" // Missing documentation is ignored here\n" +" #[allow(missing_doc)]\n" +" pub fn undocumented_one() -> int { 1 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1455 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here\n" +" #[warn(missing_doc)]\n" +" pub fn undocumented_too() -> int { 2 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1461 +#, no-wrap +msgid "" +" // Missing documentation signals an error here\n" +" #[deny(missing_doc)]\n" +" pub fn undocumented_end() -> int { 3 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1464 +msgid "" +"This example shows how one can use `allow` and `warn` to toggle a particular " +"check on and off." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1472 +#, no-wrap +msgid "" +"~~~\n" +"#[warn(missing_doc)]\n" +"mod m2{\n" +" #[allow(missing_doc)]\n" +" mod nested {\n" +" // Missing documentation is ignored here\n" +" pub fn undocumented_one() -> int { 1 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1478 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here,\n" +" // despite the allow above.\n" +" #[warn(missing_doc)]\n" +" pub fn undocumented_two() -> int { 2 }\n" +" }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1483 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here\n" +" pub fn undocumented_too() -> int { 3 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1486 +msgid "" +"This example shows how one can use `forbid` to disallow uses of `allow` for " +"that lint check." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1496 +#, no-wrap +msgid "" +"~~~{.xfail-test}\n" +"#[forbid(missing_doc)]\n" +"mod m3 {\n" +" // Attempting to toggle warning signals an error here\n" +" #[allow(missing_doc)]\n" +" /// Returns 2.\n" +" pub fn undocumented_too() -> int { 2 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1498 +msgid "### Language items" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1504 msgid "" "Some primitive Rust operations are defined in Rust code, rather than being " "implemented directly in C or assembly language. The definitions of these " @@ -2825,7 +2974,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1442 +#: doc/rust.md:1511 #, no-wrap msgid "" "~~~ {.xfail-test}\n" @@ -2837,7 +2986,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1446 +#: doc/rust.md:1515 msgid "" "The name `str_eq` has a special meaning to the Rust compiler, and the " "presence of this definition means that it will use this definition when " @@ -2845,17 +2994,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1448 +#: doc/rust.md:1517 msgid "A complete list of the built-in language items follows:" msgstr "" #. type: Plain text -#: doc/rust.md:1450 +#: doc/rust.md:1519 msgid "#### Traits" msgstr "" #. type: Plain text -#: doc/rust.md:1491 +#: doc/rust.md:1560 #, no-wrap msgid "" "`const`\n" @@ -2901,12 +3050,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1493 +#: doc/rust.md:1562 msgid "#### Operations" msgstr "" #. type: Plain text -#: doc/rust.md:1522 +#: doc/rust.md:1591 #, no-wrap msgid "" "`str_eq`\n" @@ -2940,19 +3089,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1525 +#: doc/rust.md:1594 msgid "" "> **Note:** This list is likely to become out of date. We should auto-" "generate it > from `librustc/middle/lang_items.rs`." msgstr "" #. type: Plain text -#: doc/rust.md:1527 +#: doc/rust.md:1596 msgid "### Deriving" msgstr "" #. type: Plain text -#: doc/rust.md:1533 +#: doc/rust.md:1602 msgid "" "The `deriving` attribute allows certain traits to be automatically " "implemented for data structures. For example, the following will create an " @@ -2961,7 +3110,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1541 +#: doc/rust.md:1610 #, no-wrap msgid "" "~~~\n" @@ -2974,12 +3123,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1543 +#: doc/rust.md:1612 msgid "The generated `impl` for `Eq` is equivalent to" msgstr "" #. type: Plain text -#: doc/rust.md:1550 +#: doc/rust.md:1619 #, no-wrap msgid "" "~~~\n" @@ -2991,7 +3140,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1556 +#: doc/rust.md:1625 #, no-wrap msgid "" " fn ne(&self, other: &Foo) -> bool {\n" @@ -3002,42 +3151,42 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1558 +#: doc/rust.md:1627 msgid "Supported traits for `deriving` are:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "Serialization: `Encodable`, `Decodable`. These require `extra`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Clone` and `DeepClone`, to perform (deep) copies." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`IterBytes`, to iterate over the bytes in a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Rand`, to create a random instance of a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Zero`, to create an zero (or empty) instance of a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "" "`ToStr`, to convert to a string. For a type with this instance, `obj." "to_str()` has similar output as `fmt!(\"%?\", obj)`, but it differs in that " @@ -3046,12 +3195,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1571 +#: doc/rust.md:1640 msgid "# Statements and expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1578 +#: doc/rust.md:1647 msgid "" "Rust is _primarily_ an expression language. This means that most forms of " "value-producing or effect-causing evaluation are directed by the uniform " @@ -3062,38 +3211,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1581 +#: doc/rust.md:1650 msgid "" "In contrast, statements in Rust serve _mostly_ to contain and explicitly " "sequence expression evaluation." msgstr "" #. type: Plain text -#: doc/rust.md:1583 +#: doc/rust.md:1652 msgid "## Statements" msgstr "" #. type: Plain text -#: doc/rust.md:1586 +#: doc/rust.md:1655 msgid "" "A _statement_ is a component of a block, which is in turn a component of an " "outer [expression](#expressions) or [function](#functions)." msgstr "" #. type: Plain text -#: doc/rust.md:1590 +#: doc/rust.md:1659 msgid "" "Rust has two kinds of statement: [declaration statements](#declaration-" "statements) and [expression statements](#expression-statements)." msgstr "" #. type: Plain text -#: doc/rust.md:1592 +#: doc/rust.md:1661 msgid "### Declaration statements" msgstr "" #. type: Plain text -#: doc/rust.md:1595 +#: doc/rust.md:1664 msgid "" "A _declaration statement_ is one that introduces one or more *names* into " "the enclosing statement block. The declared names may denote new slots or " @@ -3101,12 +3250,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1597 +#: doc/rust.md:1666 msgid "#### Item declarations" msgstr "" #. type: Plain text -#: doc/rust.md:1604 +#: doc/rust.md:1673 msgid "" "An _item declaration statement_ has a syntactic form identical to an [item]" "(#items) declaration within a module. Declaring an item -- a function, " @@ -3117,26 +3266,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1607 +#: doc/rust.md:1676 msgid "" "Note: there is no implicit capture of the function's dynamic environment " "when declaring a function-local item." msgstr "" #. type: Plain text -#: doc/rust.md:1610 +#: doc/rust.md:1679 msgid "#### Slot declarations" msgstr "" #. type: Plain text -#: doc/rust.md:1615 +#: doc/rust.md:1684 msgid "" "~~~~~~~~{.ebnf .gram} let_decl : \"let\" pat [':' type ] ? [ init ] ? ';' ; " "init : [ '=' ] expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1621 +#: doc/rust.md:1690 msgid "" "A _slot declaration_ introduces a new set of slots, given by a pattern. The " "pattern may be followed by a type annotation, and/or an initializer " @@ -3147,12 +3296,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1623 +#: doc/rust.md:1692 msgid "### Expression statements" msgstr "" #. type: Plain text -#: doc/rust.md:1628 +#: doc/rust.md:1697 msgid "" "An _expression statement_ is one that evaluates an [expression]" "(#expressions) and ignores its result. The type of an expression statement " @@ -3162,12 +3311,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1630 +#: doc/rust.md:1699 msgid "## Expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1639 +#: doc/rust.md:1708 #, no-wrap msgid "" "An expression may have two roles: it always produces a *value*, and it may have *effects*\n" @@ -3181,7 +3330,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1644 +#: doc/rust.md:1713 msgid "" "In this way, the structure of expressions dictates the structure of " "execution. Blocks are just another kind of expression, so blocks, " @@ -3190,12 +3339,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1646 +#: doc/rust.md:1715 msgid "#### Lvalues, rvalues and temporaries" msgstr "" #. type: Plain text -#: doc/rust.md:1650 +#: doc/rust.md:1719 msgid "" "Expressions are divided into two main categories: _lvalues_ and _rvalues_. " "Likewise within each expression, sub-expressions may occur in _lvalue " @@ -3204,14 +3353,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1653 +#: doc/rust.md:1722 msgid "" "[Path](#path-expressions), [field](#field-expressions) and [index](#index-" "expressions) expressions are lvalues. All other expressions are rvalues." msgstr "" #. type: Plain text -#: doc/rust.md:1661 +#: doc/rust.md:1730 msgid "" "The left operand of an [assignment](#assignment-expressions), [binary move]" "(#binary-move-expressions) or [compound-assignment](#compound-assignment-" @@ -3222,7 +3371,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1664 +#: doc/rust.md:1733 msgid "" "When an lvalue is evaluated in an _lvalue context_, it denotes a memory " "location; when evaluated in an _rvalue context_, it denotes the value held " @@ -3230,7 +3379,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1667 +#: doc/rust.md:1736 msgid "" "When an rvalue is used in lvalue context, a temporary un-named lvalue is " "created and used instead. A temporary's lifetime equals the largest " @@ -3238,12 +3387,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1669 +#: doc/rust.md:1738 msgid "#### Moved and copied types" msgstr "" #. type: Plain text -#: doc/rust.md:1675 +#: doc/rust.md:1744 msgid "" "When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-" "rvalues-and-temporaries) the variable will either be [moved](#move-" @@ -3253,12 +3402,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1678 +#: doc/rust.md:1747 msgid "### Literal expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1682 +#: doc/rust.md:1751 msgid "" "A _literal expression_ consists of one of the [literal](#literals) forms " "described earlier. It directly describes a number, character, string, " @@ -3266,7 +3415,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1689 +#: doc/rust.md:1758 #, no-wrap msgid "" "~~~~~~~~ {.literals}\n" @@ -3278,12 +3427,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1691 +#: doc/rust.md:1760 msgid "### Path expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1694 +#: doc/rust.md:1763 msgid "" "A [path](#paths) used as an expression context denotes either a local " "variable or an item. Path expressions are [lvalues](#lvalues-rvalues-and-" @@ -3291,29 +3440,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1696 +#: doc/rust.md:1765 msgid "### Tuple expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1700 +#: doc/rust.md:1769 msgid "" "Tuples are written by enclosing one or more comma-separated expressions in " "parentheses. They are used to create [tuple-typed](#tuple-types) values." msgstr "" #. type: Plain text -#: doc/rust.md:1706 +#: doc/rust.md:1775 msgid "~~~~~~~~ {.tuple} (0,); (0f, 4.5f); (\"a\", 4u, true); ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1708 +#: doc/rust.md:1777 msgid "### Structure expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1717 +#: doc/rust.md:1786 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -3327,7 +3476,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1724 +#: doc/rust.md:1793 msgid "" "There are several forms of structure expressions. A _structure expression_ " "consists of the [path](#paths) of a [structure item](#structures), followed " @@ -3339,7 +3488,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1729 +#: doc/rust.md:1798 msgid "" "A _tuple structure expression_ consists of the [path](#paths) of a " "[structure item](#structures), followed by a parenthesized list of one or " @@ -3349,19 +3498,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1731 +#: doc/rust.md:1800 msgid "" "A _unit-like structure expression_ consists only of the [path](#paths) of a " "[structure item](#structures)." msgstr "" #. type: Plain text -#: doc/rust.md:1733 +#: doc/rust.md:1802 msgid "The following are examples of structure expressions:" msgstr "" #. type: Plain text -#: doc/rust.md:1744 +#: doc/rust.md:1813 msgid "" "~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, " "float); # mod game { pub struct User<'self> { name: &'self str, age: uint, " @@ -3371,7 +3520,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1747 +#: doc/rust.md:1816 msgid "" "A structure expression forms a new value of the named structure type. Note " "that for a given *unit-like* structure type, this will always be the same " @@ -3379,7 +3528,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1754 +#: doc/rust.md:1823 msgid "" "A structure expression can terminate with the syntax `..` followed by an " "expression to denote a functional update. The expression following `..` " @@ -3391,19 +3540,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1760 +#: doc/rust.md:1829 msgid "" "~~~~ # struct Point3d { x: int, y: int, z: int } let base = Point3d {x: 1, " "y: 2, z: 3}; Point3d {y: 0, z: 10, .. base}; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1762 +#: doc/rust.md:1831 msgid "### Record expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1768 +#: doc/rust.md:1837 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -3414,19 +3563,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1770 +#: doc/rust.md:1839 msgid "### Method-call expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1774 +#: doc/rust.md:1843 msgid "" "~~~~~~~~{.ebnf .gram} method_call_expr : expr '.' ident paren_expr_list ; " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1779 +#: doc/rust.md:1848 msgid "" "A _method call_ consists of an expression followed by a single dot, an " "identifier, and a parenthesized expression-list. Method calls are resolved " @@ -3437,17 +3586,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1782 +#: doc/rust.md:1851 msgid "### Field expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1786 +#: doc/rust.md:1855 msgid "~~~~~~~~{.ebnf .gram} field_expr : expr '.' ident ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1790 +#: doc/rust.md:1859 msgid "" "A _field expression_ consists of an expression followed by a single dot and " "an identifier, when not immediately followed by a parenthesized expression-" @@ -3456,12 +3605,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1795 +#: doc/rust.md:1864 msgid "~~~~~~~~ {.field} myrecord.myfield; {a: 10, b: 20}.a; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1798 +#: doc/rust.md:1867 msgid "" "A field access on a record is an [lvalue](#lvalues-rvalues-and-temporaries) " "referring to the value of that field. When the field is mutable, it can be " @@ -3469,7 +3618,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1801 +#: doc/rust.md:1870 msgid "" "When the type of the expression to the left of the dot is a pointer to a " "record or structure, it is automatically derferenced to make the field " @@ -3477,29 +3626,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1804 +#: doc/rust.md:1873 msgid "### Vector expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1807 +#: doc/rust.md:1876 msgid "~~~~~~~~{.ebnf .gram} vec_expr : '[' \"mut\"? vec_elems? ']'" msgstr "" #. type: Plain text -#: doc/rust.md:1810 +#: doc/rust.md:1879 msgid "vec_elems : [expr [',' expr]*] | [expr ',' \"..\" expr] ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1813 +#: doc/rust.md:1882 msgid "" "A [_vector_](#vector-types) _expression_ is written by enclosing zero or " "more comma-separated expressions of uniform type in square brackets." msgstr "" #. type: Plain text -#: doc/rust.md:1817 +#: doc/rust.md:1886 msgid "" "In the `[expr ',' \"..\" expr]` form, the expression after the `\"..\"` must " "be a constant expression that can be evaluated at compile time, such as a " @@ -3507,7 +3656,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1824 +#: doc/rust.md:1893 #, no-wrap msgid "" "~~~~\n" @@ -3519,17 +3668,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1826 +#: doc/rust.md:1895 msgid "### Index expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1830 +#: doc/rust.md:1899 msgid "~~~~~~~~{.ebnf .gram} idx_expr : expr '[' expr ']' ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1835 +#: doc/rust.md:1904 msgid "" "[Vector](#vector-types)-typed expressions can be indexed by writing a square-" "bracket-enclosed expression (the index) after them. When the vector is " @@ -3538,7 +3687,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1839 +#: doc/rust.md:1908 msgid "" "Indices are zero-based, and may be of any integral type. Vector access is " "bounds-checked at run-time. When the check fails, it will put the task in a " @@ -3546,27 +3695,27 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1843 +#: doc/rust.md:1912 msgid "~~~~ # use std::task; # do task::spawn_unlinked {" msgstr "" #. type: Plain text -#: doc/rust.md:1846 +#: doc/rust.md:1915 msgid "([1, 2, 3, 4])[0]; ([\"a\", \"b\"])[10]; // fails" msgstr "" #. type: Plain text -#: doc/rust.md:1849 doc/tutorial-tasks.md:649 +#: doc/rust.md:1918 doc/tutorial-tasks.md:649 msgid "# } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1851 +#: doc/rust.md:1920 msgid "### Unary operator expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1855 +#: doc/rust.md:1924 msgid "" "Rust defines six symbolic unary operators, in addition to the unary [copy]" "(#unary-copy-expressions) and [move](#unary-move-expressions) operators. " @@ -3575,7 +3724,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1874 +#: doc/rust.md:1943 #, no-wrap msgid "" "`-`\n" @@ -3599,29 +3748,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1876 +#: doc/rust.md:1945 msgid "### Binary operator expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1880 +#: doc/rust.md:1949 msgid "~~~~~~~~{.ebnf .gram} binop_expr : expr binop expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1883 +#: doc/rust.md:1952 msgid "" "Binary operators expressions are given in terms of [operator precedence]" "(#operator-precedence)." msgstr "" #. type: Plain text -#: doc/rust.md:1885 +#: doc/rust.md:1954 msgid "#### Arithmetic operators" msgstr "" #. type: Plain text -#: doc/rust.md:1890 +#: doc/rust.md:1959 msgid "" "Binary arithmetic expressions are syntactic sugar for calls to built-in " "traits, defined in the `std::ops` module of the `std` library. This means " @@ -3630,7 +3779,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1906 +#: doc/rust.md:1975 #, no-wrap msgid "" "`+`\n" @@ -3651,12 +3800,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1908 +#: doc/rust.md:1977 msgid "#### Bitwise operators" msgstr "" #. type: Plain text -#: doc/rust.md:1913 +#: doc/rust.md:1982 msgid "" "Like the [arithmetic operators](#arithmetic-operators), bitwise operators " "are syntactic sugar for calls to methods of built-in traits. This means " @@ -3665,7 +3814,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1929 +#: doc/rust.md:1998 #, no-wrap msgid "" "`&`\n" @@ -3686,12 +3835,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1931 +#: doc/rust.md:2000 msgid "#### Lazy boolean operators" msgstr "" #. type: Plain text -#: doc/rust.md:1938 +#: doc/rust.md:2007 msgid "" "The operators `||` and `&&` may be applied to operands of boolean type. The " "`||` operator denotes logical 'or', and the `&&` operator denotes logical " @@ -3703,12 +3852,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1940 +#: doc/rust.md:2009 msgid "#### Comparison operators" msgstr "" #. type: Plain text -#: doc/rust.md:1946 +#: doc/rust.md:2015 msgid "" "Comparison operators are, like the [arithmetic operators](#arithmetic-" "operators), and [bitwise operators](#bitwise-operators), syntactic sugar for " @@ -3718,7 +3867,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1965 +#: doc/rust.md:2034 #, no-wrap msgid "" "`==`\n" @@ -3742,24 +3891,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1968 +#: doc/rust.md:2037 msgid "#### Type cast expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1970 +#: doc/rust.md:2039 msgid "A type cast expression is denoted with the binary operator `as`." msgstr "" #. type: Plain text -#: doc/rust.md:1973 +#: doc/rust.md:2042 msgid "" "Executing an `as` expression casts the value on the left-hand side to the " "type on the right-hand side." msgstr "" #. type: Plain text -#: doc/rust.md:1977 +#: doc/rust.md:2046 msgid "" "A numeric value can be cast to any numeric type. A raw pointer value can be " "cast to or from any integral type or raw pointer type. Any other cast is " @@ -3767,19 +3916,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1979 +#: doc/rust.md:2048 msgid "An example of an `as` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:1983 +#: doc/rust.md:2052 msgid "" "~~~~ # fn sum(v: &[float]) -> float { 0.0 } # fn len(v: &[float]) -> int " "{ 0 }" msgstr "" #. type: Plain text -#: doc/rust.md:1990 +#: doc/rust.md:2059 #, no-wrap msgid "" "fn avg(v: &[float]) -> float {\n" @@ -3791,12 +3940,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1992 +#: doc/rust.md:2061 msgid "#### Assignment expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1995 +#: doc/rust.md:2064 msgid "" "An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-" "temporaries) expression followed by an equals sign (`=`) and an [rvalue]" @@ -3804,29 +3953,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1997 +#: doc/rust.md:2066 msgid "" "Evaluating an assignment expression [either copies or moves](#moved-and-" "copied-types) its right-hand operand to its left-hand operand." msgstr "" #. type: Plain text -#: doc/rust.md:2001 +#: doc/rust.md:2070 msgid "~~~~ # let mut x = 0; # let y = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2004 +#: doc/rust.md:2073 msgid "x = y; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2006 +#: doc/rust.md:2075 msgid "#### Compound assignment expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2011 +#: doc/rust.md:2080 msgid "" "The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be " "composed with the `=` operator. The expression `lval OP= val` is equivalent " @@ -3834,24 +3983,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2013 +#: doc/rust.md:2082 msgid "Any such expression always has the [`unit`](#primitive-types) type." msgstr "" #. type: Plain text -#: doc/rust.md:2015 +#: doc/rust.md:2084 msgid "#### Operator precedence" msgstr "" #. type: Plain text -#: doc/rust.md:2018 +#: doc/rust.md:2087 msgid "" "The precedence of Rust binary operators is ordered as follows, going from " "strong to weak:" msgstr "" #. type: Plain text -#: doc/rust.md:2031 +#: doc/rust.md:2100 #, no-wrap msgid "" "~~~~ {.precedence}\n" @@ -3870,12 +4019,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2033 doc/rust.md:2174 doc/tutorial-macros.md:323 +#: doc/rust.md:2102 doc/rust.md:2243 doc/tutorial-macros.md:323 msgid "~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2036 +#: doc/rust.md:2105 msgid "" "Operators at the same precedence level are evaluated left-to-right. [Unary " "operators](#unary-operator-expressions) have the same precedence level and " @@ -3883,12 +4032,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2038 +#: doc/rust.md:2107 msgid "### Grouped expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2042 +#: doc/rust.md:2111 msgid "" "An expression enclosed in parentheses evaluates to the result of the " "enclosed expression. Parentheses can be used to explicitly specify " @@ -3896,46 +4045,46 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2046 +#: doc/rust.md:2115 msgid "~~~~~~~~{.ebnf .gram} paren_expr : '(' expr ')' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2048 +#: doc/rust.md:2117 msgid "An example of a parenthesized expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2052 +#: doc/rust.md:2121 msgid "~~~~ let x = (2 + 3) * 4; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2054 +#: doc/rust.md:2123 msgid "### Unary copy expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2058 +#: doc/rust.md:2127 msgid "~~~~~~~~{.ebnf .gram} copy_expr : \"copy\" expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2061 +#: doc/rust.md:2130 msgid "" "> **Note:** `copy` expressions are deprecated. It's preferable to use > the " "`Clone` trait and `clone()` method." msgstr "" #. type: Plain text -#: doc/rust.md:2064 +#: doc/rust.md:2133 msgid "" "A _unary copy expression_ consists of the unary `copy` operator applied to " "some argument expression." msgstr "" #. type: Plain text -#: doc/rust.md:2068 +#: doc/rust.md:2137 msgid "" "Evaluating a copy expression first evaluates the argument expression, then " "copies the resulting value, allocating any memory necessary to hold the new " @@ -3943,7 +4092,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2072 +#: doc/rust.md:2141 msgid "" "[Managed boxes](#pointer-types) (type `@`) are, as usual, shallow-copied, as " "are raw and borrowed pointers. [Owned boxes](#pointer-types), [owned " @@ -3951,7 +4100,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2075 +#: doc/rust.md:2144 msgid "" "Since the binary [assignment operator](#assignment-expressions) `=` performs " "a copy or move implicitly, the unary copy operator is typically only used to " @@ -3959,12 +4108,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2077 +#: doc/rust.md:2146 msgid "An example of a copy expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2082 +#: doc/rust.md:2151 #, no-wrap msgid "" "~~~~\n" @@ -3974,33 +4123,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2084 +#: doc/rust.md:2153 msgid "let v = ~[1,2,3];" msgstr "" #. type: Plain text -#: doc/rust.md:2086 +#: doc/rust.md:2155 #, no-wrap msgid "mutate(copy v); // Pass a copy\n" msgstr "" #. type: Plain text -#: doc/rust.md:2089 +#: doc/rust.md:2158 msgid "assert!(v[0] == 1); // Original was not modified ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2091 +#: doc/rust.md:2160 msgid "### Unary move expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2095 +#: doc/rust.md:2164 msgid "~~~~~~~~{.ebnf .gram} move_expr : \"move\" expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2102 +#: doc/rust.md:2171 msgid "" "A _unary move expression_ is similar to a [unary copy](#unary-copy-" "expressions) expression, except that it can only be applied to a [local " @@ -4011,7 +4160,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2106 +#: doc/rust.md:2175 msgid "" "> **Note:** In future versions of Rust, `move` may be removed as a separate " "operator; > moves are now [automatically performed](#moved-and-copied-types) " @@ -4019,12 +4168,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2109 +#: doc/rust.md:2178 msgid "### Call expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2115 +#: doc/rust.md:2184 msgid "" "~~~~~~~~ {.abnf .gram} expr_list : [ expr [ ',' expr ]* ] ? ; " "paren_expr_list : '(' expr_list ')' ; call_expr : expr paren_expr_list ; " @@ -4032,7 +4181,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2120 +#: doc/rust.md:2189 msgid "" "A _call expression_ invokes a function, providing zero or more input slots " "and an optional reference slot to serve as the function's output, bound to " @@ -4041,36 +4190,36 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2122 +#: doc/rust.md:2191 msgid "Some examples of call expressions:" msgstr "" #. type: Plain text -#: doc/rust.md:2126 +#: doc/rust.md:2195 msgid "" "~~~~ # use std::from_str::FromStr; # fn add(x: int, y: int) -> int { 0 }" msgstr "" #. type: Plain text -#: doc/rust.md:2130 +#: doc/rust.md:2199 msgid "" "let x: int = add(1, 2); let pi = FromStr::from_str::(\"3.14\"); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2132 +#: doc/rust.md:2201 msgid "### Lambda expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2137 +#: doc/rust.md:2206 msgid "" "~~~~~~~~ {.abnf .gram} ident_list : [ ident [ ',' ident ]* ] ? ; " "lambda_expr : '|' ident_list '|' expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2141 +#: doc/rust.md:2210 msgid "" "A _lambda expression_ (sometimes called an \"anonymous function expression" "\") defines a function and denotes it as a value, in a single expression. A " @@ -4079,7 +4228,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2146 +#: doc/rust.md:2215 msgid "" "A lambda expression denotes a function that maps a list of parameters " "(`ident_list`) onto the expression that follows the `ident_list`. The " @@ -4089,7 +4238,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2149 +#: doc/rust.md:2218 msgid "" "Lambda expressions are most useful when passing functions as arguments to " "other functions, as an abbreviation for defining and capturing a separate " @@ -4097,7 +4246,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2158 +#: doc/rust.md:2227 msgid "" "Significantly, lambda expressions _capture their environment_, which regular " "[function definitions](#functions) do not. The exact type of capture " @@ -4111,14 +4260,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2161 +#: doc/rust.md:2230 msgid "" "In this example, we define a function `ten_times` that takes a higher-order " "function argument, and call it with a lambda expression as an argument." msgstr "" #. type: Plain text -#: doc/rust.md:2170 +#: doc/rust.md:2239 #, no-wrap msgid "" "~~~~\n" @@ -4132,23 +4281,23 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2172 +#: doc/rust.md:2241 msgid "ten_times(|j| println(fmt!(\"hello, %d\", j)));" msgstr "" #. type: Plain text -#: doc/rust.md:2176 +#: doc/rust.md:2245 msgid "### While loops" msgstr "" #. type: Plain text -#: doc/rust.md:2180 +#: doc/rust.md:2249 msgid "" "~~~~~~~~{.ebnf .gram} while_expr : \"while\" expr '{' block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2185 +#: doc/rust.md:2254 msgid "" "A `while` loop begins by evaluating the boolean loop conditional " "expression. If the loop conditional expression evaluates to `true`, the " @@ -4158,17 +4307,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2187 +#: doc/rust.md:2256 msgid "An example:" msgstr "" #. type: Plain text -#: doc/rust.md:2190 +#: doc/rust.md:2259 msgid "~~~~ let mut i = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2196 +#: doc/rust.md:2265 #, no-wrap msgid "" "while i < 10 {\n" @@ -4179,12 +4328,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2198 +#: doc/rust.md:2267 msgid "### Infinite loops" msgstr "" #. type: Plain text -#: doc/rust.md:2202 +#: doc/rust.md:2271 msgid "" "The keyword `loop` in Rust appears both in _loop expressions_ and in " "_continue expressions_. A loop expression denotes an infinite loop; see " @@ -4192,14 +4341,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2206 +#: doc/rust.md:2275 msgid "" "~~~~~~~~{.ebnf .gram} loop_expr : [ lifetime ':' ] \"loop\" '{' block '}'; " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2211 +#: doc/rust.md:2280 msgid "" "A `loop` expression may optionally have a _label_. If a label is present, " "then labeled `break` and `loop` expressions nested within this loop may exit " @@ -4208,17 +4357,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2213 +#: doc/rust.md:2282 msgid "### Break expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2217 +#: doc/rust.md:2286 msgid "~~~~~~~~{.ebnf .gram} break_expr : \"break\" [ lifetime ]; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2224 +#: doc/rust.md:2293 msgid "" "A `break` expression has an optional `label`. If the label is absent, then " "executing a `break` expression immediately terminates the innermost loop " @@ -4229,17 +4378,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2226 +#: doc/rust.md:2295 msgid "### Continue expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2230 +#: doc/rust.md:2299 msgid "~~~~~~~~{.ebnf .gram} continue_expr : \"loop\" [ lifetime ]; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2241 +#: doc/rust.md:2310 msgid "" "A continue expression, written `loop`, also has an optional `label`. If the " "label is absent, then executing a `loop` expression immediately terminates " @@ -4253,24 +4402,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2243 +#: doc/rust.md:2312 msgid "A `loop` expression is only permitted in the body of a loop." msgstr "" #. type: Plain text -#: doc/rust.md:2246 +#: doc/rust.md:2315 msgid "### Do expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2250 +#: doc/rust.md:2319 msgid "" "~~~~~~~~{.ebnf .gram} do_expr : \"do\" expr [ '|' ident_list '|' ] ? '{' " "block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2253 +#: doc/rust.md:2322 msgid "" "A _do expression_ provides a more-familiar block-syntax for a [lambda " "expression](#lambda-expressions), including a special translation of [return " @@ -4278,7 +4427,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2261 +#: doc/rust.md:2330 msgid "" "Any occurrence of a [return expression](#return-expressions) inside this " "`block` expression is rewritten as a reference to an (anonymous) flag set in " @@ -4290,7 +4439,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2264 +#: doc/rust.md:2333 msgid "" "The optional `ident_list` and `block` provided in a `do` expression are " "parsed as though they constitute a lambda expression; if the `ident_list` is " @@ -4298,7 +4447,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2270 +#: doc/rust.md:2339 msgid "" "The lambda expression is then provided as a _trailing argument_ to the " "outermost [call](#call-expressions) or [method call](#method-call-" @@ -4309,22 +4458,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2272 +#: doc/rust.md:2341 msgid "In this example, both calls to `f` are equivalent:" msgstr "" #. type: Plain text -#: doc/rust.md:2276 +#: doc/rust.md:2345 msgid "~~~~ # fn f(f: &fn(int)) { } # fn g(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2278 +#: doc/rust.md:2347 msgid "f(|j| g(j));" msgstr "" #. type: Plain text -#: doc/rust.md:2283 +#: doc/rust.md:2352 #, no-wrap msgid "" "do f |j| {\n" @@ -4334,23 +4483,23 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2285 +#: doc/rust.md:2354 msgid "" "In this example, both calls to the (binary) function `k` are equivalent:" msgstr "" #. type: Plain text -#: doc/rust.md:2289 +#: doc/rust.md:2358 msgid "~~~~ # fn k(x:int, f: &fn(int)) { } # fn l(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2291 +#: doc/rust.md:2360 msgid "k(3, |j| l(j));" msgstr "" #. type: Plain text -#: doc/rust.md:2296 +#: doc/rust.md:2365 #, no-wrap msgid "" "do k(3) |j| {\n" @@ -4360,19 +4509,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2299 +#: doc/rust.md:2368 msgid "### For expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2303 +#: doc/rust.md:2372 msgid "" "~~~~~~~~{.ebnf .gram} for_expr : \"for\" expr [ '|' ident_list '|' ] ? '{' " "block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2307 +#: doc/rust.md:2376 msgid "" "A _for expression_ is similar to a [`do` expression](#do-expressions), in " "that it provides a special block-form of lambda expression, suited to " @@ -4380,7 +4529,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2313 +#: doc/rust.md:2382 msgid "" "In contrast to a `do` expression, a `for` expression is designed to work " "with methods such as `each` and `times`, that require the body block to " @@ -4390,7 +4539,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2320 +#: doc/rust.md:2389 msgid "" "In addition, [`break`](#break-expressions) and [`loop`](#loop-expressions) " "expressions are rewritten inside `for` expressions in the same way that " @@ -4401,24 +4550,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2322 +#: doc/rust.md:2391 msgid "An example of a for loop over the contents of a vector:" msgstr "" #. type: Plain text -#: doc/rust.md:2329 +#: doc/rust.md:2398 msgid "" "~~~~ # type foo = int; # fn bar(f: foo) { } # let a = 0; # let b = 0; # let " "c = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2331 +#: doc/rust.md:2400 msgid "let v: &[foo] = &[a, b, c];" msgstr "" #. type: Plain text -#: doc/rust.md:2336 +#: doc/rust.md:2405 #, no-wrap msgid "" "for v.iter().advance |e| {\n" @@ -4428,12 +4577,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2338 +#: doc/rust.md:2407 msgid "An example of a for loop over a series of integers:" msgstr "" #. type: Plain text -#: doc/rust.md:2346 +#: doc/rust.md:2415 #, no-wrap msgid "" "~~~~\n" @@ -4446,12 +4595,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2348 +#: doc/rust.md:2417 msgid "### If expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2352 +#: doc/rust.md:2421 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -4460,7 +4609,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2356 +#: doc/rust.md:2425 #, no-wrap msgid "" "else_tail : \"else\" [ if_expr\n" @@ -4469,7 +4618,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2367 +#: doc/rust.md:2436 msgid "" "An `if` expression is a conditional branch in program control. The form of " "an `if` expression is a condition expression, followed by a consequent " @@ -4483,29 +4632,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2370 +#: doc/rust.md:2439 msgid "### Match expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2373 +#: doc/rust.md:2442 msgid "" "~~~~~~~~{.ebnf .gram} match_expr : \"match\" expr '{' match_arm [ '|' " "match_arm ] * '}' ;" msgstr "" #. type: Plain text -#: doc/rust.md:2375 +#: doc/rust.md:2444 msgid "match_arm : match_pat '=>' [ expr \",\" | '{' block '}' ] ;" msgstr "" #. type: Plain text -#: doc/rust.md:2378 +#: doc/rust.md:2447 msgid "match_pat : pat [ \"..\" pat ] ? [ \"if\" expr ] ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2386 +#: doc/rust.md:2455 msgid "" "A `match` expression branches on a *pattern*. The exact form of matching " "that occurs depends on the pattern. Patterns consist of some combination of " @@ -4517,7 +4666,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2390 +#: doc/rust.md:2459 msgid "" "In a pattern whose head expression has an `enum` type, a placeholder (`_`) " "stands for a *single* data field, whereas a wildcard `*` stands for *all* " @@ -4525,17 +4674,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2393 +#: doc/rust.md:2462 msgid "~~~~ enum List { Nil, Cons(X, @List) }" msgstr "" #. type: Plain text -#: doc/rust.md:2395 doc/rust.md:2424 +#: doc/rust.md:2464 doc/rust.md:2493 msgid "let x: List = Cons(10, @Cons(11, @Nil));" msgstr "" #. type: Plain text -#: doc/rust.md:2402 +#: doc/rust.md:2471 #, no-wrap msgid "" "match x {\n" @@ -4547,7 +4696,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2407 +#: doc/rust.md:2476 msgid "" "The first pattern matches lists constructed by applying `Cons` to any head " "value, and a tail value of `@Nil`. The second pattern matches _any_ list " @@ -4558,7 +4707,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2413 +#: doc/rust.md:2482 msgid "" "To execute an `match` expression, first the head expression is evaluated, " "then its value is sequentially compared to the patterns in the arms until a " @@ -4568,22 +4717,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2415 +#: doc/rust.md:2484 msgid "An example of an `match` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2420 +#: doc/rust.md:2489 msgid "~~~~ # fn process_pair(a: int, b: int) { } # fn process_ten() { }" msgstr "" #. type: Plain text -#: doc/rust.md:2422 +#: doc/rust.md:2491 msgid "enum List { Nil, Cons(X, @List) }" msgstr "" #. type: Plain text -#: doc/rust.md:2440 +#: doc/rust.md:2509 #, no-wrap msgid "" "match x {\n" @@ -4604,7 +4753,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2446 +#: doc/rust.md:2515 msgid "" "Patterns that bind variables default to binding to a copy or move of the " "matched value (depending on the matched value's type). This can be made " @@ -4614,7 +4763,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2457 +#: doc/rust.md:2526 msgid "" "A pattern that's just an identifier, like `Nil` in the previous answer, " "could either refer to an enum variant that's in scope, or bind a new " @@ -4629,19 +4778,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2461 +#: doc/rust.md:2530 msgid "" "Multiple match patterns may be joined with the `|` operator. A range of " "values may be specified with `..`. For example:" msgstr "" #. type: Plain text -#: doc/rust.md:2464 +#: doc/rust.md:2533 msgid "~~~~ # let x = 2;" msgstr "" #. type: Plain text -#: doc/rust.md:2471 +#: doc/rust.md:2540 #, no-wrap msgid "" "let message = match x {\n" @@ -4653,7 +4802,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2475 +#: doc/rust.md:2544 msgid "" "Range patterns only work on scalar types (like integers and characters; not " "like vectors and structs, which have sub-components). A range pattern may " @@ -4661,7 +4810,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2480 +#: doc/rust.md:2549 msgid "" "Finally, match patterns can accept *pattern guards* to further refine the " "criteria for matching a case. Pattern guards appear after the pattern and " @@ -4670,14 +4819,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2485 +#: doc/rust.md:2554 msgid "" "~~~~ # let maybe_digit = Some(0); # fn process_digit(i: int) { } # fn " "process_other(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2492 +#: doc/rust.md:2561 #, no-wrap msgid "" "let message = match maybe_digit {\n" @@ -4689,17 +4838,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2494 +#: doc/rust.md:2563 msgid "### Return expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2498 +#: doc/rust.md:2567 msgid "~~~~~~~~{.ebnf .gram} return_expr : \"return\" expr ? ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2503 +#: doc/rust.md:2572 msgid "" "Return expressions are denoted with the keyword `return`. Evaluating a " "`return` expression moves its argument into the output slot of the current " @@ -4708,12 +4857,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2505 +#: doc/rust.md:2574 msgid "An example of a `return` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2514 +#: doc/rust.md:2583 #, no-wrap msgid "" "~~~~\n" @@ -4727,24 +4876,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2517 +#: doc/rust.md:2586 msgid "# Type system" msgstr "" #. type: Plain text -#: doc/rust.md:2519 +#: doc/rust.md:2588 msgid "## Types" msgstr "" #. type: Plain text -#: doc/rust.md:2522 +#: doc/rust.md:2591 msgid "" "Every slot, item and value in a Rust program has a type. The _type_ of a " "*value* defines the interpretation of the memory holding it." msgstr "" #. type: Plain text -#: doc/rust.md:2526 +#: doc/rust.md:2595 msgid "" "Built-in types and type-constructors are tightly integrated into the " "language, in nontrivial ways that are not possible to emulate in user-" @@ -4752,17 +4901,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2528 +#: doc/rust.md:2597 msgid "### Primitive types" msgstr "" #. type: Plain text -#: doc/rust.md:2530 +#: doc/rust.md:2599 msgid "The primitive types are the following:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "" "The \"unit\" type `()`, having the single \"unit\" value `()` (occasionally " "called \"nil\"). ^[The \"unit\" value `()` is *not* a sentinel \"null " @@ -4773,32 +4922,32 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The boolean type `bool` with values `true` and `false`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The machine types." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The machine-dependent integer and floating-point types." msgstr "" #. type: Plain text -#: doc/rust.md:2538 +#: doc/rust.md:2607 msgid "#### Machine types" msgstr "" #. type: Plain text -#: doc/rust.md:2540 +#: doc/rust.md:2609 msgid "The machine types are the following:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2545 +#: doc/rust.md:2614 msgid "" "The unsigned word types `u8`, `u16`, `u32` and `u64`, with values drawn from " "the integer intervals $[0, 2^8 - 1]$, $[0, 2^{16} - 1]$, $[0, 2^{32} - 1]$ " @@ -4806,7 +4955,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2550 +#: doc/rust.md:2619 msgid "" "The signed two's complement word types `i8`, `i16`, `i32` and `i64`, with " "values drawn from the integer intervals $[-(2^7), 2^7 - 1]$, $[-(2^{15}), " @@ -4815,19 +4964,19 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2553 +#: doc/rust.md:2622 msgid "" "The IEEE 754-2008 `binary32` and `binary64` floating-point types: `f32` and " "`f64`, respectively." msgstr "" #. type: Plain text -#: doc/rust.md:2555 +#: doc/rust.md:2624 msgid "#### Machine-dependent integer types" msgstr "" #. type: Plain text -#: doc/rust.md:2560 +#: doc/rust.md:2629 msgid "" "The Rust type `uint`^[A Rust `uint` is analogous to a C99 `uintptr_t`.] is " "an unsigned integer type with target-machine-dependent size. Its size, in " @@ -4836,7 +4985,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2565 +#: doc/rust.md:2634 msgid "" "The Rust type `int`^[A Rust `int` is analogous to a C99 `intptr_t`.] is a " "two's complement signed integer type with target-machine-dependent size. Its " @@ -4845,12 +4994,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2568 +#: doc/rust.md:2637 msgid "#### Machine-dependent floating point type" msgstr "" #. type: Plain text -#: doc/rust.md:2575 +#: doc/rust.md:2644 msgid "" "The Rust type `float` is a machine-specific type equal to one of the " "supported Rust floating-point machine types (`f32` or `f64`). It is the " @@ -4861,31 +5010,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2578 +#: doc/rust.md:2647 msgid "" "Note that due to the preference for hardware-supported floating-point, the " "type `float` may not be equal to the largest *supported* floating-point type." msgstr "" #. type: Plain text -#: doc/rust.md:2581 +#: doc/rust.md:2650 msgid "### Textual types" msgstr "" #. type: Plain text -#: doc/rust.md:2583 +#: doc/rust.md:2652 msgid "The types `char` and `str` hold textual data." msgstr "" #. type: Plain text -#: doc/rust.md:2586 +#: doc/rust.md:2655 msgid "" "A value of type `char` is a Unicode character, represented as a 32-bit " "unsigned word holding a UCS-4 codepoint." msgstr "" #. type: Plain text -#: doc/rust.md:2592 +#: doc/rust.md:2661 msgid "" "A value of type `str` is a Unicode string, represented as a vector of 8-bit " "unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of " @@ -4894,61 +5043,61 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2595 +#: doc/rust.md:2664 msgid "### Tuple types" msgstr "" #. type: Plain text -#: doc/rust.md:2598 +#: doc/rust.md:2667 msgid "" "The tuple type-constructor forms a new heterogeneous product of values " "similar to the record type-constructor. The differences are as follows:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2601 +#: doc/rust.md:2670 msgid "tuple elements cannot be mutable, unlike record fields" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2601 +#: doc/rust.md:2670 msgid "" "tuple elements are not named and can be accessed only by pattern-matching" msgstr "" #. type: Plain text -#: doc/rust.md:2605 +#: doc/rust.md:2674 msgid "" "Tuple types and values are denoted by listing the types or values of their " "elements, respectively, in a parenthesized, comma-separated list." msgstr "" #. type: Plain text -#: doc/rust.md:2608 +#: doc/rust.md:2677 msgid "" "The members of a tuple are laid out in memory contiguously, like a record, " "in order specified by the tuple type." msgstr "" #. type: Plain text -#: doc/rust.md:2610 +#: doc/rust.md:2679 msgid "An example of a tuple type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2617 +#: doc/rust.md:2686 msgid "" "~~~~ type Pair<'self> = (int,&'self str); let p: Pair<'static> = (10,\"hello" "\"); let (a, b) = p; assert!(b != \"world\"); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2620 +#: doc/rust.md:2689 msgid "### Vector types" msgstr "" #. type: Plain text -#: doc/rust.md:2633 +#: doc/rust.md:2702 msgid "" "The vector type constructor represents a homogeneous array of values of a " "given type. A vector has a fixed size. (Operations like `vec.push` operate " @@ -4963,7 +5112,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2637 +#: doc/rust.md:2706 msgid "" "Expressions producing vectors of definite size cannot be evaluated in a " "context expecting a vector of indefinite size; one must copy the definite-" @@ -4971,30 +5120,30 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2639 +#: doc/rust.md:2708 msgid "An example of a vector type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2645 +#: doc/rust.md:2714 msgid "" "~~~~ let v: &[int] = &[7, 5, 3]; let i: int = v[2]; assert!(i == 3); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2648 +#: doc/rust.md:2717 msgid "" "All in-bounds elements of a vector are always initialized, and access to a " "vector is always bounds-checked." msgstr "" #. type: Plain text -#: doc/rust.md:2651 +#: doc/rust.md:2720 msgid "### Structure types" msgstr "" #. type: Plain text -#: doc/rust.md:2656 +#: doc/rust.md:2725 msgid "" "A `struct` *type* is a heterogeneous product of other types, called the " "*fields* of the type. ^[`struct` types are analogous `struct` types in C, " @@ -5003,14 +5152,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2658 +#: doc/rust.md:2727 msgid "" "New instances of a `struct` can be constructed with a [struct expression]" "(#struct-expressions)." msgstr "" #. type: Plain text -#: doc/rust.md:2662 +#: doc/rust.md:2731 msgid "" "The memory order of fields in a `struct` is given by the item defining it. " "Fields may be given in any order in a corresponding struct *expression*; the " @@ -5019,7 +5168,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2665 +#: doc/rust.md:2734 msgid "" "The fields of a `struct` may be qualified by [visibility modifiers]" "(#visibility-modifiers), to restrict access to implementation-private data " @@ -5027,14 +5176,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2667 +#: doc/rust.md:2736 msgid "" "A _tuple struct_ type is just like a structure type, except that the fields " "are anonymous." msgstr "" #. type: Plain text -#: doc/rust.md:2670 +#: doc/rust.md:2739 msgid "" "A _unit-like struct_ type is like a structure type, except that it has no " "fields. The one value constructed by the associated [structure expression]" @@ -5042,12 +5191,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2672 +#: doc/rust.md:2741 msgid "### Enumerated types" msgstr "" #. type: Plain text -#: doc/rust.md:2677 +#: doc/rust.md:2746 msgid "" "An *enumerated type* is a nominal, heterogeneous disjoint union type, " "denoted by the name of an [`enum` item](#enumerations). ^[The `enum` type " @@ -5056,7 +5205,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2680 +#: doc/rust.md:2749 msgid "" "An [`enum` item](#enumerations) declares both the type and a number of " "*variant constructors*, each of which is independently named and takes an " @@ -5064,33 +5213,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2683 +#: doc/rust.md:2752 msgid "" "New instances of an `enum` can be constructed by calling one of the variant " "constructors, in a [call expression](#call-expressions)." msgstr "" #. type: Plain text -#: doc/rust.md:2685 +#: doc/rust.md:2754 msgid "" "Any `enum` value consumes as much memory as the largest variant constructor " "for its corresponding `enum` type." msgstr "" #. type: Plain text -#: doc/rust.md:2688 +#: doc/rust.md:2757 msgid "" "Enum types cannot be denoted *structurally* as types, but must be denoted by " "named reference to an [`enum` item](#enumerations)." msgstr "" #. type: Plain text -#: doc/rust.md:2691 +#: doc/rust.md:2760 msgid "### Recursive types" msgstr "" #. type: Plain text -#: doc/rust.md:2695 +#: doc/rust.md:2764 msgid "" "Nominal types -- [enumerations](#enumerated-types) and [structures]" "(#structure-types) -- may be recursive. That is, each `enum` constructor or " @@ -5099,7 +5248,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2705 +#: doc/rust.md:2774 #, no-wrap msgid "" "* Recursive types must include a nominal type in the recursion\n" @@ -5114,12 +5263,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2707 +#: doc/rust.md:2776 msgid "An example of a *recursive* type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2713 +#: doc/rust.md:2782 #, no-wrap msgid "" "~~~~\n" @@ -5130,17 +5279,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2716 +#: doc/rust.md:2785 msgid "let a: List = Cons(7, @Cons(13, @Nil)); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2719 +#: doc/rust.md:2788 msgid "### Pointer types" msgstr "" #. type: Plain text -#: doc/rust.md:2723 +#: doc/rust.md:2792 msgid "" "All pointers in Rust are explicit first-class values. They can be copied, " "stored into data structures, and returned from functions. There are four " @@ -5148,7 +5297,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2733 +#: doc/rust.md:2802 #, no-wrap msgid "" "Managed pointers (`@`)\n" @@ -5163,7 +5312,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2742 +#: doc/rust.md:2811 #, no-wrap msgid "" "Owning pointers (`~`)\n" @@ -5177,7 +5326,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2755 +#: doc/rust.md:2824 #, no-wrap msgid "" "Borrowed pointers (`&`)\n" @@ -5195,7 +5344,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2765 +#: doc/rust.md:2834 #, no-wrap msgid "" "Raw pointers (`*`)\n" @@ -5210,12 +5359,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2768 +#: doc/rust.md:2837 msgid "### Function types" msgstr "" #. type: Plain text -#: doc/rust.md:2772 +#: doc/rust.md:2841 msgid "" "The function type constructor `fn` forms new function types. A function " "type consists of a possibly-empty set of function-type modifiers (such as " @@ -5223,12 +5372,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2774 +#: doc/rust.md:2843 msgid "An example of a `fn` type:" msgstr "" #. type: Plain text -#: doc/rust.md:2779 +#: doc/rust.md:2848 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5238,24 +5387,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2781 +#: doc/rust.md:2850 msgid "let mut x = add(5,7);" msgstr "" #. type: Plain text -#: doc/rust.md:2786 +#: doc/rust.md:2855 msgid "" "type Binop<'self> = &'self fn(int,int) -> int; let bo: Binop = add; x = " "bo(5,7); ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2788 +#: doc/rust.md:2857 msgid "### Object types" msgstr "" #. type: Plain text -#: doc/rust.md:2795 +#: doc/rust.md:2864 msgid "" "Every trait item (see [traits](#traits)) defines a type with the same name " "as the trait. This type is called the _object type_ of the trait. Object " @@ -5268,7 +5417,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2800 +#: doc/rust.md:2869 msgid "" "Given a pointer-typed expression `E` of type `&T`, `~T` or `@T`, where `T` " "implements trait `R`, casting `E` to the corresponding pointer type `&R`, " @@ -5278,12 +5427,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2802 +#: doc/rust.md:2871 msgid "An example of an object type:" msgstr "" #. type: Plain text -#: doc/rust.md:2808 +#: doc/rust.md:2877 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5294,7 +5443,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2812 +#: doc/rust.md:2881 #, no-wrap msgid "" "impl Printable for int {\n" @@ -5303,7 +5452,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2816 +#: doc/rust.md:2885 #, no-wrap msgid "" "fn print(a: @Printable) {\n" @@ -5312,7 +5461,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2821 +#: doc/rust.md:2890 #, no-wrap msgid "" "fn main() {\n" @@ -5322,26 +5471,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2824 +#: doc/rust.md:2893 msgid "" "In this example, the trait `Printable` occurs as an object type in both the " "type signature of `print`, and the cast expression in `main`." msgstr "" #. type: Plain text -#: doc/rust.md:2826 +#: doc/rust.md:2895 msgid "### Type parameters" msgstr "" #. type: Plain text -#: doc/rust.md:2828 +#: doc/rust.md:2897 msgid "" "Within the body of an item that has type parameter declarations, the names " "of its type parameters are types:" msgstr "" #. type: Plain text -#: doc/rust.md:2837 +#: doc/rust.md:2906 #, no-wrap msgid "" "~~~~~~~\n" @@ -5355,26 +5504,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2840 +#: doc/rust.md:2909 msgid "" "Here, `first` has type `B`, referring to `map`'s `B` type parameter; and " "`rest` has type `~[B]`, a vector type with element type `B`." msgstr "" #. type: Plain text -#: doc/rust.md:2842 +#: doc/rust.md:2911 msgid "### Self types" msgstr "" #. type: Plain text -#: doc/rust.md:2846 +#: doc/rust.md:2915 msgid "" "The special type `self` has a meaning within methods inside an impl item. It " "refers to the type of the implicit `self` argument. For example, in:" msgstr "" #. type: Plain text -#: doc/rust.md:2851 +#: doc/rust.md:2920 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5384,7 +5533,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2856 +#: doc/rust.md:2925 #, no-wrap msgid "" "impl Printable for ~str {\n" @@ -5394,26 +5543,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2859 +#: doc/rust.md:2928 msgid "" "`self` refers to the value of type `~str` that is the receiver for a call to " "the method `make_string`." msgstr "" #. type: Plain text -#: doc/rust.md:2861 +#: doc/rust.md:2930 msgid "## Type kinds" msgstr "" #. type: Plain text -#: doc/rust.md:2864 +#: doc/rust.md:2933 msgid "" "Types in Rust are categorized into kinds, based on various properties of the " "components of the type. The kinds are:" msgstr "" #. type: Plain text -#: doc/rust.md:2884 +#: doc/rust.md:2953 #, no-wrap msgid "" "`Freeze`\n" @@ -5438,7 +5587,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2891 +#: doc/rust.md:2960 #, no-wrap msgid "" "_Default_\n" @@ -5450,20 +5599,20 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2894 +#: doc/rust.md:2963 msgid "" "Kinds can be supplied as _bounds_ on type parameters, like traits, in which " "case the parameter is constrained to types satisfying that kind." msgstr "" #. type: Plain text -#: doc/rust.md:2896 +#: doc/rust.md:2965 msgid "" "By default, type parameters do not carry any assumed kind-bounds at all." msgstr "" #. type: Plain text -#: doc/rust.md:2900 +#: doc/rust.md:2969 msgid "" "Any operation that causes a value to be copied requires the type of that " "value to be of copyable kind, so the `Copy` bound is frequently required on " @@ -5471,24 +5620,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2904 +#: doc/rust.md:2973 msgid "~~~~{.xfail-test} fn box(x: T) -> @T { @x } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2907 +#: doc/rust.md:2976 msgid "" "Putting `x` into a managed box involves copying, and the `T` parameter has " "the default (non-copyable) kind. To change that, a bound is declared:" msgstr "" #. type: Plain text -#: doc/rust.md:2911 +#: doc/rust.md:2980 msgid "~~~~ fn box(x: T) -> @T { @x } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2916 +#: doc/rust.md:2985 msgid "" "Calling this second version of `box` on a noncopyable type is not allowed. " "When instantiating a type parameter, the kind bounds on the parameter are " @@ -5497,7 +5646,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2920 +#: doc/rust.md:2989 msgid "" "Sending operations are not part of the Rust language, but are implemented in " "the library. Generic functions that send values bound the kind of these " @@ -5505,12 +5654,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2922 +#: doc/rust.md:2991 msgid "# Memory and concurrency models" msgstr "" #. type: Plain text -#: doc/rust.md:2927 +#: doc/rust.md:2996 msgid "" "Rust has a memory model centered around concurrently-executing _tasks_. Thus " "its memory model and its concurrency model are best discussed " @@ -5519,7 +5668,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2932 +#: doc/rust.md:3001 msgid "" "When reading about the memory model, keep in mind that it is partitioned in " "order to support tasks; and when reading about tasks, keep in mind that " @@ -5528,12 +5677,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2934 +#: doc/rust.md:3003 msgid "## Memory model" msgstr "" #. type: Plain text -#: doc/rust.md:2938 +#: doc/rust.md:3007 msgid "" "A Rust program's memory consists of a static set of *items*, a set of [tasks]" "(#tasks) each with its own *stack*, and a *heap*. Immutable portions of the " @@ -5541,19 +5690,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2941 +#: doc/rust.md:3010 msgid "" "Allocations in the stack consist of *slots*, and allocations in the heap " "consist of *boxes*." msgstr "" #. type: Plain text -#: doc/rust.md:2944 +#: doc/rust.md:3013 msgid "### Memory allocation and lifetime" msgstr "" #. type: Plain text -#: doc/rust.md:2949 +#: doc/rust.md:3018 msgid "" "The _items_ of a program are those functions, modules and types that have " "their value calculated at compile-time and stored uniquely in the memory " @@ -5561,7 +5710,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2953 +#: doc/rust.md:3022 msgid "" "A task's _stack_ consists of activation frames automatically allocated on " "entry to each function as the task executes. A stack allocation is reclaimed " @@ -5569,7 +5718,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2960 +#: doc/rust.md:3029 msgid "" "The _heap_ is a general term that describes two separate sets of boxes: " "managed boxes -- which may be subject to garbage collection -- and owned " @@ -5580,19 +5729,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2962 +#: doc/rust.md:3031 msgid "### Memory ownership" msgstr "" #. type: Plain text -#: doc/rust.md:2965 +#: doc/rust.md:3034 msgid "" "A task owns all memory it can *safely* reach through local variables, as " "well as managed, owning and borrowed pointers." msgstr "" #. type: Plain text -#: doc/rust.md:2972 +#: doc/rust.md:3041 msgid "" "When a task sends a value that has the `Send` trait to another task, it " "loses ownership of the value sent and can no longer refer to it. This is " @@ -5603,14 +5752,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2975 +#: doc/rust.md:3044 msgid "" "When a stack frame is exited, its local allocations are all released, and " "its references to boxes (both managed and owned) are dropped." msgstr "" #. type: Plain text -#: doc/rust.md:2981 +#: doc/rust.md:3050 msgid "" "A managed box may (in the case of a recursive, mutable managed type) be " "cyclic; in this case the release of memory inside the managed structure may " @@ -5620,38 +5769,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2984 +#: doc/rust.md:3053 msgid "" "When a task finishes, its stack is necessarily empty and it therefore has no " "references to any boxes; the remainder of its heap is immediately freed." msgstr "" #. type: Plain text -#: doc/rust.md:2987 +#: doc/rust.md:3056 msgid "### Memory slots" msgstr "" #. type: Plain text -#: doc/rust.md:2989 +#: doc/rust.md:3058 msgid "A task's stack contains slots." msgstr "" #. type: Plain text -#: doc/rust.md:2992 +#: doc/rust.md:3061 msgid "" "A _slot_ is a component of a stack frame, either a function parameter, a " "[temporary](#lvalues-rvalues-and-temporaries), or a local variable." msgstr "" #. type: Plain text -#: doc/rust.md:2995 +#: doc/rust.md:3064 msgid "" "A _local variable_ (or *stack-local* allocation) holds a value directly, " "allocated within the stack's memory. The value is a part of the stack frame." msgstr "" #. type: Plain text -#: doc/rust.md:3000 +#: doc/rust.md:3069 msgid "" "Local variables are immutable unless declared with `let mut`. The `mut` " "keyword applies to all local variables declared within that declaration (so " @@ -5659,7 +5808,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3005 +#: doc/rust.md:3074 msgid "" "Function parameters are immutable unless declared with `mut`. The `mut` " "keyword applies only to the following parameter (so `|mut x, y|` and `fn " @@ -5668,7 +5817,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3011 +#: doc/rust.md:3080 msgid "" "Local variables are not initialized when allocated; the entire frame worth " "of local variables are allocated at once, on frame-entry, in an " @@ -5678,31 +5827,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3014 +#: doc/rust.md:3083 msgid "### Memory boxes" msgstr "" #. type: Plain text -#: doc/rust.md:3017 +#: doc/rust.md:3086 msgid "" "A _box_ is a reference to a heap allocation holding another value. There are " "two kinds of boxes: *managed boxes* and *owned boxes*." msgstr "" #. type: Plain text -#: doc/rust.md:3019 +#: doc/rust.md:3088 msgid "" "A _managed box_ type or value is constructed by the prefix *at* sigil `@`." msgstr "" #. type: Plain text -#: doc/rust.md:3021 +#: doc/rust.md:3090 msgid "" "An _owned box_ type or value is constructed by the prefix *tilde* sigil `~`." msgstr "" #. type: Plain text -#: doc/rust.md:3026 +#: doc/rust.md:3095 msgid "" "Multiple managed box values can point to the same heap allocation; copying a " "managed box value makes a shallow copy of the pointer (optionally " @@ -5711,7 +5860,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3030 +#: doc/rust.md:3099 msgid "" "Owned box values exist in 1:1 correspondence with their heap allocation; " "copying an owned box value makes a deep copy of the heap allocation and " @@ -5719,33 +5868,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3033 +#: doc/rust.md:3102 msgid "" "An example of constructing one managed box type and value, and one owned box " "type and value:" msgstr "" #. type: Plain text -#: doc/rust.md:3038 +#: doc/rust.md:3107 msgid "~~~~~~~~ let x: @int = @10; let x: ~int = ~10; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:3041 +#: doc/rust.md:3110 msgid "" "Some operations (such as field selection) implicitly dereference boxes. An " "example of an _implicit dereference_ operation performed on box values:" msgstr "" #. type: Plain text -#: doc/rust.md:3047 +#: doc/rust.md:3116 msgid "" "~~~~~~~~ struct Foo { y: int } let x = @Foo{y: 10}; assert!(x.y == 10); " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:3053 +#: doc/rust.md:3122 msgid "" "Other operations act on box values as single-word-sized address values. For " "these operations, to access the value held in the box requires an explicit " @@ -5755,33 +5904,33 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3056 +#: doc/rust.md:3125 msgid "copying box values (`x = y`)" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3056 +#: doc/rust.md:3125 msgid "passing box values to functions (`f(x,y)`)" msgstr "" #. type: Plain text -#: doc/rust.md:3059 +#: doc/rust.md:3128 msgid "" "An example of an explicit-dereference operation performed on box values:" msgstr "" #. type: Plain text -#: doc/rust.md:3063 +#: doc/rust.md:3132 msgid "~~~~~~~~ fn takes_boxed(b: @int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:3066 +#: doc/rust.md:3135 msgid "fn takes_unboxed(b: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:3073 +#: doc/rust.md:3142 #, no-wrap msgid "" "fn main() {\n" @@ -5793,12 +5942,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3075 +#: doc/rust.md:3144 msgid "## Tasks" msgstr "" #. type: Plain text -#: doc/rust.md:3083 +#: doc/rust.md:3152 msgid "" "An executing Rust program consists of a tree of tasks. A Rust _task_ " "consists of an entry function, a stack, a set of outgoing communication " @@ -5809,7 +5958,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3098 +#: doc/rust.md:3167 msgid "" "Multiple Rust tasks may coexist in a single operating-system process. The " "runtime scheduler maps tasks to a certain number of operating-system " @@ -5828,12 +5977,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3101 +#: doc/rust.md:3170 msgid "### Communication between tasks" msgstr "" #. type: Plain text -#: doc/rust.md:3106 +#: doc/rust.md:3175 msgid "" "Rust tasks are isolated and generally unable to interfere with one another's " "memory directly, except through [`unsafe` code](#unsafe-functions). All " @@ -5842,33 +5991,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3109 +#: doc/rust.md:3178 msgid "" "Inter-task communication and co-ordination facilities are provided in the " "standard library. These include:" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "" "synchronous and asynchronous communication channels with various " "communication topologies" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "" "read-only and read-write shared variables with various safe mutual exclusion " "patterns" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "simple locks and semaphores" msgstr "" #. type: Plain text -#: doc/rust.md:3118 +#: doc/rust.md:3187 msgid "" "When such facilities carry values, the values are restricted to the [`Send` " "type-kind](#type-kinds). Restricting communication interfaces to this kind " @@ -5879,39 +6028,39 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3121 +#: doc/rust.md:3190 msgid "### Task lifecycle" msgstr "" #. type: Plain text -#: doc/rust.md:3124 +#: doc/rust.md:3193 msgid "" "The _lifecycle_ of a task consists of a finite set of states and events that " "cause transitions between the states. The lifecycle states of a task are:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "running" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "blocked" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "failing" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "dead" msgstr "" #. type: Plain text -#: doc/rust.md:3133 +#: doc/rust.md:3202 msgid "" "A task begins its lifecycle -- once it has been spawned -- in the *running* " "state. In this state it executes the statements of its entry function, and " @@ -5919,7 +6068,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3139 +#: doc/rust.md:3208 msgid "" "A task may transition from the *running* state to the *blocked* state any " "time it makes a blocking communication call. When the call can be completed " @@ -5929,7 +6078,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3158 +#: doc/rust.md:3227 msgid "" "A task may transition to the *failing* state at any time, due being killed " "by some external event or internally, from the evaluation of a `fail!()` " @@ -5952,7 +6101,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3162 +#: doc/rust.md:3231 msgid "" "A task in the *dead* state cannot transition to other states; it exists only " "to have its termination status inspected by other tasks, and/or to await " @@ -5960,12 +6109,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3165 +#: doc/rust.md:3234 msgid "### Task scheduling" msgstr "" #. type: Plain text -#: doc/rust.md:3169 +#: doc/rust.md:3238 msgid "" "The currently scheduled task is given a finite *time slice* in which to " "execute, after which it is *descheduled* at a loop-edge or similar " @@ -5973,7 +6122,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3173 +#: doc/rust.md:3242 msgid "" "An executing task can yield control at any time, by making a library call to " "`std::task::yield`, which deschedules it immediately. Entering any other non-" @@ -5981,12 +6130,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3176 +#: doc/rust.md:3245 msgid "# Runtime services, linkage and debugging" msgstr "" #. type: Plain text -#: doc/rust.md:3183 +#: doc/rust.md:3252 msgid "" "The Rust _runtime_ is a relatively compact collection of C++ and Rust code " "that provides fundamental services and datatypes to all Rust tasks at run-" @@ -5996,19 +6145,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3185 +#: doc/rust.md:3254 msgid "" "> **Note:** The runtime library will merge with the `std` library in future " "versions of Rust." msgstr "" #. type: Plain text -#: doc/rust.md:3187 +#: doc/rust.md:3256 msgid "### Memory allocation" msgstr "" #. type: Plain text -#: doc/rust.md:3193 +#: doc/rust.md:3262 msgid "" "The runtime memory-management system is based on a _service-provider " "interface_, through which the runtime requests blocks of memory from its " @@ -6018,7 +6167,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3197 +#: doc/rust.md:3266 msgid "" "The runtime memory-management system, in turn, supplies Rust tasks with " "facilities for allocating, extending and releasing stacks, as well as " @@ -6026,12 +6175,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3199 +#: doc/rust.md:3268 msgid "### Built in types" msgstr "" #. type: Plain text -#: doc/rust.md:3203 +#: doc/rust.md:3272 msgid "" "The runtime provides C and Rust code to assist with various built-in types, " "such as vectors, strings, and the low level communication system (ports, " @@ -6039,19 +6188,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3206 +#: doc/rust.md:3275 msgid "" "Support for other built-in types such as simple types, tuples, records, and " "enums is open-coded by the Rust compiler." msgstr "" #. type: Plain text -#: doc/rust.md:3210 +#: doc/rust.md:3279 msgid "### Task scheduling and communication" msgstr "" #. type: Plain text -#: doc/rust.md:3216 +#: doc/rust.md:3285 msgid "" "The runtime provides code to manage inter-task communication. This includes " "the system of task-lifecycle state transitions depending on the contents of " @@ -6061,12 +6210,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3219 +#: doc/rust.md:3288 msgid "### Logging system" msgstr "" #. type: Plain text -#: doc/rust.md:3223 +#: doc/rust.md:3292 msgid "" "The runtime contains a system for directing [logging expressions](#log-" "expressions) to a logging console and/or internal logging buffers. Logging " @@ -6074,7 +6223,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3230 +#: doc/rust.md:3299 msgid "" "Logging output is enabled by setting the `RUST_LOG` environment variable. " "`RUST_LOG` accepts a logging specification made up of a comma-separated list " @@ -6085,7 +6234,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3238 +#: doc/rust.md:3307 msgid "" "The path to a module consists of the crate name, any parent modules, then " "the module itself, all separated by double colons (`::`). The optional log " @@ -6096,7 +6245,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3244 +#: doc/rust.md:3313 msgid "" "As an example, to see all the logs generated by the compiler, you would set " "`RUST_LOG` to `rustc`, which is the crate name (as specified in its `link` " @@ -6106,7 +6255,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3249 +#: doc/rust.md:3318 msgid "" "Note that when compiling either `.rs` or `.rc` files that don't specify a " "crate name the crate is given a default name that matches the source file, " @@ -6116,7 +6265,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3253 +#: doc/rust.md:3322 msgid "" "As a convenience, the logging spec can also be set to a special pseudo-" "crate, `::help`. In this case, when the application starts, the runtime will " @@ -6124,7 +6273,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3258 +#: doc/rust.md:3327 msgid "" "The Rust runtime itself generates logging information. The runtime's logs " "are generated for a number of artificial modules in the `::rt` pseudo-crate, " @@ -6133,84 +6282,84 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::mem` Memory management" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::comm` Messaging and task communication" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::task` Task management" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::dom` Task scheduling" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::trace` Unused" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::cache` Type descriptor cache" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::upcall` Compiler-generated runtime calls" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::timer` The scheduler timer" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::gc` Garbage collection" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::stdlib` Functions used directly by the standard library" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::kern` The runtime kernel" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::backtrace` Log a backtrace on task failure" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::callback` Unused" msgstr "" #. type: Plain text -#: doc/rust.md:3274 +#: doc/rust.md:3343 msgid "#### Logging Expressions" msgstr "" #. type: Plain text -#: doc/rust.md:3277 +#: doc/rust.md:3346 msgid "" "Rust provides several macros to log information. Here's a simple Rust " "program that demonstrates all four of them:" msgstr "" #. type: Plain text -#: doc/rust.md:3286 +#: doc/rust.md:3355 #, no-wrap msgid "" "```rust\n" @@ -6224,13 +6373,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3288 +#: doc/rust.md:3357 msgid "" "These four log levels correspond to levels 1-4, as controlled by `RUST_LOG`:" msgstr "" #. type: Plain text -#: doc/rust.md:3295 +#: doc/rust.md:3364 msgid "" "```bash $ RUST_LOG=rust=3 ./rust rust: ~\"\\\"This is an error log\\\"\" " "rust: ~\"\\\"This is a warn log\\\"\" rust: ~\"\\\"this is an info log\\\"\" " @@ -6238,28 +6387,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3297 +#: doc/rust.md:3366 msgid "# Appendix: Rationales and design tradeoffs" msgstr "" #. type: Plain text -#: doc/rust.md:3299 +#: doc/rust.md:3368 #, no-wrap msgid "*TODO*.\n" msgstr "" #. type: Plain text -#: doc/rust.md:3301 +#: doc/rust.md:3370 msgid "# Appendix: Influences and further references" msgstr "" #. type: Plain text -#: doc/rust.md:3303 +#: doc/rust.md:3372 msgid "## Influences" msgstr "" #. type: Plain text -#: doc/rust.md:3312 +#: doc/rust.md:3381 msgid "" "> The essential problem that must be solved in making a fault-tolerant > " "software system is therefore that of fault-isolation. Different programmers " @@ -6270,7 +6419,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3324 +#: doc/rust.md:3393 msgid "" "> In our approach, all data is private to some process, and processes can > " "only communicate through communications channels. *Security*, as used > in " @@ -6282,7 +6431,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3332 +#: doc/rust.md:3401 msgid "" "> Concurrent and applicative programming complement each other. The > " "ability to send messages on channels provides I/O without side effects, > " @@ -6291,7 +6440,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3339 +#: doc/rust.md:3408 msgid "" "Rust is not a particularly original language. It may however appear unusual " "by contemporary standards, as its design elements are drawn from a number of " @@ -6301,7 +6450,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3343 +#: doc/rust.md:3412 msgid "" "The NIL (1981) and Hermes (1990) family. These languages were developed by " "Robert Strom, Shaula Yemini, David Bacon and others in their group at IBM " @@ -6309,7 +6458,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3347 +#: doc/rust.md:3416 msgid "" "The Erlang (1987) language, developed by Joe Armstrong, Robert Virding, " "Claes Wikström, Mike Williams and others in their group at the Ericsson " @@ -6317,7 +6466,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3352 +#: doc/rust.md:3421 msgid "" "The Sather (1990) language, developed by Stephen Omohundro, Chu-Cheow Lim, " "Heinz Schmidt and others in their group at The International Computer " @@ -6326,7 +6475,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3357 +#: doc/rust.md:3426 msgid "" "The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These languages " "were developed by Rob Pike, Phil Winterbottom, Sean Dorward and others in " @@ -6335,7 +6484,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3361 +#: doc/rust.md:3430 msgid "" "The Napier (1985) and Napier88 (1988) family. These languages were developed " "by Malcolm Atkinson, Ron Morrison and others in their group at the " @@ -6343,47 +6492,47 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3363 +#: doc/rust.md:3432 msgid "" "Additional specific influences can be seen from the following languages:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The stack-growth implementation of Go." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The structural algebraic types and compilation manager of SML." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The attribute and assembly systems of C#." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The references and deterministic destructor system of C++." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The memory region systems of the ML Kit and Cyclone." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The typeclass system of Haskell." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The lexical identifier rule of Python." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The block syntax of Ruby." msgstr "" diff --git a/doc/po/rustpkg.md.pot b/doc/po/rustpkg.md.pot index f6b962d8565d0..134aa56b3dab4 100644 --- a/doc/po/rustpkg.md.pot +++ b/doc/po/rustpkg.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial-borrowed-ptr.md.pot b/doc/po/tutorial-borrowed-ptr.md.pot index 87900073001db..816b3eeea61e6 100644 --- a/doc/po/tutorial-borrowed-ptr.md.pot +++ b/doc/po/tutorial-borrowed-ptr.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/tutorial.md:1110 doc/tutorial-borrowed-ptr.md:72 +#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" diff --git a/doc/po/tutorial-container.md.pot b/doc/po/tutorial-container.md.pot index aa9dae62a6153..3a4e86f8c82ee 100644 --- a/doc/po/tutorial-container.md.pot +++ b/doc/po/tutorial-container.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -195,7 +195,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:89 +#: doc/tutorial-container.md:89 doc/tutorial-container.md:262 #, no-wrap msgid "" "~~~\n" @@ -217,7 +217,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:107 +#: doc/tutorial-container.md:107 doc/tutorial-container.md:284 #, no-wrap msgid "" "impl Iterator for ZeroStream {\n" @@ -440,6 +440,162 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:207 +#: doc/tutorial-container.md:208 msgid "// the iterator is now fully consumed assert!(it.next().is_none()); ~~~" msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:210 +msgid "## Conversion" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:212 +msgid "" +"Iterators offer generic conversion to containers with the `collect` adaptor:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:218 +msgid "" +"~~~ let xs = [0, 1, 1, 2, 3, 5, 8]; let ys = xs.rev_iter().skip(1)." +"transform(|&x| x * 2).collect::<~[int]>(); assert_eq!(ys, ~[10, 6, 4, 2, 2, " +"0]); ~~~" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:221 +msgid "" +"The method requires a type hint for the container type, if the surrounding " +"code does not provide sufficient information." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:225 +msgid "" +"Containers can provide conversion from iterators through `collect` by " +"implementing the `FromIterator` trait. For example, the implementation for " +"vectors is as follows:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:238 +#, no-wrap +msgid "" +"~~~\n" +"impl> FromIterator for ~[A] {\n" +" pub fn from_iterator(iterator: &mut T) -> ~[A] {\n" +" let (lower, _) = iterator.size_hint();\n" +" let mut xs = with_capacity(lower);\n" +" for iterator.advance |x| {\n" +" xs.push(x);\n" +" }\n" +" xs\n" +" }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:240 +msgid "### Size hints" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:243 +msgid "" +"The `Iterator` trait provides a `size_hint` default method, returning a " +"lower bound and optionally on upper bound on the length of the iterator:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:247 +msgid "~~~ fn size_hint(&self) -> (uint, Option) { (0, None) } ~~~" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:251 +msgid "" +"The vector implementation of `FromIterator` from above uses the lower bound " +"to pre-allocate enough space to hold the minimum number of elements the " +"iterator will yield." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:254 +msgid "" +"The default implementation is always correct, but it should be overridden if " +"the iterator can provide better information." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:256 +msgid "" +"The `ZeroStream` from earlier can provide an exact lower and upper bound:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:267 +#, no-wrap +msgid "" +"impl ZeroStream {\n" +" fn new(n: uint) -> ZeroStream {\n" +" ZeroStream { remaining: n }\n" +" }\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:272 +#, no-wrap +msgid "" +" fn size_hint(&self) -> (uint, Option) {\n" +" (self.remaining, Some(self.remaining))\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:286 +msgid "## Double-ended iterators" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:290 +msgid "" +"The `DoubleEndedIterator` trait represents an iterator able to yield " +"elements from either end of a range. It inherits from the `Iterator` trait " +"and extends it with the `next_back` function." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:293 +msgid "" +"A `DoubleEndedIterator` can be flipped with the `invert` adaptor, returning " +"another `DoubleEndedIterator` with `next` and `next_back` exchanged." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:300 +msgid "" +"~~~ let xs = [1, 2, 3, 4, 5, 6]; let mut it = xs.iter(); println(fmt!(\"%?" +"\", it.next())); // prints `Some(&1)` println(fmt!(\"%?\", it.next())); // " +"prints `Some(&2)` println(fmt!(\"%?\", it.next_back())); // prints `Some(&6)`" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:306 +#, no-wrap +msgid "" +"// prints `5`, `4` and `3`\n" +"for it.invert().advance |&x| {\n" +" println(fmt!(\"%?\", x))\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:308 +msgid "" +"The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted " +"version of the standard immutable and mutable vector iterators." +msgstr "" diff --git a/doc/po/tutorial-ffi.md.pot b/doc/po/tutorial-ffi.md.pot index 20641225b135d..c43b6652331ff 100644 --- a/doc/po/tutorial-ffi.md.pot +++ b/doc/po/tutorial-ffi.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/tutorial.md:875 doc/tutorial-ffi.md:143 +#: doc/tutorial.md:876 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" diff --git a/doc/po/tutorial-macros.md.pot b/doc/po/tutorial-macros.md.pot index 92a8651d2920c..5487ab5ebbd8c 100644 --- a/doc/po/tutorial-macros.md.pot +++ b/doc/po/tutorial-macros.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial-tasks.md.pot b/doc/po/tutorial-tasks.md.pot index 897d89b2a9066..43c0f4c092404 100644 --- a/doc/po/tutorial-tasks.md.pot +++ b/doc/po/tutorial-tasks.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial.md.pot b/doc/po/tutorial.md.pot index cf04b7f5dc805..415d5052a0643 100644 --- a/doc/po/tutorial.md.pot +++ b/doc/po/tutorial.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/rust.md:1231 doc/tutorial.md:2179 +#: doc/rust.md:1231 doc/tutorial.md:2177 msgid "" "In type-parameterized functions, methods of the supertrait may be called on " "values of subtrait-bound type parameters. Refering to the previous example " @@ -32,7 +32,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1240 doc/tutorial.md:2188 +#: doc/rust.md:1240 doc/tutorial.md:2186 #, no-wrap msgid "" "~~~\n" @@ -46,12 +46,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1242 doc/tutorial.md:2190 +#: doc/rust.md:1242 doc/tutorial.md:2188 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" #. type: Plain text -#: doc/tutorial.md:2 doc/tut.md:2 +#: doc/tutorial.md:2 msgid "% The Rust Language Tutorial" msgstr "" @@ -961,24 +961,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:515 +#: doc/tutorial.md:516 #, no-wrap msgid "" "~~~~\n" "# use std::float;\n" +"# use std::num::atan;\n" "fn angle(vector: (float, float)) -> float {\n" " let pi = float::consts::pi;\n" " match vector {\n" " (0f, y) if y < 0f => 1.5 * pi,\n" " (0f, y) => 0.5 * pi,\n" -" (x, y) => float::atan(y / x)\n" +" (x, y) => atan(y / x)\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:521 +#: doc/tutorial.md:522 msgid "" "A variable name in a pattern matches any value, *and* binds that name to the " "value of the matched value inside of the arm's action. Thus, `(0f, y)` " @@ -988,7 +989,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:528 +#: doc/tutorial.md:529 msgid "" "Any `match` arm can have a guard clause (written `if EXPR`), called a " "*pattern guard*, which is an expression of type `bool` that determines, " @@ -998,7 +999,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:533 +#: doc/tutorial.md:534 msgid "" "You've already seen simple `let` bindings, but `let` is a little fancier " "than you've been led to believe. It, too, supports destructuring patterns. " @@ -1007,14 +1008,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:538 +#: doc/tutorial.md:539 msgid "" "~~~~ # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) } let (a, b) = " "get_tuple_of_two_ints(); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:542 +#: doc/tutorial.md:543 msgid "" "Let bindings only work with _irrefutable_ patterns: that is, patterns that " "can never fail to match. This excludes `let` from matching literals and most " @@ -1022,12 +1023,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:544 +#: doc/tutorial.md:545 msgid "## Loops" msgstr "" #. type: Plain text -#: doc/tutorial.md:549 +#: doc/tutorial.md:550 msgid "" "`while` denotes a loop that iterates as long as its given condition (which " "must have type `bool`) evaluates to `true`. Inside a loop, the keyword " @@ -1036,7 +1037,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:556 +#: doc/tutorial.md:557 #, no-wrap msgid "" "~~~~\n" @@ -1048,14 +1049,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:558 +#: doc/tutorial.md:559 msgid "" "`loop` denotes an infinite loop, and is the preferred way of writing `while " "true`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:568 +#: doc/tutorial.md:569 #, no-wrap msgid "" "~~~~\n" @@ -1070,14 +1071,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:571 +#: doc/tutorial.md:572 msgid "" "This code prints out a weird sequence of numbers and stops as soon as it " "finds one that can be divided by five." msgstr "" #. type: Plain text -#: doc/tutorial.md:576 +#: doc/tutorial.md:577 msgid "" "Rust also has a `for` construct. It's different from C's `for` and it works " "best when iterating over collections. See the section on [closures]" @@ -1086,17 +1087,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:578 +#: doc/tutorial.md:579 msgid "# Data structures" msgstr "" #. type: Plain text -#: doc/tutorial.md:580 +#: doc/tutorial.md:581 msgid "## Structs" msgstr "" #. type: Plain text -#: doc/tutorial.md:585 +#: doc/tutorial.md:586 msgid "" "Rust struct types must be declared before they are used using the `struct` " "syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, " @@ -1105,7 +1106,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:589 +#: doc/tutorial.md:590 msgid "" "Structs are quite similar to C structs and are even laid out the same way in " "memory (so you can read from a Rust struct in C, and vice-versa). Use the " @@ -1113,7 +1114,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:596 +#: doc/tutorial.md:597 #, no-wrap msgid "" "~~~~\n" @@ -1125,7 +1126,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:600 +#: doc/tutorial.md:601 msgid "" "Inherited mutability means that any field of a struct may be mutable, if the " "struct is in a mutable slot (or a field of a struct in a mutable slot, and " @@ -1133,7 +1134,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:604 +#: doc/tutorial.md:605 msgid "" "With a value (say, `mypoint`) of such a type in a mutable location, you can " "do `mypoint.y += 1.0`. But in an immutable location, such an assignment to a " @@ -1141,28 +1142,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:609 +#: doc/tutorial.md:610 msgid "" "~~~~ {.xfail-test} # struct Point { x: float, y: float } let mut mypoint = " "Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };" msgstr "" #. type: Plain text -#: doc/tutorial.md:613 +#: doc/tutorial.md:614 msgid "" "mypoint.y += 1.0; // mypoint is mutable, and its fields as well origin.y += " "1.0; // ERROR: assigning to immutable field ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:616 +#: doc/tutorial.md:617 msgid "" "`match` patterns destructure structs. The basic syntax is `Name { fieldname: " "pattern, ... }`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:625 +#: doc/tutorial.md:626 #, no-wrap msgid "" "~~~~\n" @@ -1176,7 +1177,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:632 +#: doc/tutorial.md:633 msgid "" "In general, the field names of a struct do not have to appear in the same " "order they appear in the type. When you are not interested in all the fields " @@ -1187,7 +1188,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:640 +#: doc/tutorial.md:641 #, no-wrap msgid "" "~~~\n" @@ -1200,19 +1201,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:642 +#: doc/tutorial.md:643 msgid "## Enums" msgstr "" #. type: Plain text -#: doc/tutorial.md:645 +#: doc/tutorial.md:646 msgid "" "Enums are datatypes that have several alternate representations. For " "example, consider the type shown earlier:" msgstr "" #. type: Plain text -#: doc/tutorial.md:653 +#: doc/tutorial.md:654 #, no-wrap msgid "" "~~~~\n" @@ -1225,7 +1226,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:659 +#: doc/tutorial.md:660 msgid "" "A value of this type is either a `Circle`, in which case it contains a " "`Point` struct and a float, or a `Rectangle`, in which case it contains two " @@ -1235,7 +1236,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:665 +#: doc/tutorial.md:666 msgid "" "The above declaration will define a type `Shape` that can refer to such " "shapes, and two functions, `Circle` and `Rectangle`, which can be used to " @@ -1244,14 +1245,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:668 +#: doc/tutorial.md:669 msgid "" "Enum variants need not have parameters. This `enum` declaration, for " "example, is equivalent to a C enum:" msgstr "" #. type: Plain text -#: doc/tutorial.md:677 +#: doc/tutorial.md:678 #, no-wrap msgid "" "~~~~\n" @@ -1265,14 +1266,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:680 +#: doc/tutorial.md:681 msgid "" "This declaration defines `North`, `East`, `South`, and `West` as constants, " "all of which have type `Direction`." msgstr "" #. type: Plain text -#: doc/tutorial.md:684 +#: doc/tutorial.md:685 msgid "" "When an enum is C-like (that is, when none of the variants have parameters), " "it is possible to explicitly set the discriminator values to a constant " @@ -1280,7 +1281,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:692 +#: doc/tutorial.md:693 #, no-wrap msgid "" "~~~~\n" @@ -1293,7 +1294,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:697 +#: doc/tutorial.md:698 msgid "" "If an explicit discriminator is not specified for a variant, the value " "defaults to the value of the previous variant plus one. If the first variant " @@ -1302,14 +1303,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:700 +#: doc/tutorial.md:701 msgid "" "When an enum is C-like, you can apply the `as` cast operator to convert it " "to its discriminator value as an `int`." msgstr "" #. type: Plain text -#: doc/tutorial.md:704 +#: doc/tutorial.md:705 msgid "" "For enum types with multiple variants, destructuring is the only way to get " "at their contents. All variant constructors can be used as patterns, as in " @@ -1317,7 +1318,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:716 +#: doc/tutorial.md:717 #, no-wrap msgid "" "~~~~\n" @@ -1334,7 +1335,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:721 +#: doc/tutorial.md:722 msgid "" "You can write a lone `_` to ignore an individual field, and can ignore all " "fields of a variant like: `Circle(*)`. As in their introduction form, " @@ -1342,7 +1343,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:734 +#: doc/tutorial.md:735 #, no-wrap msgid "" "~~~~\n" @@ -1360,12 +1361,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:736 +#: doc/tutorial.md:737 msgid "Enum variants may also be structs. For example:" msgstr "" #. type: Plain text -#: doc/tutorial.md:754 +#: doc/tutorial.md:755 #, no-wrap msgid "" "~~~~\n" @@ -1388,12 +1389,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:756 +#: doc/tutorial.md:757 msgid "## Tuples" msgstr "" #. type: Plain text -#: doc/tutorial.md:761 +#: doc/tutorial.md:762 msgid "" "Tuples in Rust behave exactly like structs, except that their fields do not " "have names. Thus, you cannot access their fields with dot notation. Tuples " @@ -1402,7 +1403,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:768 +#: doc/tutorial.md:769 #, no-wrap msgid "" "~~~~\n" @@ -1414,12 +1415,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:770 +#: doc/tutorial.md:771 msgid "## Tuple structs" msgstr "" #. type: Plain text -#: doc/tutorial.md:775 +#: doc/tutorial.md:776 msgid "" "Rust also has _tuple structs_, which behave like both structs and tuples, " "except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a " @@ -1428,7 +1429,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:784 +#: doc/tutorial.md:785 #, no-wrap msgid "" "For example:\n" @@ -1442,12 +1443,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:786 +#: doc/tutorial.md:787 msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:791 +#: doc/tutorial.md:792 msgid "" "There is a special case for tuple structs with a single field, which are " "sometimes called \"newtypes\" (after Haskell's \"newtype\" feature). These " @@ -1456,50 +1457,50 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:795 +#: doc/tutorial.md:796 msgid "~~~~ struct GizmoId(int); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:798 +#: doc/tutorial.md:799 msgid "" "For convenience, you can extract the contents of such a struct with the " "dereference (`*`) unary operator:" msgstr "" #. type: Plain text -#: doc/tutorial.md:804 +#: doc/tutorial.md:805 msgid "" "~~~~ # struct GizmoId(int); let my_gizmo_id: GizmoId = GizmoId(10); let " "id_int: int = *my_gizmo_id; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:807 +#: doc/tutorial.md:808 msgid "" "Types like this can be useful to differentiate between data that have the " "same type but must be used in different ways." msgstr "" #. type: Plain text -#: doc/tutorial.md:812 +#: doc/tutorial.md:813 msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:815 +#: doc/tutorial.md:816 msgid "" "The above definitions allow for a simple way for programs to avoid confusing " "numbers that correspond to different units." msgstr "" #. type: Plain text -#: doc/tutorial.md:817 +#: doc/tutorial.md:818 msgid "# Functions" msgstr "" #. type: Plain text -#: doc/tutorial.md:825 +#: doc/tutorial.md:826 msgid "" "We've already seen several function definitions. Like all other static " "declarations, such as `type`, functions can be declared both at the top " @@ -1511,7 +1512,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:831 +#: doc/tutorial.md:832 #, no-wrap msgid "" "~~~~\n" @@ -1522,7 +1523,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:836 +#: doc/tutorial.md:837 msgid "" "The `return` keyword immediately returns from the body of a function. It is " "optionally followed by an expression to return. A function can also return a " @@ -1530,7 +1531,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:842 +#: doc/tutorial.md:843 #, no-wrap msgid "" "~~~~\n" @@ -1541,7 +1542,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:849 +#: doc/tutorial.md:850 msgid "" "It's better Rust style to write a return value this way instead of writing " "an explicit `return`. The utility of `return` comes in when returning early " @@ -1551,35 +1552,35 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:852 +#: doc/tutorial.md:853 msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }" msgstr "" #. type: Plain text -#: doc/tutorial.md:855 +#: doc/tutorial.md:856 msgid "fn do_nothing_the_easy_way() { } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:857 +#: doc/tutorial.md:858 msgid "" "Ending the function with a semicolon like so is equivalent to returning `()`." msgstr "" #. type: Plain text -#: doc/tutorial.md:861 +#: doc/tutorial.md:862 msgid "" "~~~~ fn line(a: int, b: int, x: int) -> int { a * x + b } fn oops(a: int, b: " "int, x: int) -> () { a * x + b; }" msgstr "" #. type: Plain text -#: doc/tutorial.md:865 +#: doc/tutorial.md:866 msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:869 +#: doc/tutorial.md:870 msgid "" "As with `match` expressions and `let` bindings, function arguments support " "pattern destructuring. Like `let`, argument patterns must be irrefutable, as " @@ -1587,17 +1588,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:873 +#: doc/tutorial.md:874 msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:875 doc/tutorial-ffi.md:143 +#: doc/tutorial.md:876 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" #. type: Plain text -#: doc/tutorial.md:879 +#: doc/tutorial.md:880 msgid "" "A *destructor* is a function responsible for cleaning up the resources used " "by an object when it is no longer accessible. Destructors can be defined to " @@ -1605,7 +1606,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:883 +#: doc/tutorial.md:884 msgid "" "Objects are never accessible after their destructor has been called, so " "there are no dynamic failures from accessing freed resources. When a task " @@ -1613,13 +1614,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:885 +#: doc/tutorial.md:886 msgid "" "The `~` sigil represents a unique handle for a memory allocation on the heap:" msgstr "" #. type: Plain text -#: doc/tutorial.md:893 +#: doc/tutorial.md:894 #, no-wrap msgid "" "~~~~\n" @@ -1632,7 +1633,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:897 +#: doc/tutorial.md:898 msgid "" "Rust includes syntax for heap memory allocation in the language since it's " "commonly used, but the same semantics can be implemented by a type with a " @@ -1640,12 +1641,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:899 +#: doc/tutorial.md:900 msgid "# Ownership" msgstr "" #. type: Plain text -#: doc/tutorial.md:904 +#: doc/tutorial.md:905 msgid "" "Rust formalizes the concept of object ownership to delegate management of an " "object's lifetime to either a variable or a task-local garbage collector. An " @@ -1655,7 +1656,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:910 +#: doc/tutorial.md:911 msgid "" "Ownership is recursive, so mutability is inherited recursively and a " "destructor destroys the contained tree of owned objects. Variables are top-" @@ -1665,14 +1666,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:914 +#: doc/tutorial.md:915 msgid "" "~~~~ // the struct owns the objects contained in the `x` and `y` fields " "struct Foo { x: int, y: ~int }" msgstr "" #. type: Plain text -#: doc/tutorial.md:921 +#: doc/tutorial.md:922 #, no-wrap msgid "" "{\n" @@ -1684,14 +1685,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:926 +#: doc/tutorial.md:927 msgid "" "// `b` is mutable, and the mutability is inherited by the objects it owns " "let mut b = Foo { x: 5, y: ~10 }; b.x = 10; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:932 +#: doc/tutorial.md:933 msgid "" "If an object doesn't contain garbage-collected boxes, it consists of a " "single ownership tree and is given the `Owned` trait which allows it to be " @@ -1701,12 +1702,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:934 +#: doc/tutorial.md:935 msgid "# Boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:941 +#: doc/tutorial.md:942 msgid "" "Many modern languages represent values as pointers to heap memory by " "default. In contrast, Rust, like C and C++, represents such types directly. " @@ -1717,7 +1718,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:946 +#: doc/tutorial.md:947 msgid "" "For small structs like `Point`, this is usually more efficient than " "allocating memory and indirecting through a pointer. But for big structs, or " @@ -1726,31 +1727,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:948 +#: doc/tutorial.md:949 msgid "## Owned boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:951 +#: doc/tutorial.md:952 msgid "" "An owned box (`~`) is a uniquely owned allocation on the heap. It inherits " "the mutability and lifetime of the owner as it would if there was no box:" msgstr "" #. type: Plain text -#: doc/tutorial.md:956 +#: doc/tutorial.md:957 msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;" msgstr "" #. type: Plain text -#: doc/tutorial.md:961 +#: doc/tutorial.md:962 msgid "" "let x = ~5; // immutable let mut y = ~5; // mutable *y += 2; // the * " "operator is needed to access the contained value ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:966 +#: doc/tutorial.md:967 msgid "" "The purpose of an owned box is to add a layer of indirection in order to " "create recursive data structures or cheaply pass around an object larger " @@ -1759,14 +1760,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:969 +#: doc/tutorial.md:970 msgid "" "The following struct won't compile, because the lack of indirection would " "mean it has an infinite size:" msgstr "" #. type: Plain text -#: doc/tutorial.md:975 +#: doc/tutorial.md:976 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -1777,7 +1778,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:979 +#: doc/tutorial.md:980 msgid "" "> ***Note:*** The `Option` type is an enum that represents an *optional* " "value. > It's comparable to a nullable pointer in many other languages, but " @@ -1785,7 +1786,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:983 +#: doc/tutorial.md:984 msgid "" "Adding indirection with an owned pointer allocates the child outside of the " "struct on the heap, which makes it a finite size and won't result in a " @@ -1793,7 +1794,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:989 +#: doc/tutorial.md:990 #, no-wrap msgid "" "~~~~\n" @@ -1804,12 +1805,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:991 +#: doc/tutorial.md:992 msgid "## Managed boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:999 +#: doc/tutorial.md:1000 msgid "" "A managed box (`@`) is a heap allocation with the lifetime managed by a task-" "local garbage collector. It will be destroyed at some point after there are " @@ -1821,29 +1822,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1002 +#: doc/tutorial.md:1003 msgid "~~~~ let a = @5; // immutable" msgstr "" #. type: Plain text -#: doc/tutorial.md:1005 +#: doc/tutorial.md:1006 msgid "let mut b = @5; // mutable variable, immutable box b = @10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1008 +#: doc/tutorial.md:1009 msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1013 +#: doc/tutorial.md:1014 msgid "" "let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; " "~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1018 +#: doc/tutorial.md:1019 msgid "" "A mutable variable and an immutable variable can refer to the same box, " "given that their types are compatible. Mutability of a box is a property of " @@ -1852,7 +1853,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1022 +#: doc/tutorial.md:1023 #, no-wrap msgid "" "~~~~\n" @@ -1861,7 +1862,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1025 +#: doc/tutorial.md:1026 #, no-wrap msgid "" "let mut c : @int; // declare a variable with type managed immutable int\n" @@ -1869,7 +1870,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1029 +#: doc/tutorial.md:1030 #, no-wrap msgid "" "c = a; // box type is the same, okay\n" @@ -1878,7 +1879,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1034 +#: doc/tutorial.md:1035 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -1888,12 +1889,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1036 +#: doc/tutorial.md:1037 msgid "# Move semantics" msgstr "" #. type: Plain text -#: doc/tutorial.md:1042 +#: doc/tutorial.md:1043 msgid "" "Rust uses a shallow copy for parameter passing, assignment and returning " "values from functions. A shallow copy is considered a move of ownership if " @@ -1903,33 +1904,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1048 +#: doc/tutorial.md:1049 msgid "" "~~~~ let x = ~5; let y = x.clone(); // y is a newly allocated box let z = " "x; // no new memory allocated, x can no longer be used ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1051 +#: doc/tutorial.md:1052 msgid "" "Since in owned boxes mutability is a property of the owner, not the box, " "mutable boxes may become immutable when they are moved, and vice-versa." msgstr "" #. type: Plain text -#: doc/tutorial.md:1058 +#: doc/tutorial.md:1059 msgid "" "~~~~ let r = ~13; let mut s = r; // box becomes mutable *s += 1; let t = " "s; // box becomes immutable ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1060 +#: doc/tutorial.md:1061 msgid "# Borrowed pointers" msgstr "" #. type: Plain text -#: doc/tutorial.md:1066 +#: doc/tutorial.md:1067 msgid "" "Rust's borrowed pointers are a general purpose reference type. In contrast " "with owned boxes, where the holder of an owned box is the owner of the " @@ -1939,12 +1940,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1068 +#: doc/tutorial.md:1069 msgid "As an example, consider a simple struct type, `Point`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1075 +#: doc/tutorial.md:1076 #, no-wrap msgid "" "~~~\n" @@ -1956,7 +1957,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1079 +#: doc/tutorial.md:1080 msgid "" "We can use this simple definition to allocate points in many different ways. " "For example, in this code, each of these three local variables contains a " @@ -1964,7 +1965,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1086 +#: doc/tutorial.md:1087 #, no-wrap msgid "" "~~~\n" @@ -1976,7 +1977,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1098 +#: doc/tutorial.md:1099 msgid "" "Suppose we want to write a procedure that computes the distance between any " "two points, no matter where they are stored. For example, we might like to " @@ -1991,7 +1992,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1108 +#: doc/tutorial.md:1109 #, no-wrap msgid "" "~~~\n" @@ -2006,12 +2007,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1110 doc/tutorial-borrowed-ptr.md:72 +#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1120 +#: doc/tutorial.md:1121 #, no-wrap msgid "" "~~~\n" @@ -2026,7 +2027,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1127 +#: doc/tutorial.md:1128 msgid "" "Here the `&` operator is used to take the address of the variable " "`on_the_stack`; this is because `on_the_stack` has the type `Point` (that " @@ -2036,7 +2037,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1133 +#: doc/tutorial.md:1134 msgid "" "In the case of the boxes `managed_box` and `owned_box`, however, no explicit " "action is necessary. The compiler will automatically convert a box like " @@ -2046,7 +2047,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1142 +#: doc/tutorial.md:1143 msgid "" "Whenever a value is borrowed, there are some limitations on what you can do " "with the original. For example, if the contents of a variable have been lent " @@ -2058,31 +2059,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1145 +#: doc/tutorial.md:1146 msgid "" "For a more in-depth explanation of borrowed pointers, read the [borrowed " "pointer tutorial][borrowtut]." msgstr "" #. type: Plain text -#: doc/tutorial.md:1147 +#: doc/tutorial.md:1148 msgid "[borrowtut]: tutorial-borrowed-ptr.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1149 +#: doc/tutorial.md:1150 msgid "## Freezing" msgstr "" #. type: Plain text -#: doc/tutorial.md:1152 +#: doc/tutorial.md:1153 msgid "" "Borrowing an immutable pointer to an object freezes it and prevents " "mutation. `Owned` objects have freezing enforced statically at compile-time." msgstr "" #. type: Plain text -#: doc/tutorial.md:1160 +#: doc/tutorial.md:1161 #, no-wrap msgid "" "~~~~\n" @@ -2095,7 +2096,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1164 +#: doc/tutorial.md:1165 msgid "" "Mutable managed boxes handle freezing dynamically when any of their contents " "are borrowed, and the task will fail if an attempt to modify them is made " @@ -2103,7 +2104,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1174 +#: doc/tutorial.md:1175 #, no-wrap msgid "" "~~~~\n" @@ -2118,29 +2119,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1176 +#: doc/tutorial.md:1177 msgid "# Dereferencing pointers" msgstr "" #. type: Plain text -#: doc/tutorial.md:1179 +#: doc/tutorial.md:1180 msgid "" "Rust uses the unary star operator (`*`) to access the contents of a box or " "pointer, similarly to C." msgstr "" #. type: Plain text -#: doc/tutorial.md:1184 +#: doc/tutorial.md:1185 msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1187 +#: doc/tutorial.md:1188 msgid "let sum = *managed + *owned + *borrowed; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1191 +#: doc/tutorial.md:1192 msgid "" "Dereferenced mutable pointers may appear on the left hand side of " "assignments. Such an assignment modifies the value that the pointer points " @@ -2148,17 +2149,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1195 +#: doc/tutorial.md:1196 msgid "~~~ let managed = @mut 10; let mut owned = ~20;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1198 +#: doc/tutorial.md:1199 msgid "let mut value = 30; let borrowed = &mut value;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1203 +#: doc/tutorial.md:1204 #, no-wrap msgid "" "*managed = *owned + 10;\n" @@ -2168,7 +2169,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1207 +#: doc/tutorial.md:1208 msgid "" "Pointers have high operator precedence, but lower precedence than the dot " "operator used for field and method access. This precedence order can " @@ -2176,7 +2177,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1217 +#: doc/tutorial.md:1218 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " @@ -2185,7 +2186,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1221 +#: doc/tutorial.md:1222 msgid "" "To combat this ugliness the dot operator applies _automatic pointer " "dereferencing_ to the receiver (the value on the left-hand side of the dot), " @@ -2193,7 +2194,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1231 +#: doc/tutorial.md:1232 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " @@ -2202,7 +2203,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1235 +#: doc/tutorial.md:1236 msgid "" "You can write an expression that dereferences any number of pointers " "automatically. For example, if you feel inclined, you could write something " @@ -2210,24 +2211,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1241 +#: doc/tutorial.md:1242 msgid "" "~~~ # struct Point { x: float, y: float } let point = &@~Point { x: 10f, y: " "20f }; println(fmt!(\"%f\", point.x)); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1243 +#: doc/tutorial.md:1244 msgid "The indexing operator (`[]`) also auto-dereferences." msgstr "" #. type: Plain text -#: doc/tutorial.md:1245 +#: doc/tutorial.md:1246 msgid "# Vectors and strings" msgstr "" #. type: Plain text -#: doc/tutorial.md:1250 +#: doc/tutorial.md:1251 msgid "" "A vector is a contiguous section of memory containing zero or more values of " "the same type. Like other types in Rust, vectors can be stored on the stack, " @@ -2236,7 +2237,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1260 +#: doc/tutorial.md:1261 #, no-wrap msgid "" "~~~\n" @@ -2251,33 +2252,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1263 +#: doc/tutorial.md:1264 msgid "" "// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] " "= &[Aquamarine, Asparagus, AtomicTangerine];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1266 +#: doc/tutorial.md:1267 msgid "" "// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = " "@[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1270 +#: doc/tutorial.md:1271 msgid "" "// An exchange heap (owned) vector of crayons let exchange_crayons: " "~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1272 +#: doc/tutorial.md:1273 msgid "The `+` operator means concatenation when applied to vector types." msgstr "" #. type: Plain text -#: doc/tutorial.md:1277 +#: doc/tutorial.md:1278 #, no-wrap msgid "" "~~~~\n" @@ -2287,28 +2288,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1280 +#: doc/tutorial.md:1281 msgid "" "let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = " "~[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1283 +#: doc/tutorial.md:1284 msgid "" "// Add two vectors to create a new one let our_crayons = my_crayons + " "your_crayons;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1288 +#: doc/tutorial.md:1289 msgid "" "// .push_all() will append to a vector, provided it lives in a mutable slot " "let mut my_crayons = my_crayons; my_crayons.push_all(your_crayons); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1293 +#: doc/tutorial.md:1294 msgid "" "> ***Note:*** The above examples of vector addition use owned > vectors. " "Some operations on slices and stack vectors are > not yet well-supported. " @@ -2316,12 +2317,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1295 +#: doc/tutorial.md:1296 msgid "Square brackets denote indexing into a vector:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1307 +#: doc/tutorial.md:1308 #, no-wrap msgid "" "~~~~\n" @@ -2338,12 +2339,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1309 +#: doc/tutorial.md:1310 msgid "A vector can be destructured using pattern matching:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1319 +#: doc/tutorial.md:1320 #, no-wrap msgid "" "~~~~\n" @@ -2358,7 +2359,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1323 +#: doc/tutorial.md:1324 msgid "" "The elements of a vector _inherit the mutability of the vector_, and as " "such, individual elements may not be reassigned when the vector lives in an " @@ -2366,7 +2367,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1329 +#: doc/tutorial.md:1330 #, no-wrap msgid "" "~~~ {.xfail-test}\n" @@ -2377,17 +2378,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1332 +#: doc/tutorial.md:1333 msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1334 +#: doc/tutorial.md:1335 msgid "Moving it into a mutable slot makes the elements assignable." msgstr "" #. type: Plain text -#: doc/tutorial.md:1340 +#: doc/tutorial.md:1341 #, no-wrap msgid "" "~~~\n" @@ -2398,25 +2399,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1343 +#: doc/tutorial.md:1344 msgid "" "// Put the vector into a mutable slot let mut mutable_crayons = crayons;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1347 +#: doc/tutorial.md:1348 msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1350 +#: doc/tutorial.md:1351 msgid "" "This is a simple example of Rust's _dual-mode data structures_, also " "referred to as _freezing and thawing_." msgstr "" #. type: Plain text -#: doc/tutorial.md:1358 +#: doc/tutorial.md:1359 msgid "" "Strings are implemented with vectors of `u8`, though they have a distinct " "type. They support most of the same allocation options as vectors, though " @@ -2427,47 +2428,47 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1362 +#: doc/tutorial.md:1363 msgid "" "~~~ // A plain string is a slice to read-only (static) memory let " "stack_crayons: &str = \"Almond, AntiqueBrass, Apricot\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1365 +#: doc/tutorial.md:1366 msgid "" "// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, " "Asparagus, AtomicTangerine\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1368 +#: doc/tutorial.md:1369 msgid "" "// A local heap (managed) string let local_crayons: @str = @\"BananaMania, " "Beaver, Bittersweet\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1372 +#: doc/tutorial.md:1373 msgid "" "// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, " "BlizzardBlue, Blue\"; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1376 +#: doc/tutorial.md:1377 msgid "" "Both vectors and strings support a number of useful [methods](#functions-and-" "methods), defined in [`std::vec`] and [`std::str`]. Here are some examples." msgstr "" #. type: Plain text -#: doc/tutorial.md:1379 +#: doc/tutorial.md:1380 msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1390 +#: doc/tutorial.md:1391 #, no-wrap msgid "" "~~~\n" @@ -2483,19 +2484,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1392 +#: doc/tutorial.md:1393 msgid "let crayons = [Almond, AntiqueBrass, Apricot];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1396 +#: doc/tutorial.md:1397 msgid "" "// Check the length of the vector assert!(crayons.len() == 3); assert!(!" "crayons.is_empty());" msgstr "" #. type: Plain text -#: doc/tutorial.md:1403 +#: doc/tutorial.md:1404 #, no-wrap msgid "" "// Iterate over a vector, obtaining a pointer to each element\n" @@ -2507,21 +2508,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1407 +#: doc/tutorial.md:1408 msgid "" "// Map vector elements let crayon_names = crayons.map(|v| " "crayon_to_str(*v)); let favorite_crayon_name = crayon_names[0];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1410 +#: doc/tutorial.md:1411 msgid "" "// Remove whitespace from before and after the string let " "new_favorite_crayon_name = favorite_crayon_name.trim();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1416 +#: doc/tutorial.md:1417 #, no-wrap msgid "" "if favorite_crayon_name.len() > 5 {\n" @@ -2532,12 +2533,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1418 +#: doc/tutorial.md:1419 msgid "# Closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1423 +#: doc/tutorial.md:1424 msgid "" "Named functions, like those we've seen so far, may not refer to local " "variables declared outside the function: they do not close over their " @@ -2546,12 +2547,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1426 +#: doc/tutorial.md:1427 msgid "~~~~ {.ignore} let foo = 10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1431 +#: doc/tutorial.md:1432 #, no-wrap msgid "" "fn bar() -> int {\n" @@ -2561,31 +2562,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1434 +#: doc/tutorial.md:1435 msgid "" "Rust also supports _closures_, functions that can access variables in the " "enclosing scope." msgstr "" #. type: Plain text -#: doc/tutorial.md:1437 +#: doc/tutorial.md:1438 msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }" msgstr "" #. type: Plain text -#: doc/tutorial.md:1440 +#: doc/tutorial.md:1441 msgid "" "let captured_var = 20; let closure = |arg| println(fmt!(\"captured_var=%d, " "arg=%d\", captured_var, arg));" msgstr "" #. type: Plain text -#: doc/tutorial.md:1443 +#: doc/tutorial.md:1444 msgid "call_closure_with_ten(closure); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1449 +#: doc/tutorial.md:1450 msgid "" "Closures begin with the argument list between vertical bars and are followed " "by a single expression. Remember that a block, `{ ; ; ... }`, " @@ -2595,7 +2596,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1454 +#: doc/tutorial.md:1455 msgid "" "The types of the arguments are generally omitted, as is the return type, " "because the compiler can almost always infer them. In the rare case where " @@ -2604,12 +2605,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1458 +#: doc/tutorial.md:1459 msgid "~~~~ let square = |x: int| -> uint { x * x as uint }; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1462 +#: doc/tutorial.md:1463 msgid "" "There are several forms of closure, each with its own role. The most common, " "called a _stack closure_, has type `&fn` and can directly access local " @@ -2617,12 +2618,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1467 +#: doc/tutorial.md:1468 msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1476 +#: doc/tutorial.md:1477 msgid "" "Stack closures are very efficient because their environment is allocated on " "the call stack and refers by pointer to captured locals. To ensure that " @@ -2634,12 +2635,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1478 +#: doc/tutorial.md:1479 msgid "## Managed closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1484 +#: doc/tutorial.md:1485 msgid "" "When you need to store a closure in a data structure, a stack closure will " "not do, since the compiler will refuse to let you store it. For this " @@ -2649,7 +2650,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1489 +#: doc/tutorial.md:1490 msgid "" "A managed closure does not directly access its environment, but merely " "copies out the values that it closes over into a private data structure. " @@ -2658,14 +2659,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1492 +#: doc/tutorial.md:1493 msgid "" "This code creates a closure that adds a given string to its argument, " "returns it from a function, and then calls it:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1498 +#: doc/tutorial.md:1499 #, no-wrap msgid "" "~~~~\n" @@ -2676,7 +2677,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1504 +#: doc/tutorial.md:1505 #, no-wrap msgid "" "fn main() {\n" @@ -2687,12 +2688,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1506 +#: doc/tutorial.md:1507 msgid "## Owned closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1513 +#: doc/tutorial.md:1514 msgid "" "Owned closures, written `~fn` in analogy to the `~` pointer type, hold on to " "things that can safely be sent between processes. They copy the values they " @@ -2702,17 +2703,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1515 +#: doc/tutorial.md:1516 msgid "[tasks]: tutorial-tasks.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1517 +#: doc/tutorial.md:1518 msgid "## Closure compatibility" msgstr "" #. type: Plain text -#: doc/tutorial.md:1524 +#: doc/tutorial.md:1525 msgid "" "Rust closures have a convenient subtyping property: you can pass any kind of " "closure (as long as the arguments and return types match) to functions that " @@ -2723,7 +2724,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1532 +#: doc/tutorial.md:1533 msgid "" "~~~~ fn call_twice(f: &fn()) { f(); f(); } let closure = || { \"I'm a " "closure, and it doesn't matter what type I am\"; }; fn function() { \"I'm a " @@ -2731,7 +2732,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1536 +#: doc/tutorial.md:1537 msgid "" "> ***Note:*** Both the syntax and the semantics will be changing > in small " "ways. At the moment they can be unsound in some > scenarios, particularly " @@ -2739,26 +2740,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1538 +#: doc/tutorial.md:1539 msgid "## Do syntax" msgstr "" #. type: Plain text -#: doc/tutorial.md:1541 +#: doc/tutorial.md:1542 msgid "" "The `do` expression provides a way to treat higher-order functions " "(functions that take closures as arguments) as control structures." msgstr "" #. type: Plain text -#: doc/tutorial.md:1544 +#: doc/tutorial.md:1545 msgid "" "Consider this function that iterates over a vector of integers, passing in a " "pointer to each integer in the vector:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1554 +#: doc/tutorial.md:1555 #, no-wrap msgid "" "~~~~\n" @@ -2773,14 +2774,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1558 +#: doc/tutorial.md:1559 msgid "" "As a caller, if we use a closure to provide the final operator argument, we " "can write it in a way that has a pleasant, block-like structure." msgstr "" #. type: Plain text -#: doc/tutorial.md:1566 +#: doc/tutorial.md:1567 #, no-wrap msgid "" "~~~~\n" @@ -2793,14 +2794,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1569 +#: doc/tutorial.md:1570 msgid "" "This is such a useful pattern that Rust has a special form of function call " "that can be written more like a built-in control structure:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1577 +#: doc/tutorial.md:1578 #, no-wrap msgid "" "~~~~\n" @@ -2813,7 +2814,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1582 +#: doc/tutorial.md:1583 msgid "" "The call is prefixed with the keyword `do` and, instead of writing the final " "closure inside the argument list, it appears outside of the parentheses, " @@ -2821,7 +2822,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1587 +#: doc/tutorial.md:1588 msgid "" "`do` is a convenient way to create tasks with the `task::spawn` function. " "`spawn` has the signature `spawn(fn: ~fn())`. In other words, it is a " @@ -2829,12 +2830,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1590 +#: doc/tutorial.md:1591 msgid "~~~~ use std::task::spawn;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1595 +#: doc/tutorial.md:1596 #, no-wrap msgid "" "do spawn() || {\n" @@ -2844,7 +2845,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1599 +#: doc/tutorial.md:1600 msgid "" "Look at all those bars and parentheses -- that's two empty argument lists " "back to back. Since that is so unsightly, empty argument lists may be " @@ -2852,7 +2853,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1606 +#: doc/tutorial.md:1607 #, no-wrap msgid "" "~~~~\n" @@ -2864,7 +2865,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1609 +#: doc/tutorial.md:1610 msgid "" "If you want to see the output of `debug!` statements, you will need to turn " "on `debug!` logging. To enable `debug!` logging, set the RUST_LOG " @@ -2873,12 +2874,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1611 +#: doc/tutorial.md:1612 msgid "# Methods" msgstr "" #. type: Plain text -#: doc/tutorial.md:1617 +#: doc/tutorial.md:1618 msgid "" "Methods are like functions except that they always begin with a special " "argument, called `self`, which has the type of the method's receiver. The " @@ -2887,7 +2888,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1621 +#: doc/tutorial.md:1622 msgid "" "_Implementations_, written with the `impl` keyword, can define methods on " "most Rust types, including structs and enums. As an example, let's define a " @@ -2895,7 +2896,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1629 +#: doc/tutorial.md:1630 #, no-wrap msgid "" "~~~\n" @@ -2908,7 +2909,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1634 +#: doc/tutorial.md:1635 #, no-wrap msgid "" "enum Shape {\n" @@ -2918,7 +2919,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1643 +#: doc/tutorial.md:1644 #, no-wrap msgid "" "impl Shape {\n" @@ -2932,12 +2933,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1647 +#: doc/tutorial.md:1648 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1651 +#: doc/tutorial.md:1652 msgid "" "This defines an _implementation_ for `Shape` containing a single method, " "`draw`. In most respects the `draw` method is defined like any other " @@ -2945,7 +2946,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1656 +#: doc/tutorial.md:1657 msgid "" "The type of `self` is the type on which the method is implemented, or a " "pointer thereof. As an argument it is written either `self`, `&self`, " @@ -2954,7 +2955,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1671 +#: doc/tutorial.md:1672 #, no-wrap msgid "" "~~~\n" @@ -2974,26 +2975,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1673 +#: doc/tutorial.md:1674 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);" msgstr "" #. type: Plain text -#: doc/tutorial.md:1679 +#: doc/tutorial.md:1680 msgid "" "(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s." "draw_value(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1683 +#: doc/tutorial.md:1684 msgid "" "Methods typically take a borrowed pointer self type, so the compiler will go " "to great lengths to convert a callee to a borrowed pointer." msgstr "" #. type: Plain text -#: doc/tutorial.md:1701 +#: doc/tutorial.md:1702 #, no-wrap msgid "" "~~~\n" @@ -3016,29 +3017,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1704 +#: doc/tutorial.md:1705 msgid "(@s).draw_borrowed(); (~s).draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1708 +#: doc/tutorial.md:1709 msgid "" "// Unlike typical function arguments, the self value will // automatically " "be referenced ... s.draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1711 +#: doc/tutorial.md:1712 msgid "// ... and dereferenced (& &s).draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1715 +#: doc/tutorial.md:1716 msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1719 +#: doc/tutorial.md:1720 msgid "" "Implementations may also define standalone (sometimes called \"static\") " "methods. The absence of a `self` parameter distinguishes such methods. " @@ -3046,7 +3047,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1726 +#: doc/tutorial.md:1727 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -3058,7 +3059,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1728 +#: doc/tutorial.md:1729 msgid "" "To call such a method, just prefix it with the type name and a double colon:" msgstr "" @@ -3069,10 +3070,9 @@ msgstr "" msgid "" "~~~~\n" "# use std::float::consts::pi;\n" -"# use std::float::sqrt;\n" "struct Circle { radius: float }\n" "impl Circle {\n" -" fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" +" fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "let c = Circle::new(42.5);\n" "~~~~\n" @@ -3525,39 +3525,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2004 +#: doc/tutorial.md:2003 msgid "" -"~~~~ # use std::float::consts::pi; # use std::float::sqrt; trait Shape { fn " -"new(area: float) -> Self; } struct Circle { radius: float } struct Square " -"{ length: float }" +"~~~~ # use std::float::consts::pi; trait Shape { fn new(area: float) -> " +"Self; } struct Circle { radius: float } struct Square { length: float }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2011 +#: doc/tutorial.md:2010 #, no-wrap msgid "" "impl Shape for Circle {\n" -" fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" +" fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "impl Shape for Square {\n" -" fn new(area: float) -> Square { Square { length: sqrt(area) } }\n" +" fn new(area: float) -> Square { Square { length: (area).sqrt() } }\n" "}\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2016 +#: doc/tutorial.md:2015 msgid "" "let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::" "new(area); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2018 +#: doc/tutorial.md:2017 msgid "## Bounded type parameters and static method dispatch" msgstr "" #. type: Plain text -#: doc/tutorial.md:2023 +#: doc/tutorial.md:2022 msgid "" "Traits give us a language for defining predicates on types, or abstract " "properties that types can have. We can use this language to define _bounds_ " @@ -3565,7 +3564,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2032 +#: doc/tutorial.md:2031 #, no-wrap msgid "" "~~~~\n" @@ -3579,7 +3578,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2038 +#: doc/tutorial.md:2037 msgid "" "Declaring `T` as conforming to the `Printable` trait (as we earlier did with " "`Copy`) makes it possible to call methods from that trait on values of type " @@ -3589,14 +3588,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2041 +#: doc/tutorial.md:2040 msgid "" "Type parameters can have multiple bounds by separating them with `+`, as in " "this version of `print_all` that copies elements." msgstr "" #. type: Plain text -#: doc/tutorial.md:2053 +#: doc/tutorial.md:2052 #, no-wrap msgid "" "~~~\n" @@ -3613,7 +3612,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2057 +#: doc/tutorial.md:2056 msgid "" "Method calls to bounded type parameters are _statically dispatched_, " "imposing no more overhead than normal function invocation, so are the " @@ -3621,17 +3620,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2059 +#: doc/tutorial.md:2058 msgid "This usage of traits is similar to Haskell type classes." msgstr "" #. type: Plain text -#: doc/tutorial.md:2061 +#: doc/tutorial.md:2060 msgid "## Trait objects and dynamic method dispatch" msgstr "" #. type: Plain text -#: doc/tutorial.md:2065 +#: doc/tutorial.md:2064 msgid "" "The above allows us to define functions that polymorphically act on values " "of a single unknown type that conforms to a given trait. However, consider " @@ -3639,7 +3638,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2071 +#: doc/tutorial.md:2070 msgid "" "~~~~ # type Circle = int; type Rectangle = int; # impl Drawable for int { fn " "draw(&self) {} } # fn new_circle() -> int { 1 } trait Drawable { fn " @@ -3647,7 +3646,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2078 +#: doc/tutorial.md:2077 #, no-wrap msgid "" "fn draw_all(shapes: ~[T]) {\n" @@ -3659,7 +3658,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2084 +#: doc/tutorial.md:2083 msgid "" "You can call that on an array of circles, or an array of rectangles " "(assuming those have suitable `Drawable` traits defined), but not on an " @@ -3668,7 +3667,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2091 +#: doc/tutorial.md:2090 #, no-wrap msgid "" "~~~~\n" @@ -3680,7 +3679,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2096 +#: doc/tutorial.md:2095 msgid "" "In this example, there is no type parameter. Instead, the `@Drawable` type " "denotes any managed box value that implements the `Drawable` trait. To " @@ -3689,7 +3688,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2103 +#: doc/tutorial.md:2102 msgid "" "~~~~ # type Circle = int; type Rectangle = bool; # trait Drawable { fn " "draw(&self); } # fn new_circle() -> Circle { 1 } # fn new_rectangle() -> " @@ -3697,21 +3696,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2106 +#: doc/tutorial.md:2105 msgid "" "impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for " "Rectangle { fn draw(&self) { ... } }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2111 +#: doc/tutorial.md:2110 msgid "" "let c: @Circle = @new_circle(); let r: @Rectangle = @new_rectangle(); " "draw_all([c as @Drawable, r as @Drawable]); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2119 +#: doc/tutorial.md:2118 msgid "" "We omit the code for `new_circle` and `new_rectangle`; imagine that these " "just return `Circle`s and `Rectangle`s with a default size. Note that, like " @@ -3722,7 +3721,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2133 +#: doc/tutorial.md:2132 msgid "" "~~~ # type Circle = int; type Rectangle = int; # trait Drawable { fn " "draw(&self); } # impl Drawable for int { fn draw(&self) {} } # fn " @@ -3733,7 +3732,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2138 +#: doc/tutorial.md:2137 msgid "" "Method calls to trait types are _dynamically dispatched_. Since the compiler " "doesn't know specifically which functions to call at compile time, it uses a " @@ -3742,17 +3741,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2140 +#: doc/tutorial.md:2139 msgid "This usage of traits is similar to Java interfaces." msgstr "" #. type: Plain text -#: doc/tutorial.md:2142 +#: doc/tutorial.md:2141 msgid "## Trait inheritance" msgstr "" #. type: Plain text -#: doc/tutorial.md:2147 +#: doc/tutorial.md:2146 msgid "" "We can write a trait declaration that _inherits_ from other traits, called " "_supertraits_. Types that implement a trait must also implement its " @@ -3761,32 +3760,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2152 +#: doc/tutorial.md:2151 msgid "" "~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn " "radius(&self) -> float; } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2154 +#: doc/tutorial.md:2153 msgid "" "Now, we can implement `Circle` on a type only if we also implement `Shape`." msgstr "" #. type: Plain text -#: doc/tutorial.md:2170 +#: doc/tutorial.md:2168 #, no-wrap msgid "" "~~~~\n" "# use std::float::consts::pi;\n" -"# use std::float::sqrt;\n" "# trait Shape { fn area(&self) -> float; }\n" "# trait Circle : Shape { fn radius(&self) -> float; }\n" "# struct Point { x: float, y: float }\n" "# fn square(x: float) -> float { x * x }\n" "struct CircleStruct { center: Point, radius: float }\n" "impl Circle for CircleStruct {\n" -" fn radius(&self) -> float { sqrt(self.area() / pi) }\n" +" fn radius(&self) -> float { (self.area() / pi).sqrt() }\n" "}\n" "impl Shape for CircleStruct {\n" " fn area(&self) -> float { pi * square(self.radius) }\n" @@ -3795,7 +3793,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2175 +#: doc/tutorial.md:2173 msgid "" "Notice that methods of `Circle` can call methods on `Shape`, as our `radius` " "implementation calls the `area` method. This is a silly way to compute the " @@ -3804,18 +3802,18 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2200 +#: doc/tutorial.md:2197 msgid "" -"~~~ {.xfail-test} # use std::float::consts::pi; # use std::float::sqrt; # " -"trait Shape { fn area(&self) -> float; } # trait Circle : Shape { fn " -"radius(&self) -> float; } # struct Point { x: float, y: float } # struct " -"CircleStruct { center: Point, radius: float } # impl Circle for CircleStruct " -"{ fn radius(&self) -> float { sqrt(self.area() / pi) } } # impl Shape for " +"~~~ {.xfail-test} # use std::float::consts::pi; # trait Shape { fn " +"area(&self) -> float; } # trait Circle : Shape { fn radius(&self) -> " +"float; } # struct Point { x: float, y: float } # struct CircleStruct " +"{ center: Point, radius: float } # impl Circle for CircleStruct { fn " +"radius(&self) -> float { (self.area() / pi).sqrt() } } # impl Shape for " "CircleStruct { fn area(&self) -> float { pi * square(self.radius) } }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2205 +#: doc/tutorial.md:2202 msgid "" "let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; let " "mycircle: Circle = concrete as @Circle; let nonsense = mycircle.radius() * " @@ -3823,17 +3821,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2207 +#: doc/tutorial.md:2204 msgid "> ***Note:*** Trait inheritance does not actually work with objects yet" msgstr "" #. type: Plain text -#: doc/tutorial.md:2209 +#: doc/tutorial.md:2206 msgid "## Deriving implementations for traits" msgstr "" #. type: Plain text -#: doc/tutorial.md:2216 +#: doc/tutorial.md:2213 msgid "" "A small number of traits in `std` and `extra` can have implementations that " "can be automatically derived. These instances are specified by placing the " @@ -3844,17 +3842,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2220 +#: doc/tutorial.md:2217 msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2224 +#: doc/tutorial.md:2221 msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2228 +#: doc/tutorial.md:2225 msgid "" "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, " "`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, " @@ -3862,19 +3860,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2230 +#: doc/tutorial.md:2227 msgid "# Modules and crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2234 +#: doc/tutorial.md:2231 msgid "" "The Rust namespace is arranged in a hierarchy of modules. Each source (.rs) " "file represents a single module and may in turn contain additional modules." msgstr "" #. type: Plain text -#: doc/tutorial.md:2240 +#: doc/tutorial.md:2237 #, no-wrap msgid "" "~~~~\n" @@ -3885,7 +3883,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2245 +#: doc/tutorial.md:2242 #, no-wrap msgid "" "fn main() {\n" @@ -3895,7 +3893,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2250 +#: doc/tutorial.md:2247 msgid "" "The contents of modules can be imported into the current scope with the " "`use` keyword, optionally giving it an alias. `use` may appear at the " @@ -3903,14 +3901,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2256 +#: doc/tutorial.md:2253 msgid "" "~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` " "into scope use farm::chicken;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2266 +#: doc/tutorial.md:2263 #, no-wrap msgid "" "fn chicken_farmer() {\n" @@ -3925,7 +3923,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2273 +#: doc/tutorial.md:2270 msgid "" "These farm animal functions have a new keyword, `pub`, attached to them. The " "`pub` keyword modifies an item's visibility, making it visible outside its " @@ -3935,7 +3933,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2280 +#: doc/tutorial.md:2277 msgid "" "Visibility restrictions in Rust exist only at module boundaries. This is " "quite different from most object-oriented languages that also enforce " @@ -3946,7 +3944,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2293 +#: doc/tutorial.md:2290 #, no-wrap msgid "" "~~~\n" @@ -3964,7 +3962,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2299 +#: doc/tutorial.md:2296 #, no-wrap msgid "" " impl Farm {\n" @@ -3975,7 +3973,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2305 +#: doc/tutorial.md:2302 #, no-wrap msgid "" " pub fn feed_animals(farm: &Farm) {\n" @@ -3986,7 +3984,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2315 +#: doc/tutorial.md:2312 #, no-wrap msgid "" "fn main() {\n" @@ -4001,12 +3999,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2317 +#: doc/tutorial.md:2314 msgid "## Crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2321 +#: doc/tutorial.md:2318 msgid "" "The unit of independent compilation in Rust is the crate: rustc compiles a " "single crate at a time, from which it produces either a library or an " @@ -4014,7 +4012,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2326 +#: doc/tutorial.md:2323 msgid "" "When compiling a single `.rs` source file, the file acts as the whole " "crate. You can compile it with the `--lib` compiler switch to create a " @@ -4023,7 +4021,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2331 +#: doc/tutorial.md:2328 msgid "" "Larger crates typically span multiple files and are, by convention, compiled " "from a source file with the `.rc` extension, called a *crate file*. The " @@ -4032,7 +4030,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2340 +#: doc/tutorial.md:2337 msgid "" "A typical crate file declares attributes associated with the crate that may " "affect how the compiler processes the source. Crate attributes specify " @@ -4043,34 +4041,34 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2344 +#: doc/tutorial.md:2341 msgid "" "~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers " "= \"2.5\", author = \"mjh\")];" msgstr "" #. type: Plain text -#: doc/tutorial.md:2347 +#: doc/tutorial.md:2344 msgid "// Make a library (\"bin\" is the default) #[crate_type = \"lib\"];" msgstr "" #. type: Plain text -#: doc/tutorial.md:2350 +#: doc/tutorial.md:2347 msgid "// Turn on a warning #[warn(non_camel_case_types)]" msgstr "" #. type: Plain text -#: doc/tutorial.md:2353 +#: doc/tutorial.md:2350 msgid "// Link to the standard library extern mod std;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2358 +#: doc/tutorial.md:2355 msgid "// Load some modules from other files mod cow; mod chicken; mod horse;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2363 +#: doc/tutorial.md:2360 #, no-wrap msgid "" "fn main() {\n" @@ -4080,7 +4078,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2370 +#: doc/tutorial.md:2367 msgid "" "Compiling this file will cause `rustc` to look for files named `cow.rs`, " "`chicken.rs`, and `horse.rs` in the same directory as the `.rc` file, " @@ -4090,21 +4088,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2374 +#: doc/tutorial.md:2371 msgid "" "The `#[link(...)]` attribute provides meta information about the module, " "which other crates can use to load the right module. More about that later." msgstr "" #. type: Plain text -#: doc/tutorial.md:2377 +#: doc/tutorial.md:2374 msgid "" "To have a nested directory structure for your source files, you can nest " "mods:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2384 +#: doc/tutorial.md:2381 #, no-wrap msgid "" "~~~~ {.ignore}\n" @@ -4116,7 +4114,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2389 +#: doc/tutorial.md:2386 msgid "" "The compiler will now look for `poultry/chicken.rs` and `poultry/turkey.rs`, " "and export their content in `poultry::chicken` and `poultry::turkey`. You " @@ -4125,12 +4123,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2391 +#: doc/tutorial.md:2388 msgid "## Using other crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2399 +#: doc/tutorial.md:2396 msgid "" "The `extern mod` directive lets you use a crate (once it's been compiled " "into a library) from inside another crate. `extern mod` can appear at the " @@ -4141,17 +4139,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2401 +#: doc/tutorial.md:2398 msgid "For example, `extern mod std` links the [standard library]." msgstr "" #. type: Plain text -#: doc/tutorial.md:2403 +#: doc/tutorial.md:2400 msgid "[standard library]: std/index.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:2410 +#: doc/tutorial.md:2407 msgid "" "When a comma-separated list of name/value pairs appears after `extern mod`, " "the compiler front-end matches these pairs against the attributes provided " @@ -4161,22 +4159,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2412 +#: doc/tutorial.md:2409 msgid "Our example crate declared this set of `link` attributes:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2416 +#: doc/tutorial.md:2413 msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2418 +#: doc/tutorial.md:2415 msgid "Which you can then link with any (or all) of the following:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2424 +#: doc/tutorial.md:2421 msgid "" "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", " "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = " @@ -4184,45 +4182,45 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2427 +#: doc/tutorial.md:2424 msgid "" "If any of the requested metadata do not match, then the crate will not be " "compiled successfully." msgstr "" #. type: Plain text -#: doc/tutorial.md:2429 +#: doc/tutorial.md:2426 msgid "## A minimal example" msgstr "" #. type: Plain text -#: doc/tutorial.md:2432 +#: doc/tutorial.md:2429 msgid "" "Now for something that you can actually compile yourself, we have these two " "files:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2438 +#: doc/tutorial.md:2435 msgid "" "~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() " "-> &str { \"world\" } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2444 +#: doc/tutorial.md:2441 msgid "" "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello " "\" + world::explore()); } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2446 +#: doc/tutorial.md:2443 msgid "Now compile and run like this (adjust to your platform if necessary):" msgstr "" #. type: Plain text -#: doc/tutorial.md:2453 +#: doc/tutorial.md:2450 #, no-wrap msgid "" "~~~~ {.notrust}\n" @@ -4234,7 +4232,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2458 +#: doc/tutorial.md:2455 msgid "" "Notice that the library produced contains the version in the filename as " "well as an inscrutable string of alphanumerics. These are both part of " @@ -4243,12 +4241,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2460 +#: doc/tutorial.md:2457 msgid "## The standard library" msgstr "" #. type: Plain text -#: doc/tutorial.md:2465 +#: doc/tutorial.md:2462 msgid "" "The Rust standard library provides runtime features required by the " "language, including the task scheduler and memory allocators, as well as " @@ -4257,7 +4255,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2476 +#: doc/tutorial.md:2473 msgid "" "[`std`] includes modules corresponding to each of the integer types, each of " "the floating point types, the [`bool`] type, [tuples], [characters], " @@ -4271,25 +4269,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2478 +#: doc/tutorial.md:2475 msgid "### Standard Library injection and the Rust prelude" msgstr "" #. type: Plain text -#: doc/tutorial.md:2481 +#: doc/tutorial.md:2478 msgid "" "`std` is imported at the topmost level of every crate by default, as if the " "first line of each crate was" msgstr "" #. type: Plain text -#: doc/tutorial.md:2483 +#: doc/tutorial.md:2480 #, no-wrap msgid " extern mod std;\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2487 +#: doc/tutorial.md:2484 msgid "" "This means that the contents of std can be accessed from from any context " "with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, " @@ -4297,7 +4295,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2492 +#: doc/tutorial.md:2489 msgid "" "Additionally, `std` contains a `prelude` module that reexports many of the " "most common standard modules, types and traits. The contents of the prelude " @@ -4306,13 +4304,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2494 +#: doc/tutorial.md:2491 #, no-wrap msgid " use std::prelude::*;\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2520 +#: doc/tutorial.md:2517 msgid "" "[`std`]: std/index.html [`bool`]: std/bool.html [tuples]: std/tuple.html " "[characters]: std/char.html [strings]: std/str.html [vectors]: std/vec.html " @@ -4326,56 +4324,56 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2522 +#: doc/tutorial.md:2519 msgid "# What next?" msgstr "" #. type: Plain text -#: doc/tutorial.md:2525 +#: doc/tutorial.md:2522 msgid "" "Now that you know the essentials, check out any of the additional tutorials " "on individual topics." msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Borrowed pointers][borrow]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Tasks and communication][tasks]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Macros][macros]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[The foreign function interface][ffi]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Containers and iterators](tutorial-container.html)" msgstr "" #. type: Plain text -#: doc/tutorial.md:2533 +#: doc/tutorial.md:2530 msgid "There is further documentation on the [wiki]." msgstr "" #. type: Plain text -#: doc/tutorial.md:2538 +#: doc/tutorial.md:2535 msgid "" "[borrow]: tutorial-borrowed-ptr.html [tasks]: tutorial-tasks.html [macros]: " "tutorial-macros.html [ffi]: tutorial-ffi.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:2544 +#: doc/tutorial.md:2541 msgid "" "[wiki]: https://github.com/mozilla/rust/wiki/Docs [unit testing]: https://" "github.com/mozilla/rust/wiki/Doc-unit-testing [rustdoc]: https://github.com/" @@ -4385,7 +4383,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2545 +#: doc/tutorial.md:2542 msgid "" "[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust" msgstr "" diff --git a/mk/docs.mk b/mk/docs.mk index 14480dfed00f9..cc86111b728d4 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -236,6 +236,9 @@ GENERATED += doc/version.md doc/version_info.html docs: $(DOCS) docs-l10n: - po4a doc/po4a.conf + po4a --copyright-holder="The Rust Project Developers" \ + --package-name="Rust" \ + --package-version="$(CFG_RELEASE)" \ + doc/po4a.conf .PHONY: docs-l10n diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 9eacddd90028b..35600df4f9dd0 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -173,11 +173,11 @@ impl Deque for DList { let tail_own = match tail.prev.resolve() { None => { self.list_tail = Rawlink::none(); - self.list_head.swap_unwrap() + self.list_head.take_unwrap() }, Some(tail_prev) => { self.list_tail = tail.prev; - tail_prev.next.swap_unwrap() + tail_prev.next.take_unwrap() } }; Some(tail_own.value) @@ -465,7 +465,7 @@ impl<'self, A> ListInsertion for MutDListIterator<'self, A> { Some(prev) => prev, }; let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()}; - let node_own = prev_node.next.swap_unwrap(); + let node_own = prev_node.next.take_unwrap(); ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node)); prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node)); self.list.length += 1; diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs index 6876b3510b6ca..11e3106e4b5a9 100644 --- a/src/libextra/net/ip.rs +++ b/src/libextra/net/ip.rs @@ -116,7 +116,7 @@ pub fn get_addr(node: &str, iotask: &iotask) let (output_po, output_ch) = stream(); let mut output_ch = Some(SharedChan::new(output_ch)); do str::as_buf(node) |node_ptr, len| { - let output_ch = output_ch.swap_unwrap(); + let output_ch = output_ch.take_unwrap(); debug!("slice len %?", len); let handle = create_uv_getaddrinfo_t(); let handle_ptr: *uv_getaddrinfo_t = &handle; diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 27e9f8cd60f33..200e824209450 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -161,8 +161,8 @@ impl SmallIntMap { /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { - match self.v[i - 1] { - Some(ref elt) => if !it(i - 1, elt) { return false; }, + match self.v[i] { + Some(ref elt) => if !it(i, elt) { return false; }, None => () } } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index b9d25451a8a95..632f5d7827d4c 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -260,7 +260,7 @@ impl<'self> Condvar<'self> { signal_waitqueue(&state.waiters); } // Enqueue ourself to be woken up by a signaller. - let SignalEnd = SignalEnd.swap_unwrap(); + let SignalEnd = SignalEnd.take_unwrap(); state.blocked[condvar_id].tail.send(SignalEnd); } else { out_of_bounds = Some(state.blocked.len()); @@ -281,7 +281,7 @@ impl<'self> Condvar<'self> { // Unconditionally "block". (Might not actually block if a // signaller already sent -- I mean 'unconditionally' in contrast // with acquire().) - let _ = comm::recv_one(WaitEnd.swap_unwrap()); + let _ = comm::recv_one(WaitEnd.take_unwrap()); } // This is needed for a failing condition variable to reacquire the @@ -353,7 +353,7 @@ impl<'self> Condvar<'self> { } } do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { - let queue = queue.swap_unwrap(); + let queue = queue.take_unwrap(); broadcast_waitqueue(&queue) } } @@ -1436,7 +1436,7 @@ mod tests { do x.write_downgrade |xwrite| { let mut xopt = Some(xwrite); do y.write_downgrade |_ywrite| { - y.downgrade(xopt.swap_unwrap()); + y.downgrade(xopt.take_unwrap()); error!("oops, y.downgrade(x) should have failed!"); } } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f1fe7acb00f83..bd13c8619be1d 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -552,7 +552,7 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, // Remove left horizontal link by rotating right fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { - let mut save = node.left.swap_unwrap(); + let mut save = node.left.take_unwrap(); swap(&mut node.left, &mut save.right); // save.right now None swap(node, &mut save); node.right = Some(save); @@ -564,7 +564,7 @@ fn skew(node: &mut ~TreeNode) { fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { - let mut save = node.right.swap_unwrap(); + let mut save = node.right.take_unwrap(); swap(&mut node.right, &mut save.left); // save.left now None save.level += 1; swap(node, &mut save); @@ -643,7 +643,7 @@ fn remove(node: &mut Option<~TreeNode>, Equal => { if save.left.is_some() { if save.right.is_some() { - let mut left = save.left.swap_unwrap(); + let mut left = save.left.take_unwrap(); if left.right.is_some() { heir_swap(save, &mut left.right); } else { @@ -653,13 +653,13 @@ fn remove(node: &mut Option<~TreeNode>, save.left = Some(left); (remove(&mut save.left, key), true) } else { - let new = save.left.swap_unwrap(); + let new = save.left.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); - *save = save.left.swap_unwrap(); + *save = save.left.take_unwrap(); (Some(value), true) } } else if save.right.is_some() { - let new = save.right.swap_unwrap(); + let new = save.right.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); (Some(value), true) } else { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index af39dea6d79e1..2cf99e07dc9f1 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -165,10 +165,58 @@ pub fn classify(e: &expr, pub fn lookup_const(tcx: ty::ctxt, e: &expr) -> Option<@expr> { match tcx.def_map.find(&e.id) { Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id), + Some(&ast::def_variant(enum_def, variant_def)) => lookup_variant_by_id(tcx, + enum_def, + variant_def), _ => None } } +pub fn lookup_variant_by_id(tcx: ty::ctxt, + enum_def: ast::def_id, + variant_def: ast::def_id) + -> Option<@expr> { + fn variant_expr(variants: &[ast::variant], id: ast::node_id) -> Option<@expr> { + for variants.iter().advance |variant| { + if variant.node.id == id { + return variant.node.disr_expr; + } + } + None + } + + if ast_util::is_local(enum_def) { + match tcx.items.find(&enum_def.node) { + None => None, + Some(&ast_map::node_item(it, _)) => match it.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + Some(_) => None + } + } else { + let maps = astencode::Maps { + root_map: @mut HashMap::new(), + method_map: @mut HashMap::new(), + vtable_map: @mut HashMap::new(), + write_guard_map: @mut HashSet::new(), + capture_map: @mut HashMap::new() + }; + match csearch::maybe_get_item_ast(tcx, enum_def, + |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) { + csearch::found(ast::ii_item(item)) => match item.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + _ => None + } + } +} + pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::def_id) -> Option<@expr> { @@ -237,13 +285,13 @@ pub enum const_val { } pub fn eval_const_expr(tcx: middle::ty::ctxt, e: &expr) -> const_val { - match eval_const_expr_partial(tcx, e) { + match eval_const_expr_partial(&tcx, e) { Ok(r) => r, Err(s) => tcx.sess.span_fatal(e.span, s) } } -pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) +pub fn eval_const_expr_partial(tcx: &T, e: &expr) -> Result { use middle::ty; fn fromb(b: bool) -> Result { Ok(const_int(b as i64)) } @@ -360,7 +408,7 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_cast(base, _) => { - let ety = ty::expr_ty(tcx, e); + let ety = tcx.expr_ty(e); let base = eval_const_expr_partial(tcx, base); match /*bad*/copy base { Err(_) => base, @@ -390,8 +438,8 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_path(_) => { - match lookup_const(tcx, e) { - Some(actual_e) => eval_const_expr_partial(tcx, actual_e), + match lookup_const(tcx.ty_ctxt(), e) { + Some(actual_e) => eval_const_expr_partial(&tcx.ty_ctxt(), actual_e), None => Err(~"Non-constant path in constant expr") } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 9a75601a08288..cce5a9d85f59f 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -309,7 +309,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { "explicit copy requires a copyable argument"); } expr_repeat(element, count_expr, _) => { - let count = ty::eval_repeat_count(cx.tcx, count_expr); + let count = ty::eval_repeat_count(&cx.tcx, count_expr); if count > 1 { let element_ty = ty::expr_ty(cx.tcx, element); check_copy(cx, element_ty, element.span, diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index b679da714a174..d18fbada009a1 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -108,17 +108,22 @@ pub fn level_to_str(lv: level) -> &'static str { } } -#[deriving(Eq)] +#[deriving(Eq, Ord)] pub enum level { allow, warn, deny, forbid } -struct LintSpec { +#[deriving(Eq)] +pub struct LintSpec { lint: lint, desc: &'static str, default: level } +impl Ord for LintSpec { + fn lt(&self, other: &LintSpec) -> bool { self.default < other.default } +} + pub type LintDict = HashMap<&'static str, LintSpec>; enum AttributedNode<'self> { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d7c0490751332..b2d14dce4d854 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1610,6 +1610,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, llfndecl: ValueRef, id: ast::node_id, output_type: ty::t, + skip_retptr: bool, param_substs: Option<@param_substs>, sp: Option) -> fn_ctxt { @@ -1653,7 +1654,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, fcx.llenv = unsafe { llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) }; - if !ty::type_is_nil(substd_output_type) { + if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) { fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type)); } fcx @@ -1665,7 +1666,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext, output_type: ty::t, sp: Option) -> fn_ctxt { - new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp) + new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp) } // NB: must keep 4 fns in sync: @@ -1859,6 +1860,7 @@ pub fn trans_closure(ccx: @mut CrateContext, llfndecl, id, output_type, + false, param_substs, Some(body.span)); let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); @@ -2068,6 +2070,7 @@ pub fn trans_enum_variant_or_tuple_like_struct( llfndecl, ctor_id, result_ty, + false, param_substs, None); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index edf003e3e529e..d9de1657da273 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -10,7 +10,7 @@ use back::{link, abi}; -use lib::llvm::{ValueRef}; +use lib::llvm::{Pointer, ValueRef}; use lib; use middle::trans::base::*; use middle::trans::cabi; @@ -550,6 +550,66 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ref_id: Option) { debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); + fn simple_llvm_intrinsic(bcx: block, name: &'static str, num_args: uint) { + assert!(num_args <= 4); + let mut args = [0 as ValueRef, ..4]; + let first_real_arg = bcx.fcx.arg_pos(0u); + for uint::range(0, num_args) |i| { + args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); + } + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Ret(bcx, Call(bcx, llfn, args.slice(0, num_args))); + } + + fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); + } + + fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); + } + + fn count_zeros_intrinsic(bcx: block, name: &'static str) { + let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); + let y = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Ret(bcx, Call(bcx, llfn, [x, y])); + } + let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); let fcx = new_fn_ctxt_w_id(ccx, @@ -557,16 +617,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, decl, item.id, output_type, + true, Some(substs), Some(item.span)); + set_always_inline(fcx.llfn); + // Set the fixed stack segment flag if necessary. if attr::attrs_contains_name(attributes, "fixed_stack_segment") { set_fixed_stack_segment(fcx.llfn); } let mut bcx = top_scope_block(fcx, None); - let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); let nm = ccx.sess.str_of(item.ident); @@ -595,17 +657,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg + 2u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "load" => { let old = AtomicLoad(bcx, get_param(decl, first_real_arg), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "store" => { AtomicStore(bcx, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg), order); + RetVoid(bcx); } op => { // These are all AtomicRMW ops @@ -627,12 +690,10 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } } - finish_fn(fcx, lltop, bcx); - return; } @@ -640,8 +701,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty))); } "move_val" => { // Create a datum reflecting the value being moved. @@ -655,6 +715,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, get_param(decl, first_real_arg)); + RetVoid(bcx); } "move_val_init" => { // See comments for `"move_val"`. @@ -663,18 +724,17 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); + RetVoid(bcx); } "min_align_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty))); } "pref_align_of"=> { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))); } "get_tydesc" => { let tp_ty = substs.tys[0]; @@ -687,19 +747,31 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // the llvm type of intrinsic::TyDesc struct. let userland_tydesc_ty = type_of::type_of(ccx, output_type); let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty); - Store(bcx, td, fcx.llretptr.get()); + Ret(bcx, td); } "init" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - if !ty::type_is_nil(tp_ty) { - Store(bcx, C_null(lltp_ty), fcx.llretptr.get()); + match bcx.fcx.llretptr { + Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); } + None if ty::type_is_nil(tp_ty) => RetVoid(bcx), + None => Ret(bcx, C_null(lltp_ty)), } } "uninit" => { // Do nothing, this is effectively a no-op + let retty = substs.tys[0]; + if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) { + unsafe { + Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref())); + } + } else { + RetVoid(bcx) + } + } + "forget" => { + RetVoid(bcx); } - "forget" => {} "transmute" => { let (in_type, out_type) = (substs.tys[0], substs.tys[1]); let llintype = type_of::type_of(ccx, in_type); @@ -726,34 +798,45 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } if !ty::type_is_nil(out_type) { - let lldestptr = fcx.llretptr.get(); let llsrcval = get_param(decl, first_real_arg); if ty::type_is_immediate(ccx.tcx, in_type) { - let lldestptr = PointerCast(bcx, lldestptr, llintype.ptr_to()); - Store(bcx, llsrcval, lldestptr); + match fcx.llretptr { + Some(llretptr) => { + Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to())); + RetVoid(bcx); + } + None => match (llintype.kind(), llouttype.kind()) { + (Pointer, other) | (other, Pointer) if other != Pointer => { + let tmp = Alloca(bcx, llouttype, ""); + Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to())); + Ret(bcx, Load(bcx, tmp)); + } + _ => Ret(bcx, BitCast(bcx, llsrcval, llouttype)) + } + } } else { // NB: Do not use a Load and Store here. This causes massive // code bloat when `transmute` is used on large structural // types. + let lldestptr = fcx.llretptr.get(); let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p()); let llsize = llsize_of(ccx, llintype); call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); + RetVoid(bcx); }; + } else { + RetVoid(bcx); } } "needs_drop" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty))); } "contains_managed" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed())); } "visit_tydesc" => { let td = get_param(decl, first_real_arg); @@ -763,6 +846,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to()); glue::call_tydesc_glue_full(bcx, visitor, td, abi::tydesc_field_visit_glue, None); + RetVoid(bcx); } "frame_address" => { let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress"); @@ -789,6 +873,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, bcx, None, fty, ty::mk_nil(), |bcx| Callee {bcx: bcx, data: Closure(datum)}, ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx; + RetVoid(bcx); } "morestack_addr" => { // XXX This is a hack to grab the address of this particular @@ -798,334 +883,65 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); - Store(bcx, morestack_addr, fcx.llretptr.get()); - } - "memcpy32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memcpy64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memset32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "memset64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "sqrtf32" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f32"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "sqrtf64" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f64"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "powif32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f32"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "powif64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f64"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "sinf32" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f32"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "sinf64" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f64"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "cosf32" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f32"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "cosf64" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f64"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "powf32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f32"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "powf64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f64"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "expf32" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f32"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "expf64" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f64"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "exp2f32" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f32"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "exp2f64" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f64"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "logf32" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f32"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "logf64" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f64"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "log10f32" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f32"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log10f64" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f64"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log2f32" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f32"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "log2f64" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f64"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "fmaf32" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f32"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fmaf64" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f64"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fabsf32" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f32"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "fabsf64" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f64"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "floorf32" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f32"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "floorf64" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f64"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "ceilf32" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f32"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "ceilf64" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f64"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "truncf32" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f32"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "truncf64" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f64"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "ctpop8" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i8"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop16" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i16"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop32" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i32"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop64" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i64"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctlz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i8"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i16"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i32"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i64"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "cttz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i8"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i16"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i32"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i64"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "bswap16" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i16"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap32" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i32"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap64" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i64"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } + Ret(bcx, morestack_addr); + } + "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), + "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), + "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), + "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64), + "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32), + "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64), + "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1), + "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1), + "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2), + "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2), + "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1), + "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1), + "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1), + "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1), + "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2), + "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2), + "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1), + "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1), + "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1), + "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1), + "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1), + "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1), + "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1), + "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1), + "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1), + "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1), + "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3), + "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3), + "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1), + "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1), + "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1), + "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1), + "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1), + "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1), + "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1), + "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1), + "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1), + "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1), + "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1), + "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1), + "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"), + "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"), + "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"), + "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"), + "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"), + "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"), + "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"), + "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"), + "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1), + "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1), + "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1), _ => { // Could we make this an enum rather than a string? does it get // checked earlier? ccx.sess.span_bug(item.span, "unknown intrinsic"); } } - finish_fn(fcx, lltop, bcx); } /** diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 2a16b13677428..be840f6a295dc 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -420,7 +420,7 @@ pub fn write_content(bcx: block, return expr::trans_into(bcx, element, Ignore); } SaveIn(lldest) => { - let count = ty::eval_repeat_count(bcx.tcx(), count_expr); + let count = ty::eval_repeat_count(&bcx.tcx(), count_expr); if count == 0 { return bcx; } @@ -512,7 +512,7 @@ pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint { }, ast::expr_vec(ref es, _) => es.len(), ast::expr_repeat(_, count_expr, _) => { - ty::eval_repeat_count(bcx.tcx(), count_expr) + ty::eval_repeat_count(&bcx.tcx(), count_expr) } _ => bcx.tcx().sess.span_bug(content_expr.span, "Unexpected evec content") diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c9bf94776c0e2..5e118b25a5fdd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4232,42 +4232,57 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { return t_norm; } +pub trait ExprTyProvider { + pub fn expr_ty(&self, ex: &ast::expr) -> t; + pub fn ty_ctxt(&self) -> ctxt; +} + +impl ExprTyProvider for ctxt { + pub fn expr_ty(&self, ex: &ast::expr) -> t { + expr_ty(*self, ex) + } + + pub fn ty_ctxt(&self) -> ctxt { + *self + } +} + // Returns the repeat count for a repeating vector expression. -pub fn eval_repeat_count(tcx: ctxt, count_expr: &ast::expr) -> uint { +pub fn eval_repeat_count(tcx: &T, count_expr: &ast::expr) -> uint { match const_eval::eval_const_expr_partial(tcx, count_expr) { Ok(ref const_val) => match *const_val { const_eval::const_int(count) => if count < 0 { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found negative integer"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found negative integer"); return 0; } else { return count as uint }, const_eval::const_uint(count) => return count as uint, const_eval::const_float(count) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found float"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found float"); return count as uint; } const_eval::const_str(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found string"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found string"); return 0; } const_eval::const_bool(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found boolean"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found boolean"); return 0; } }, Err(*) => { - tcx.sess.span_err(count_expr.span, - "expected constant integer for repeat count \ - but found variable"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected constant integer for repeat count \ + but found variable"); return 0; } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d0e793160fedc..e9297b12ed0fd 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -479,7 +479,7 @@ pub fn ast_ty_to_ty( } } ast::ty_fixed_length_vec(ref a_mt, e) => { - match const_eval::eval_const_expr_partial(tcx, e) { + match const_eval::eval_const_expr_partial(&tcx, e) { Ok(ref r) => { match *r { const_eval::const_int(i) => diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 8ffff56a9c485..87d45294967a2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -83,7 +83,7 @@ use middle::pat_util; use middle::lint::unreachable_code; use middle::ty::{FnSig, VariantInfo_}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; -use middle::ty::{substs, param_ty}; +use middle::ty::{substs, param_ty, ExprTyProvider}; use middle::ty; use middle::typeck::astconv::AstConv; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; @@ -290,6 +290,16 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, } } +impl ExprTyProvider for FnCtxt { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { + self.expr_ty(ex) + } + + pub fn ty_ctxt(&self) -> ty::ctxt { + self.ccx.tcx + } +} + pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { let visit = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_item: |a| check_item(ccx, a), @@ -797,7 +807,7 @@ impl FnCtxt { pat.repr(self.tcx()) } - pub fn expr_ty(&self, ex: @ast::expr) -> ty::t { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { match self.inh.node_types.find(&ex.id) { Some(&t) => t, None => { @@ -2250,8 +2260,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_repeat(element, count_expr, mutbl) => { - let _ = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let _ = ty::eval_repeat_count(fcx, count_expr); let tt = ast_expr_vstore_to_vstore(fcx, ev, vst); let mutability = match vst { ast::expr_vstore_mut_box | ast::expr_vstore_mut_slice => { @@ -2730,8 +2740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } ast::expr_repeat(element, count_expr, mutbl) => { - let count = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let count = ty::eval_repeat_count(fcx, count_expr); let t: ty::t = fcx.infcx().next_ty_var(); check_expr_has_type(fcx, element, t); let element_ty = fcx.expr_ty(element); @@ -3126,7 +3136,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, // that the expression is in an form that eval_const_expr can // handle, so we may still get an internal compiler error - match const_eval::eval_const_expr_partial(ccx.tcx, e) { + match const_eval::eval_const_expr_partial(&ccx.tcx, e) { Ok(const_eval::const_int(val)) => { *disr_val = val as int; } diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 787d8d5685a34..6f638959bc830 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -144,6 +144,7 @@ Additional help: } pub fn describe_warnings() { + use extra::sort::Sort; io::println(fmt!(" Available lint options: -W Warn about @@ -153,8 +154,15 @@ Available lint options: ")); let lint_dict = lint::get_lint_dict(); + let mut lint_dict = lint_dict.consume_iter() + .transform(|(k, v)| (v, k)) + .collect::<~[(lint::LintSpec, &'static str)]>(); + lint_dict.qsort(); + let mut max_key = 0; - for lint_dict.each_key |k| { max_key = num::max(k.len(), max_key); } + for lint_dict.iter().advance |&(_, name)| { + max_key = num::max(name.len(), max_key); + } fn padded(max: uint, s: &str) -> ~str { str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s } @@ -163,17 +171,12 @@ Available lint options: padded(max_key, "name"), "default", "meaning")); io::println(fmt!(" %s %7.7s %s\n", padded(max_key, "----"), "-------", "-------")); - for lint_dict.iter().advance |(k, v)| { - let k = k.replace("_", "-"); + for lint_dict.consume_iter().advance |(spec, name)| { + let name = name.replace("_", "-"); io::println(fmt!(" %s %7.7s %s", - padded(max_key, k), - match v.default { - lint::allow => ~"allow", - lint::warn => ~"warn", - lint::deny => ~"deny", - lint::forbid => ~"forbid" - }, - v.desc)); + padded(max_key, name), + lint::level_to_str(spec.default), + spec.desc)); } io::println(""); } diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index be170cce07e54..6c1640e683e59 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -41,7 +41,7 @@ magic. use prelude::*; -use task::local_data_priv::{local_get, local_pop, local_set, Handle}; +use task::local_data_priv::*; #[cfg(test)] use task; @@ -95,6 +95,13 @@ pub fn get(key: Key<@T>, f: &fn(Option<&@T>) -> U) -> U { pub fn get(key: Key, f: &fn(Option<&T>) -> U) -> U { unsafe { local_get(Handle::new(), key, f) } } +/** + * Retrieve a mutable borrowed pointer to a task-local data value. + */ +#[cfg(not(stage0))] +pub fn get_mut(key: Key, f: &fn(Option<&mut T>) -> U) -> U { + unsafe { local_get_mut(Handle::new(), key, f) } +} /** * Store a value in task-local data. If this key already has a value, * that value is overwritten (and its destructor is run). @@ -262,6 +269,34 @@ fn test_static_pointer() { fn test_owned() { static key: Key<~int> = &Key; set(key, ~1); + + do get(key) |v| { + do get(key) |v| { + do get(key) |v| { + assert_eq!(**v.unwrap(), 1); + } + assert_eq!(**v.unwrap(), 1); + } + assert_eq!(**v.unwrap(), 1); + } + set(key, ~2); + do get(key) |v| { + assert_eq!(**v.unwrap(), 2); + } +} + +#[test] +fn test_get_mut() { + static key: Key = &Key; + set(key, 1); + + do get_mut(key) |v| { + *v.unwrap() = 2; + } + + do get(key) |v| { + assert_eq!(*v.unwrap(), 2); + } } #[test] @@ -283,3 +318,43 @@ fn test_same_key_type() { get(key4, |x| assert_eq!(*x.unwrap(), 4)); get(key5, |x| assert_eq!(*x.unwrap(), 5)); } + +#[test] +#[should_fail] +fn test_nested_get_set1() { + static key: Key = &Key; + set(key, 4); + do get(key) |_| { + set(key, 4); + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut2() { + static key: Key = &Key; + set(key, 4); + do get(key) |_| { + get_mut(key, |_| {}) + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut3() { + static key: Key = &Key; + set(key, 4); + do get_mut(key) |_| { + get(key, |_| {}) + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut4() { + static key: Key = &Key; + set(key, 4); + do get_mut(key) |_| { + get_mut(key, |_| {}) + } +} diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 75e0bbcb71b04..cef32b5c7e445 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -29,28 +29,38 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = (-1 as $T) << (bits - 1); pub static max_value: $T = min_value - 1 as $T; +enum Range { Closed, HalfOpen } + +#[inline] /// -/// Iterate over the range [`lo`..`hi`) +/// Iterate through a range with a given step value. /// -/// # Arguments +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. /// -/// * `lo` - lower bound, inclusive -/// * `hi` - higher bound, exclusive -/// -/// # Examples -/// ~~~ -/// let mut sum = 0; -/// for int::range(1, 5) |i| { -/// sum += i; -/// } -/// assert!(sum == 10); -/// ~~~ +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. /// -#[inline] -pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { +fn range_step_core(start: $T, stop: $T, step: $T, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); + } else if step == (1 as $T) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } @@ -66,9 +76,55 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { i += step; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// * `x_i == start + step*i`, and +/// * `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ +/// let mut sum = 0; +/// for int::range(1, 5) |i| { +/// sum += i; +/// } +/// assert!(sum == 10); +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } + #[inline] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { @@ -76,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T, it) } impl Num for $T {} @@ -841,7 +898,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index de1b997b14b52..54c1327fa9303 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -30,32 +30,46 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = 0 as $T; pub static max_value: $T = 0 as $T - 1 as $T; +enum Range { Closed, HalfOpen } + #[inline] -/** - * Iterate through a range with a given step value. - * - * # Examples - * ~~~ {.rust} - * let nums = [1,2,3,4,5,6,7]; - * - * for uint::range_step(0, nums.len() - 1, 2) |i| { - * println(fmt!("%d & %d", nums[i], nums[i+1])); - * } - * ~~~ - */ -pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { +/// +/// Iterate through a range with a given step value. +/// +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. +/// +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. +/// +fn range_step_core(start: $T, stop: $T, step: $T_SIGNED, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!("range_step called with step == 0"); - } - if step >= 0 { + } else if step == (1 as $T_SIGNED) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T_SIGNED) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } + } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } // avoiding overflow. break if i + step > max_value if i > max_value - (step as $T) { return true; } i += step as $T; } - } else { + } else { // descending while i > stop { if !it(i) { return false; } // avoiding underflow. break if i + step < min_value @@ -63,7 +77,52 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> i -= -step as $T; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// - `x_i == start + step*i`, and +/// - `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ {.rust} +/// let nums = [1,2,3,4,5,6,7]; +/// +/// for uint::range_step(0, nums.len() - 1, 2) |i| { +/// println(fmt!("%d & %d", nums[i], nums[i+1])); +/// } +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } #[inline] @@ -73,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T_SIGNED, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T_SIGNED, it) } impl Num for $T {} @@ -603,7 +663,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 222952a6dc143..b0811674a7bfa 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -203,14 +203,14 @@ impl Option { /// Apply a function to the contained value or do nothing pub fn mutate(&mut self, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } } /// Apply a function to the contained value or set it to a default pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } else { *self = Some(def); } @@ -293,8 +293,8 @@ impl Option { * Fails if the value equals `None`. */ #[inline] - pub fn swap_unwrap(&mut self) -> T { - if self.is_none() { fail!("option::swap_unwrap none") } + pub fn take_unwrap(&mut self) -> T { + if self.is_none() { fail!("option::take_unwrap none") } util::replace(self, None).unwrap() } @@ -460,7 +460,7 @@ fn test_option_dance() { let mut y = Some(5); let mut y2 = 0; for x.iter().advance |_x| { - y2 = y.swap_unwrap(); + y2 = y.take_unwrap(); } assert_eq!(y2, 5); assert!(y.is_none()); @@ -468,8 +468,8 @@ fn test_option_dance() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_option_too_much_dance() { let mut y = Some(util::NonCopyable); - let _y2 = y.swap_unwrap(); - let _y3 = y.swap_unwrap(); + let _y2 = y.take_unwrap(); + let _y3 = y.take_unwrap(); } #[test] diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 6e9aef7773051..4e4145ddc161f 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -328,7 +328,7 @@ impl Scheduler { /// Given an input Coroutine sends it back to its home scheduler. fn send_task_home(task: ~Task) { let mut task = task; - let mut home = task.home.swap_unwrap(); + let mut home = task.home.take_unwrap(); match home { Sched(ref mut home_handle) => { home_handle.send(PinnedTask(task)); @@ -418,7 +418,7 @@ impl Scheduler { do self.deschedule_running_task_and_then |sched, dead_task| { let mut dead_task = dead_task; - let coroutine = dead_task.coroutine.swap_unwrap(); + let coroutine = dead_task.coroutine.take_unwrap(); coroutine.recycle(&mut sched.stack_pool); } @@ -506,7 +506,7 @@ impl Scheduler { this.metrics.context_switches_task_to_sched += 1; unsafe { - let blocked_task = this.current_task.swap_unwrap(); + let blocked_task = this.current_task.take_unwrap(); let f_fake_region = transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f); let f_opaque = ClosureConverter::from_fn(f_fake_region); @@ -538,7 +538,7 @@ impl Scheduler { rtdebug!("switching tasks"); this.metrics.context_switches_task_to_task += 1; - let old_running_task = this.current_task.swap_unwrap(); + let old_running_task = this.current_task.take_unwrap(); let f_fake_region = unsafe { transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f) @@ -576,7 +576,7 @@ impl Scheduler { assert!(self.cleanup_job.is_some()); - let cleanup_job = self.cleanup_job.swap_unwrap(); + let cleanup_job = self.cleanup_job.take_unwrap(); match cleanup_job { DoNothing => { } GiveTask(task, f) => (f.to_fn())(self, task) diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 17d0d59660f1b..449438b920551 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -127,7 +127,7 @@ impl Task { // Wait for children. Possibly report the exit status. let local_success = !self.unwinder.unwinding; - let join_latch = self.join_latch.swap_unwrap(); + let join_latch = self.join_latch.take_unwrap(); match self.on_exit { Some(ref on_exit) => { let success = join_latch.wait(local_success); diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs index 013eb438c3657..f61eee8859b1a 100644 --- a/src/libstd/rt/tube.rs +++ b/src/libstd/rt/tube.rs @@ -53,7 +53,7 @@ impl Tube { if (*state).blocked_task.is_some() { // There's a waiting task. Wake it up rtdebug!("waking blocked tube"); - let task = (*state).blocked_task.swap_unwrap(); + let task = (*state).blocked_task.take_unwrap(); let sched = Local::take::(); sched.resume_task_immediately(task); } diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs index f3d1024024ff8..81428509e33e5 100644 --- a/src/libstd/rt/uv/async.rs +++ b/src/libstd/rt/uv/async.rs @@ -62,7 +62,7 @@ impl AsyncWatcher { let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { uvll::free_handle(handle as *c_void); } diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs index a3630c9b9bf8d..28b101f686d4c 100644 --- a/src/libstd/rt/uv/idle.rs +++ b/src/libstd/rt/uv/idle.rs @@ -73,7 +73,7 @@ impl IdleWatcher { let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle); { let data = idle_watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } idle_watcher.drop_watcher_data(); uvll::idle_delete(handle); diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs index 6d096f9885a7d..09c748ec04782 100644 --- a/src/libstd/rt/uv/net.rs +++ b/src/libstd/rt/uv/net.rs @@ -209,7 +209,7 @@ impl StreamWatcher { let write_request: WriteRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = write_request.stream(); write_request.delete(); - let cb = stream_watcher.get_watcher_data().write_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -233,7 +233,7 @@ impl StreamWatcher { extern fn close_cb(handle: *uvll::uv_stream_t) { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); - stream_watcher.get_watcher_data().close_cb.swap_unwrap()(); + stream_watcher.get_watcher_data().close_cb.take_unwrap()(); stream_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } @@ -301,7 +301,7 @@ impl TcpWatcher { let connect_request: ConnectRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = connect_request.stream(); connect_request.delete(); - let cb = stream_watcher.get_watcher_data().connect_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -438,7 +438,7 @@ impl UdpWatcher { let send_request: UdpSendRequest = NativeHandle::from_native_handle(req); let mut udp_watcher = send_request.handle(); send_request.delete(); - let cb = udp_watcher.get_watcher_data().udp_send_cb.swap_unwrap(); + let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap(); let status = status_to_maybe_uv_error(udp_watcher.native_handle(), status); cb(udp_watcher, status); } @@ -456,7 +456,7 @@ impl UdpWatcher { extern fn close_cb(handle: *uvll::uv_udp_t) { let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle); - udp_watcher.get_watcher_data().close_cb.swap_unwrap()(); + udp_watcher.get_watcher_data().close_cb.take_unwrap()(); udp_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index 14465eb7dfd3a..bc5399327a032 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -70,7 +70,7 @@ impl TimerWatcher { let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 17dc604a17858..883870db1e673 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -669,7 +669,7 @@ fn spawn_process_os(prog: &str, args: &[~str], fail!("failure in dup3(err_fd, 2): %s", os::last_os_error()); } // close all other fds - for int::range_rev(getdtablesize() as int - 1, 2) |fd| { + for int::range_rev(getdtablesize() as int, 3) |fd| { close(fd as c_int); } diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index d46e5707f14a9..75fd6eacc1b3a 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -44,6 +44,21 @@ impl Handle { } } +#[deriving(Eq)] +enum LoanState { + NoLoan, ImmLoan, MutLoan +} + +impl LoanState { + fn describe(&self) -> &'static str { + match *self { + NoLoan => "no loan", + ImmLoan => "immutable", + MutLoan => "mutable" + } + } +} + trait LocalData {} impl LocalData for T {} @@ -77,7 +92,7 @@ impl LocalData for T {} // // n.b. If TLS is used heavily in future, this could be made more efficient with // a proper map. -type TaskLocalMap = ~[Option<(*libc::c_void, TLSValue, uint)>]; +type TaskLocalMap = ~[Option<(*libc::c_void, TLSValue, LoanState)>]; type TLSValue = ~LocalData:; fn cleanup_task_local_map(map_ptr: *libc::c_void) { @@ -152,9 +167,10 @@ pub unsafe fn local_pop(handle: Handle, for map.mut_iter().advance |entry| { match *entry { - Some((k, _, loans)) if k == key_value => { - if loans != 0 { - fail!("TLS value has been loaned via get already"); + Some((k, _, loan)) if k == key_value => { + if loan != NoLoan { + fail!("TLS value cannot be removed because it is already \ + borrowed as %s", loan.describe()); } // Move the data out of the `entry` slot via util::replace. This // is guaranteed to succeed because we already matched on `Some` @@ -192,6 +208,29 @@ pub unsafe fn local_pop(handle: Handle, pub unsafe fn local_get(handle: Handle, key: local_data::Key, f: &fn(Option<&T>) -> U) -> U { + local_get_with(handle, key, ImmLoan, f) +} + +pub unsafe fn local_get_mut(handle: Handle, + key: local_data::Key, + f: &fn(Option<&mut T>) -> U) -> U { + do local_get_with(handle, key, MutLoan) |x| { + match x { + None => f(None), + // We're violating a lot of compiler guarantees with this + // invocation of `transmute_mut`, but we're doing runtime checks to + // ensure that it's always valid (only one at a time). + // + // there is no need to be upset! + Some(x) => { f(Some(cast::transmute_mut(x))) } + } + } +} + +unsafe fn local_get_with(handle: Handle, + key: local_data::Key, + state: LoanState, + f: &fn(Option<&T>) -> U) -> U { // This function must be extremely careful. Because TLS can store owned // values, and we must have some form of `get` function other than `pop`, // this function has to give a `&` reference back to the caller. @@ -218,12 +257,24 @@ pub unsafe fn local_get(handle: Handle, None => { return f(None); } Some(i) => { let ret; + let mut return_loan = false; match map[i] { - Some((_, ref data, ref mut loans)) => { - *loans = *loans + 1; + Some((_, ref data, ref mut loan)) => { + match (state, *loan) { + (_, NoLoan) => { + *loan = state; + return_loan = true; + } + (ImmLoan, ImmLoan) => {} + (want, cur) => { + fail!("TLS slot cannot be borrowed as %s because \ + it is already borrowed as %s", + want.describe(), cur.describe()); + } + } // data was created with `~~T as ~LocalData`, so we extract // pointer part of the trait, (as ~~T), and then use - // compiler coercions to achieve a '&' pointer + // compiler coercions to achieve a '&' pointer. match *cast::transmute::<&TLSValue, &(uint, ~~T)>(data) { (_vtable, ref box) => { let value: &T = **box; @@ -238,9 +289,11 @@ pub unsafe fn local_get(handle: Handle, // 'f' returned because `f` could have appended more TLS items which // in turn relocated the vector. Hence we do another lookup here to // fixup the loans. - match map[i] { - Some((_, _, ref mut loans)) => { *loans = *loans - 1; } - None => { libc::abort(); } + if return_loan { + match map[i] { + Some((_, _, ref mut loan)) => { *loan = NoLoan; } + None => { libc::abort(); } + } } return ret; } @@ -269,9 +322,10 @@ pub unsafe fn local_set(handle: Handle, // First see if the map contains this key already let curspot = map.iter().position(|entry| { match *entry { - Some((ekey, _, loans)) if key == ekey => { - if loans != 0 { - fail!("TLS value has been loaned via get already"); + Some((ekey, _, loan)) if key == ekey => { + if loan != NoLoan { + fail!("TLS value cannot be overwritten because it is + already borrowed as %s", loan.describe()) } true } @@ -286,7 +340,7 @@ pub unsafe fn local_set(handle: Handle, } match insertion_position(map, keyval) { - Some(i) => { map[i] = Some((keyval, data, 0)); } - None => { map.push(Some((keyval, data, 0))); } + Some(i) => { map[i] = Some((keyval, data, NoLoan)); } + None => { map.push(Some((keyval, data, NoLoan))); } } } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 206d19e175fe9..bf09a533ebe12 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -302,7 +302,7 @@ fn each_ancestor(list: &mut AncestorList, fn with_parent_tg(parent_group: &mut Option, blk: &fn(TaskGroupInner) -> U) -> U { // If this trips, more likely the problem is 'blk' failed inside. - let tmp_arc = parent_group.swap_unwrap(); + let tmp_arc = parent_group.take_unwrap(); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; *parent_group = Some(tmp_arc); result @@ -609,7 +609,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { }; if opts.notify_chan.is_some() { - let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = opts.notify_chan.take_unwrap(); let notify_chan = Cell::new(notify_chan); let on_exit: ~fn(bool) = |success| { notify_chan.take().send( @@ -647,7 +647,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let notify_chan = if opts.notify_chan.is_none() { None } else { - Some(opts.notify_chan.swap_unwrap()) + Some(opts.notify_chan.take_unwrap()) }; let child_wrapper = make_child_wrapper(new_task, child_tg, diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 3882ab0de6333..396fdaf2e6a55 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -287,7 +287,7 @@ impl TrieNode { fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { - match self.children[idx - 1] { + match self.children[idx] { Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () @@ -488,7 +488,7 @@ mod test_map { m.insert(x, x / 2); } - let mut n = uint::max_value - 9999; + let mut n = uint::max_value - 10000; for m.each |k, v| { if n == uint::max_value - 5000 { break } assert!(n < uint::max_value - 5000); @@ -525,7 +525,7 @@ mod test_map { m.insert(x, x / 2); } - let mut n = uint::max_value; + let mut n = uint::max_value - 1; for m.each_reverse |k, v| { if n == uint::max_value - 5000 { break } assert!(n > uint::max_value - 5000); diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 2bd53f81b0581..0bf492ae55f0c 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -60,8 +60,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index b5b5b685d87c4..a5f96b35999e2 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -56,8 +56,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); diff --git a/src/test/codegen/iterate-over-array.cc b/src/test/codegen/iterate-over-array.cc new file mode 100644 index 0000000000000..7eca21b13d70b --- /dev/null +++ b/src/test/codegen/iterate-over-array.cc @@ -0,0 +1,17 @@ +#include +#include + +struct slice { + int const *p; + size_t len; +}; + +extern "C" +size_t test(slice s) { + size_t y = 0; + for (int i = 0; i < s.len; ++i) { + assert(i < s.len); + y += s.p[i]; + } + return y; +} diff --git a/src/test/codegen/iterate-over-array.rs b/src/test/codegen/iterate-over-array.rs new file mode 100644 index 0000000000000..cf54e6eafbaf1 --- /dev/null +++ b/src/test/codegen/iterate-over-array.rs @@ -0,0 +1,10 @@ +#[no_mangle] +fn test(x: &[int]) -> int { + let mut y = 0; + let mut i = 0; + while (i < x.len()) { + y += x[i]; + i += 1; + } + y +} diff --git a/src/test/codegen/scalar-function-call.cc b/src/test/codegen/scalar-function-call.cc new file mode 100644 index 0000000000000..91ed882f68a9f --- /dev/null +++ b/src/test/codegen/scalar-function-call.cc @@ -0,0 +1,10 @@ +#include + +size_t foo(size_t x) { + return x * x; +} + +extern "C" +void test() { + size_t x = foo(10); +} diff --git a/src/test/codegen/scalar-function-call.rs b/src/test/codegen/scalar-function-call.rs new file mode 100644 index 0000000000000..7e4a566749ba6 --- /dev/null +++ b/src/test/codegen/scalar-function-call.rs @@ -0,0 +1,8 @@ +fn foo(x: int) -> int { + x * x +} + +#[no_mangle] +fn test() { + let x = foo(10); +} diff --git a/src/test/codegen/small-dense-int-switch.cc b/src/test/codegen/small-dense-int-switch.cc new file mode 100644 index 0000000000000..87bc5bf852eb4 --- /dev/null +++ b/src/test/codegen/small-dense-int-switch.cc @@ -0,0 +1,11 @@ +#include + +extern "C" +size_t test(size_t x, size_t y) { + switch (x) { + case 1: return y; + case 2: return y*2; + case 4: return y*3; + default: return 11; + } +} diff --git a/src/test/codegen/small-dense-int-switch.rs b/src/test/codegen/small-dense-int-switch.rs new file mode 100644 index 0000000000000..6840dc7411b34 --- /dev/null +++ b/src/test/codegen/small-dense-int-switch.rs @@ -0,0 +1,9 @@ +#[no_mangle] +fn test(x: int, y: int) -> int { + match x { + 1 => y, + 2 => y*2, + 4 => y*3, + _ => 11 + } +} diff --git a/src/test/codegen/hello.cc b/src/test/codegen/stack-alloc-string-slice.cc similarity index 100% rename from src/test/codegen/hello.cc rename to src/test/codegen/stack-alloc-string-slice.cc diff --git a/src/test/codegen/hello.rs b/src/test/codegen/stack-alloc-string-slice.rs similarity index 100% rename from src/test/codegen/hello.rs rename to src/test/codegen/stack-alloc-string-slice.rs diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs new file mode 100644 index 0000000000000..ae590ad7d1f71 --- /dev/null +++ b/src/test/run-pass/enum-vec-initializer.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Flopsy { + Bunny = 2 +} + +static BAR:uint = Bunny as uint; +static BAR2:uint = BAR; + +fn main() { + let v = [0, .. Bunny as uint]; + let v = [0, .. BAR]; + let v = [0, .. BAR2]; + static BAR3:uint = BAR2; + let v = [0, .. BAR3]; +} \ No newline at end of file diff --git a/src/test/run-pass/num-range-rev.rs b/src/test/run-pass/num-range-rev.rs new file mode 100644 index 0000000000000..7262339e431d9 --- /dev/null +++ b/src/test/run-pass/num-range-rev.rs @@ -0,0 +1,114 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn uint_range_rev(hi: uint, lo: uint, it: &fn(uint) -> bool) -> bool { + uint::range_rev(hi, lo, it) +} + +fn int_range_rev(hi: int, lo: int, it: &fn(int) -> bool) -> bool { + int::range_rev(hi, lo, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, step: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, step, it) +} + + +pub fn main() { + // int and uint have same result for + // Sum{100 > i >= 2} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range_rev(100, 2) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range_rev(100, 2) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7,11]; + let mut prod = 1i; + for uint_range_rev(5, 0) |i| { + println(fmt!("uint 4 downto 0: %u", i)); + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); + let mut prod = 1i; + for int_range_rev(5, 0) |i| { + println(fmt!("int 4 downto 0: %d", i)); + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); + + + // range and range_rev are symmetric. + let mut sum_up = 0u; + for uint_range(10, 30) |i| { + sum_up += i; + } + let mut sum_down = 0u; + for uint_range_rev(30, 10) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + let mut sum_up = 0; + for int_range(-20, 10) |i| { + sum_up += i; + } + let mut sum_down = 0; + for int_range_rev(10, -20) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + + // empty ranges + for int_range_rev(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range_rev(0, 1) |_| { + fail!("range should be empty when start-1 underflows"); + } + + // range iterations do not wrap/underflow + let mut uflo_loop_visited = ~[]; + for int_range_step(int::min_value+15, int::min_value, -4) |x| { + uflo_loop_visited.push(x - int::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); + + let mut uflo_loop_visited = ~[]; + for uint_range_step(uint::min_value+15, uint::min_value, -4) |x| { + uflo_loop_visited.push(x - uint::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); +} diff --git a/src/test/run-pass/num-range.rs b/src/test/run-pass/num-range.rs new file mode 100644 index 0000000000000..7c1f905a049b6 --- /dev/null +++ b/src/test/run-pass/num-range.rs @@ -0,0 +1,119 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, s: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, s, it) +} + +pub fn main() { + println(fmt!("num-range start")); + // int and uint have same result for + // Sum{2 <= i < 100} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7]; + let mut prod = 1i; + for uint_range(0, 4) |i| { + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + let mut prod = 1i; + for int_range(0, 4) |i| { + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + + + // empty ranges + for int_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + + // range iterations do not wrap/overflow + let mut oflo_loop_visited = ~[]; + for uint_range_step(uint::max_value-15, uint::max_value, 4) |x| { + oflo_loop_visited.push(uint::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + let mut oflo_loop_visited = ~[]; + for int_range_step(int::max_value-15, int::max_value, 4) |x| { + oflo_loop_visited.push(int::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + + // range_step never passes nor visits the stop element + for int_range_step(0, 21, 3) |x| { + assert!(x < 21); + } + + // range_step_inclusive will never pass stop element, and may skip it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + + // range_step_inclusive will never pass stop element, but may visit it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + println(fmt!("saw: %u", x)); + if x == 21 { saw21 = true; } + } + assert!(saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(saw21); + +}