]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8531 : brson/rust/test-waitpid-workaround, r=graydon
authorbors <bors@rust-lang.org>
Sat, 17 Aug 2013 07:22:05 +0000 (00:22 -0700)
committerbors <bors@rust-lang.org>
Sat, 17 Aug 2013 07:22:05 +0000 (00:22 -0700)
...er

I believe the calls to waitpid are interacting badly with the message passing that goes
on between schedulers and causing us to have very little parallelism in
the test suite. I don't fully understand the sequence of events that causes
the problem here but clearly blocking on waitpid is something that a
well-behaved task should not be doing.

Unfortunately this adds quite a bit of overhead to each test: one thread, two
tasks, three stacks, so there's a tradeoff. The time to execute run-pass on
my 4-core machine goes from ~750s to ~300s.

This should have a pretty good impact on cycle times.

cc @toddaaro

173 files changed:
doc/po/ja/rust.md.po [new file with mode: 0644]
doc/po/ja/rustpkg.md.po [new file with mode: 0644]
doc/po/ja/tutorial-borrowed-ptr.md.po [new file with mode: 0644]
doc/po/ja/tutorial-container.md.po [new file with mode: 0644]
doc/po/ja/tutorial-ffi.md.po [new file with mode: 0644]
doc/po/ja/tutorial-macros.md.po [new file with mode: 0644]
doc/po/ja/tutorial-tasks.md.po [new file with mode: 0644]
doc/po/ja/tutorial.md.po [new file with mode: 0644]
doc/po/rust.md.pot
doc/po/rustpkg.md.pot
doc/po/tutorial-borrowed-ptr.md.pot
doc/po/tutorial-container.md.pot
doc/po/tutorial-ffi.md.pot
doc/po/tutorial-macros.md.pot
doc/po/tutorial-tasks.md.pot
doc/po/tutorial.md.pot
doc/po4a.conf
doc/tutorial-container.md
doc/tutorial.md
mk/docs.mk
src/compiletest/procsrv.rs
src/libextra/dlist.rs
src/libextra/priority_queue.rs
src/libextra/ringbuf.rs
src/libextra/rl.rs
src/libextra/sort.rs
src/libextra/stats.rs
src/libextra/test.rs
src/libextra/treemap.rs
src/librustc/back/link.rs
src/librustc/back/passes.rs
src/librustc/driver/driver.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/lint.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/rustc.rs
src/librustdoc/parse.rs
src/librusti/rusti.rs
src/librustpkg/rustpkg.rs
src/librustpkg/tests.rs
src/librustpkg/util.rs
src/libstd/at_vec.rs
src/libstd/c_str.rs
src/libstd/char.rs
src/libstd/either.rs
src/libstd/fmt/mod.rs
src/libstd/fmt/parse.rs
src/libstd/fmt/rt.rs
src/libstd/hashmap.rs
src/libstd/io.rs
src/libstd/iterator.rs
src/libstd/kinds.rs
src/libstd/local_data.rs
src/libstd/nil.rs [deleted file]
src/libstd/num/num.rs
src/libstd/option.rs
src/libstd/os.rs
src/libstd/path.rs
src/libstd/prelude.rs
src/libstd/ptr.rs
src/libstd/rand.rs
src/libstd/result.rs
src/libstd/rt/borrowck.rs
src/libstd/rt/logging.rs
src/libstd/rt/mod.rs
src/libstd/rt/task.rs
src/libstd/rt/uv/uvio.rs
src/libstd/rt/uv/uvll.rs
src/libstd/run.rs
src/libstd/std.rs
src/libstd/str.rs
src/libstd/str/ascii.rs
src/libstd/sys.rs
src/libstd/trie.rs
src/libstd/tuple.rs
src/libstd/unit.rs [new file with mode: 0644]
src/libstd/unstable/dynamic_lib.rs
src/libstd/unstable/lang.rs
src/libstd/unstable/raw.rs
src/libstd/vec.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/ifmt.rs
src/libsyntax/parse/parser.rs
src/libsyntax/visit.rs
src/snapshots.txt
src/test/auxiliary/iss.rs [new file with mode: 0644]
src/test/auxiliary/issue_3907.rs [new file with mode: 0644]
src/test/auxiliary/issue_8401.rs [new file with mode: 0644]
src/test/compile-fail/core-tls-store-pointer.rs
src/test/compile-fail/issue-3907.rs [new file with mode: 0644]
src/test/compile-fail/issue-4096.rs [new file with mode: 0644]
src/test/compile-fail/issue-5439.rs [new file with mode: 0644]
src/test/compile-fail/macro-local-data-key-priv.rs [new file with mode: 0644]
src/test/compile-fail/pattern-error-continue.rs
src/test/compile-fail/static-vec-repeat-not-constant.rs [new file with mode: 0644]
src/test/compile-fail/struct-pat-derived-error.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-for-loop.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-if.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-managed-closure.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-match.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-stack-closure.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-unconditional-loop.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-unique-closure.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-in-while.rs [new file with mode: 0644]
src/test/debug-info/lexical-scope-with-macro.rs [new file with mode: 0644]
src/test/debug-info/lexical-scopes-in-block-expression.rs [new file with mode: 0644]
src/test/debug-info/name-shadowing-and-scope-nesting.rs [new file with mode: 0644]
src/test/debug-info/shadowed-argument.rs [new file with mode: 0644]
src/test/debug-info/shadowed-variable.rs [new file with mode: 0644]
src/test/debug-info/simple-lexical-scope.rs [new file with mode: 0644]
src/test/debug-info/variable-scope.rs [deleted file]
src/test/run-fail/assert-eq-macro-fail [deleted file]
src/test/run-fail/borrowck-wg-fail-object-arg.rs [new file with mode: 0644]
src/test/run-fail/zip-different-lengths.rs [deleted file]
src/test/run-pass/c-stack-returning-int64.rs
src/test/run-pass/extoption_env-not-defined.rs
src/test/run-pass/foreign-fn-linkname.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/issue-4464.rs [new file with mode: 0644]
src/test/run-pass/issue-4759-1.rs [new file with mode: 0644]
src/test/run-pass/issue-4759.rs [new file with mode: 0644]
src/test/run-pass/issue-5666.rs [new file with mode: 0644]
src/test/run-pass/issue-5884.rs [new file with mode: 0644]
src/test/run-pass/issue-5917.rs [new file with mode: 0644]
src/test/run-pass/issue-5926.rs [new file with mode: 0644]
src/test/run-pass/issue-6318.rs [new file with mode: 0644]
src/test/run-pass/issue-6470.rs [new file with mode: 0644]
src/test/run-pass/issue-6557.rs [new file with mode: 0644]
src/test/run-pass/issue-6898.rs [new file with mode: 0644]
src/test/run-pass/issue-6919.rs [new file with mode: 0644]
src/test/run-pass/issue-7222.rs [new file with mode: 0644]
src/test/run-pass/issue-8248.rs [new file with mode: 0644]
src/test/run-pass/issue-8249.rs [new file with mode: 0644]
src/test/run-pass/issue-8398.rs [new file with mode: 0644]
src/test/run-pass/issue-8401.rs [new file with mode: 0644]
src/test/run-pass/issue-8498.rs [new file with mode: 0644]
src/test/run-pass/macro-local-data-key.rs [new file with mode: 0644]
src/test/run-pass/objects-coerce-freeze-borrored.rs [new file with mode: 0644]
src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs [new file with mode: 0644]
src/test/run-pass/repeat-expr-in-static.rs [new file with mode: 0644]
src/test/run-pass/zip-same-length.rs [deleted file]

diff --git a/doc/po/ja/rust.md.po b/doc/po/ja/rust.md.po
new file mode 100644 (file)
index 0000000..c74030f
--- /dev/null
@@ -0,0 +1,6495 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-08-12 02:06+0900\n"
+"PO-Revision-Date: 2013-08-05 19:40+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. type: Plain text
+#: doc/rust.md:2
+msgid "% Rust Reference Manual"
+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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/rust.md:7
+msgid ""
+"This document is the reference manual for the Rust programming language. It "
+"provides three kinds of material:"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:15
+msgid ""
+"Chapters that formally define the language grammar and, for each construct, "
+"informally describe its semantics and give examples of its use."
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:15
+msgid ""
+"Chapters that informally describe the memory model, concurrency model, "
+"runtime services, linkage model and debugging facilities."
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:15
+msgid ""
+"Appendix chapters providing rationale and references to languages that "
+"influenced the design."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:19
+msgid ""
+"This document does not serve as a tutorial introduction to the language. "
+"Background familiarity with the language is assumed. A separate [tutorial] "
+"document is available to help acquire such background familiarity."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:24
+msgid ""
+"This document also does not serve as a reference to the [standard] or "
+"[extra] libraries included in the language distribution. Those libraries are "
+"documented separately by extracting documentation attributes from their "
+"source code."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:28
+msgid ""
+"[tutorial]: tutorial.html [standard]: std/index.html [extra]: extra/index."
+"html"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:30 doc/rustpkg.md:8
+msgid "## Disclaimer"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:34
+msgid ""
+"Rust is a work in progress. The language continues to evolve as the design "
+"shifts and is fleshed out in working code. Certain parts work, certain parts "
+"do not, certain parts will be removed or changed."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:39
+msgid ""
+"This manual is a snapshot written in the present tense. All features "
+"described exist in working code unless otherwise noted, but some are quite "
+"primitive or remain to be further modified by planned work. Some may be "
+"temporary. It is a *draft*, and we ask that you not take anything you read "
+"here as final."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:43
+msgid ""
+"If you have suggestions to make, please try to focus them on *reductions* to "
+"the language: possible features that can be combined or omitted. We aim to "
+"keep the size and complexity of the language under control."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:52
+msgid ""
+"> **Note:** The grammar for Rust given in this document is rough and > very "
+"incomplete; only a modest number of sections have accompanying grammar > "
+"rules. Formalizing the grammar accepted by the Rust parser is ongoing work, "
+"> but future versions of this document will contain a complete > grammar. "
+"Moreover, we hope that this grammar will be extracted and verified > as "
+"LL(1) by an automated grammar-analysis tool, and further tested against the "
+"> Rust sources. Preliminary versions of this automation exist, but are not "
+"yet > complete."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:54
+msgid "# Notation"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:62
+msgid ""
+"Rust's grammar is defined over Unicode codepoints, each conventionally "
+"denoted `U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's "
+"grammar is confined to the ASCII range of Unicode, and is described in this "
+"document by a dialect of Extended Backus-Naur Form (EBNF), specifically a "
+"dialect of EBNF supported by common automated LL(k) parsing tools such as "
+"`llgen`, rather than the dialect given in ISO 14977. The dialect can be "
+"defined self-referentially as follows:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:64
+msgid "~~~~~~~~ {.ebnf .notation}"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:72
+#, no-wrap
+msgid ""
+"grammar : rule + ;\n"
+"rule    : nonterminal ':' productionrule ';' ;\n"
+"productionrule : production [ '|' production ] * ;\n"
+"production : term * ;\n"
+"term : element repeats ;\n"
+"element : LITERAL | IDENTIFIER | '[' productionrule ']' ;\n"
+"repeats : [ '*' | '+' ] NUMBER ? | NUMBER ? | '?' ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:74 doc/rust.md:416 doc/rust.md:486
+msgid "~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:76
+msgid "Where:"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:89
+msgid "Whitespace in the grammar is ignored."
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:89
+msgid "Square brackets are used to group rules."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:89
+#, no-wrap
+msgid ""
+"  - `LITERAL` is a single printable ASCII character, or an escaped hexadecimal\n"
+"     ASCII code of the form `\\xQQ`, in single quotes, denoting the corresponding\n"
+"     Unicode codepoint `U+00QQ`.\n"
+"  - `IDENTIFIER` is a nonempty string of ASCII letters and underscores.\n"
+"  - The `repeat` forms apply to the adjacent `element`, and are as follows:\n"
+"    - `?` means zero or one repetition\n"
+"    - `*` means zero or more repetitions\n"
+"    - `+` means one or more repetitions\n"
+"    - NUMBER trailing a repeat symbol gives a maximum repetition count\n"
+"    - NUMBER on its own gives an exact repetition count\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:91
+msgid "This EBNF dialect should hopefully be familiar to many readers."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:93
+msgid "## Unicode productions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:98
+msgid ""
+"A few productions in Rust's grammar permit Unicode codepoints outside the "
+"ASCII range.  We define these productions in terms of character properties "
+"specified in the Unicode standard, rather than in terms of ASCII-range "
+"codepoints.  The section [Special Unicode Productions](#special-unicode-"
+"productions) lists these productions."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:100
+msgid "## String table productions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:109
+msgid ""
+"Some rules in the grammar -- notably [unary operators](#unary-operator-"
+"expressions), [binary operators](#binary-operator-expressions), and "
+"[keywords](#keywords) -- are given in a simplified form: as a listing of a "
+"table of unquoted, printable whitespace-separated strings. These cases form "
+"a subset of the rules regarding the [token](#tokens) rule, and are assumed "
+"to be the result of a lexical-analysis phase feeding the parser, driven by a "
+"DFA, operating over the disjunction of all such string table entries."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:113
+msgid ""
+"When such a string enclosed in double-quotes (`\"`) occurs inside the "
+"grammar, it is an implicit reference to a single member of such a string "
+"table production. See [tokens](#tokens) for more information."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:116
+msgid "# Lexical structure"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:118
+msgid "## Input format"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:124
+msgid ""
+"Rust input is interpreted as a sequence of Unicode codepoints encoded in "
+"UTF-8, normalized to Unicode normalization form NFKC.  Most Rust grammar "
+"rules are defined in terms of printable ASCII-range codepoints, but a small "
+"number are defined in terms of Unicode properties or explicit codepoint "
+"lists.  ^[Substitute definitions for the special Unicode productions are "
+"provided to the grammar verifier, restricted to ASCII range, when verifying "
+"the grammar in this document.]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:126
+msgid "## Special Unicode Productions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:129
+msgid ""
+"The following productions in the Rust grammar are defined in terms of "
+"Unicode properties: `ident`, `non_null`, `non_star`, `non_eol`, "
+"`non_slash_or_star`, `non_single_quote` and `non_double_quote`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:131
+msgid "### Identifiers"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:133
+msgid ""
+"The `ident` production is any nonempty Unicode string of the following form:"
+msgstr ""
+
+#. type: Bullet: '   - '
+#: doc/rust.md:136
+msgid "The first character has property `XID_start`"
+msgstr ""
+
+#. type: Bullet: '   - '
+#: doc/rust.md:136
+msgid "The remaining characters have property `XID_continue`"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:138
+msgid "that does _not_ occur in the set of [keywords](#keywords)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:142
+msgid ""
+"Note: `XID_start` and `XID_continue` as character properties cover the "
+"character ranges used to form the more familiar C and Java language-family "
+"identifiers."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:144
+msgid "### Delimiter-restricted productions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:146
+msgid ""
+"Some productions are defined by exclusion of particular Unicode characters:"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid "`non_null` is any single Unicode character aside from `U+0000` (null)"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid "`non_eol` is `non_null` restricted to exclude `U+000A` (`'\\n'`)"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid "`non_star` is `non_null` restricted to exclude `U+002A` (`*`)"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid ""
+"`non_slash_or_star` is `non_null` restricted to exclude `U+002F` (`/`) and `U"
+"+002A` (`*`)"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid "`non_single_quote` is `non_null` restricted to exclude `U+0027` (`'`)"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:153
+msgid "`non_double_quote` is `non_null` restricted to exclude `U+0022` (`\"`)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:155
+msgid "## Comments"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:162
+msgid ""
+"~~~~~~~~ {.ebnf .gram} comment : block_comment | line_comment ; "
+"block_comment : \"/*\" block_comment_body * '*' + '/' ; block_comment_body : "
+"non_star * | '*' + non_slash_or_star ; line_comment : \"//\" non_eol * ; "
+"~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:165
+msgid ""
+"Comments in Rust code follow the general C++ style of line and block-comment "
+"forms, with no nesting of block-comment delimiters."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:170
+msgid ""
+"Line comments beginning with _three_ slashes (`///`), and block comments "
+"beginning with a repeated asterisk in the block-open sequence (`/**`), are "
+"interpreted as a special syntax for `doc` [attributes](#attributes).  That "
+"is, they are equivalent to writing `#[doc \"...\"]` around the comment's "
+"text."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:172
+msgid "Non-doc comments are interpreted as a form of whitespace."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:174
+msgid "## Whitespace"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:179
+msgid ""
+"~~~~~~~~ {.ebnf .gram} whitespace_char : '\\x20' | '\\x09' | '\\x0a' | "
+"'\\x0d' ; whitespace : [ whitespace_char | comment ] + ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:183
+msgid ""
+"The `whitespace_char` production is any nonempty Unicode string consisting "
+"of any of the following Unicode characters: `U+0020` (space, `' '`), `U"
+"+0009` (tab, `'\\t'`), `U+000A` (LF, `'\\n'`), `U+000D` (CR, `'\\r'`)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:186
+msgid ""
+"Rust is a \"free-form\" language, meaning that all forms of whitespace serve "
+"only to separate _tokens_ in the grammar, and have no semantic significance."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:189
+msgid ""
+"A Rust program has identical meaning if each whitespace element is replaced "
+"with any other legal whitespace element, such as a single space character."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:191
+msgid "## Tokens"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:196
+msgid ""
+"~~~~~~~~ {.ebnf .gram} simple_token : keyword | unop | binop ; token : "
+"simple_token | ident | literal | symbol | whitespace token ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:201
+msgid ""
+"Tokens are primitive productions in the grammar defined by regular (non-"
+"recursive) languages. \"Simple\" tokens are given in [string table "
+"production](#string-table-productions) form, and occur in the rest of the "
+"grammar as double-quoted strings. Other tokens have exact rules given."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:203
+msgid "### Keywords"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:205
+msgid "The keywords are the following strings:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:222
+msgid ""
+"~~~~~~~~ {.keyword} as break 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
+#: doc/rust.md:225
+msgid ""
+"Each of these keywords has special meaning in its grammar, and all of them "
+"are excluded from the `ident` rule."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:227
+msgid "### Literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:233
+msgid ""
+"A literal is an expression consisting of a single token, rather than a "
+"sequence of tokens, that immediately and directly denotes the value it "
+"evaluates to, rather than referring to it by name or some other evaluation "
+"rule. A literal is a form of constant expression, so is evaluated "
+"(primarily)  at compile time."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:237
+msgid ""
+"~~~~~~~~ {.ebnf .gram} literal : string_lit | char_lit | num_lit ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:239
+msgid "#### Character and string literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:243
+msgid ""
+"~~~~~~~~ {.ebnf .gram} char_lit : '\\x27' char_body '\\x27' ; string_lit : "
+"'\"' string_body * '\"' ;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:246
+#, no-wrap
+msgid ""
+"char_body : non_single_quote\n"
+"          | '\\x5c' [ '\\x27' | common_escape ] ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:249
+#, no-wrap
+msgid ""
+"string_body : non_double_quote\n"
+"            | '\\x5c' [ '\\x22' | common_escape ] ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:255
+#, no-wrap
+msgid ""
+"common_escape : '\\x5c'\n"
+"              | 'n' | 'r' | 't'\n"
+"              | 'x' hex_digit 2\n"
+"              | 'u' hex_digit 4\n"
+"              | 'U' hex_digit 8 ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:263
+#, no-wrap
+msgid ""
+"hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'\n"
+"          | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'\n"
+"          | dec_digit ;\n"
+"dec_digit : '0' | nonzero_dec ;\n"
+"nonzero_dec: '1' | '2' | '3' | '4'\n"
+"           | '5' | '6' | '7' | '8' | '9' ;\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:267
+msgid ""
+"A _character literal_ is a single Unicode character enclosed within two `U"
+"+0027` (single-quote) characters, with the exception of `U+0027` itself, "
+"which must be _escaped_ by a preceding U+005C character (`\\`)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:271
+msgid ""
+"A _string literal_ is a sequence of any Unicode characters enclosed within "
+"two `U+0022` (double-quote) characters, with the exception of `U+0022` "
+"itself, which must be _escaped_ by a preceding `U+005C` character (`\\`)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:275
+msgid ""
+"Some additional _escapes_ are available in either character or string "
+"literals. An escape starts with a `U+005C` (`\\`) and continues with one of "
+"the following forms:"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:290
+msgid ""
+"An _8-bit codepoint escape_ escape starts with `U+0078` (`x`) and is "
+"followed by exactly two _hex digits_. It denotes the Unicode codepoint equal "
+"to the provided hex value."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:290
+msgid ""
+"A _16-bit codepoint escape_ starts with `U+0075` (`u`) and is followed by "
+"exactly four _hex digits_. It denotes the Unicode codepoint equal to the "
+"provided hex value."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:290
+msgid ""
+"A _32-bit codepoint escape_ starts with `U+0055` (`U`) and is followed by "
+"exactly eight _hex digits_. It denotes the Unicode codepoint equal to the "
+"provided hex value."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:290
+msgid ""
+"A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072` "
+"(`r`), or `U+0074` (`t`), denoting the unicode values `U+000A` (LF), `U"
+"+000D` (CR) or `U+0009` (HT) respectively."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:290
+msgid ""
+"The _backslash escape_ is the character U+005C (`\\`) which must be escaped "
+"in order to denote *itself*."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:292
+msgid "#### Number literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:294 doc/rust.md:406 doc/rust.md:473
+msgid "~~~~~~~~ {.ebnf .gram}"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:299
+#, no-wrap
+msgid ""
+"num_lit : nonzero_dec [ dec_digit | '_' ] * num_suffix ?\n"
+"        | '0' [       [ dec_digit | '_' ] + num_suffix ?\n"
+"              | 'b'   [ '1' | '0' | '_' ] + int_suffix ?\n"
+"              | 'x'   [ hex_digit | '_' ] + int_suffix ? ] ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:301
+msgid "num_suffix : int_suffix | float_suffix ;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:305
+#, no-wrap
+msgid ""
+"int_suffix : 'u' int_suffix_size ?\n"
+"           | 'i' int_suffix_size ? ;\n"
+"int_suffix_size : [ '8' | '1' '6' | '3' '2' | '6' '4' ] ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:311
+msgid ""
+"float_suffix : [ exponent | '.' dec_lit exponent ? ] ? float_suffix_ty ? ; "
+"float_suffix_ty : 'f' [ '3' '2' | '6' '4' ] ; exponent : ['E' | 'e'] ['-' | "
+"'+' ] ? dec_lit ; dec_lit : [ dec_digit | '_' ] + ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:315
+msgid ""
+"A _number literal_ is either an _integer literal_ or a _floating-point "
+"literal_. The grammar for recognizing the two kinds of literals is mixed, as "
+"they are differentiated by suffixes."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:317
+msgid "##### Integer literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:319
+msgid "An _integer literal_ has one of three forms:"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:326
+msgid ""
+"A _decimal literal_ starts with a *decimal digit* and continues with any "
+"mixture of *decimal digits* and _underscores_."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:326
+msgid ""
+"A _hex literal_ starts with the character sequence `U+0030` `U+0078` (`0x`) "
+"and continues as any mixture hex digits and underscores."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:326
+msgid ""
+"A _binary literal_ starts with the character sequence `U+0030` `U+0062` "
+"(`0b`) and continues as any mixture binary digits and underscores."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:330
+msgid ""
+"An integer literal may be followed (immediately, without any spaces) by an "
+"_integer suffix_, which changes the type of the literal. There are two kinds "
+"of integer literal suffix:"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:336
+msgid ""
+"The `i` and `u` suffixes give the literal type `int` or `uint`, respectively."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:336
+msgid ""
+"Each of the signed and unsigned machine types `u8`, `i8`, `u16`, `i16`, "
+"`u32`, `i32`, `u64` and `i64` give the literal the corresponding machine "
+"type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:343
+msgid ""
+"The type of an _unsuffixed_ integer literal is determined by type "
+"inference.  If a integer type can be _uniquely_ determined from the "
+"surrounding program context, the unsuffixed integer literal has that type.  "
+"If the program context underconstrains the type, the unsuffixed integer "
+"literal's type is `int`; if the program context overconstrains the type, it "
+"is considered a static type error."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:345
+msgid "Examples of integer literals of various forms:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:350
+#, no-wrap
+msgid ""
+"~~~~\n"
+"123; 0xff00;                       // type determined by program context\n"
+"                                   // defaults to int in absence of type\n"
+"                                   // information\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:356
+#, no-wrap
+msgid ""
+"123u;                              // type uint\n"
+"123_u;                             // type uint\n"
+"0xff_u8;                           // type u8\n"
+"0b1111_1111_1001_0000_i32;         // type i32\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:358
+msgid "##### Floating-point literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:360
+msgid "A _floating-point literal_ has one of two forms:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:365
+msgid ""
+"Two _decimal literals_ separated by a period character `U+002E` (`.`), with "
+"an optional _exponent_ trailing after the second decimal literal."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:365
+msgid "A single _decimal literal_ followed by an _exponent_."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:372
+msgid ""
+"By default, a floating-point literal is of type `float`. A floating-point "
+"literal may be followed (immediately, without any spaces) by a _floating-"
+"point suffix_, which changes the type of the literal. There are three "
+"floating-point suffixes: `f` (for the base `float` type), `f32`, and `f64` "
+"(the 32-bit and 64-bit floating point types)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:374
+msgid "Examples of floating-point literals of various forms:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:382
+#, no-wrap
+msgid ""
+"~~~~\n"
+"123.0;                             // type float\n"
+"0.1;                               // type float\n"
+"3f;                                // type float\n"
+"0.1f32;                            // type f32\n"
+"12E+99_f64;                        // type f64\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:384
+msgid "##### Unit and boolean literals"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:387
+msgid ""
+"The _unit value_, the only value of the type that has the same name, is "
+"written as `()`.  The two values of the boolean type are written `true` and "
+"`false`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:389
+msgid "### Symbols"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:395
+#, no-wrap
+msgid ""
+"~~~~~~~~ {.ebnf .gram}\n"
+"symbol : \"::\" \"->\"\n"
+"       | '#' | '[' | ']' | '(' | ')' | '{' | '}'\n"
+"       | ',' | ';' ;\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:401
+msgid ""
+"Symbols are a general class of printable [token](#tokens) that play "
+"structural roles in a variety of grammar productions. They are catalogued "
+"here for completeness as the set of remaining miscellaneous printable tokens "
+"that do not otherwise appear as [unary operators](#unary-operator-"
+"expressions), [binary operators](#binary-operator-expressions), or [keywords]"
+"(#keywords)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:404
+msgid "## Paths"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:410
+#, no-wrap
+msgid ""
+"expr_path : ident [ \"::\" expr_path_tail ] + ;\n"
+"expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'\n"
+"               | expr_path ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:414
+#, no-wrap
+msgid ""
+"type_path : ident [ type_path_tail ] + ;\n"
+"type_path_tail : '<' type_expr [ ',' type_expr ] + '>'\n"
+"               | \"::\" type_path ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:421
+msgid ""
+"A _path_ is a sequence of one or more path components _logically_ separated "
+"by a namespace qualifier (`::`). If a path consists of only one component, "
+"it may refer to either an [item](#items) or a [slot](#memory-slots) in a "
+"local control scope. If a path has multiple components, it refers to an item."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:425
+msgid ""
+"Every item has a _canonical path_ within its crate, but the path naming an "
+"item is only meaningful within a given crate. There is no global namespace "
+"across crates; an item's canonical path merely identifies it within the "
+"crate."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:427
+msgid "Two examples of simple paths consisting of only identifier components:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:432
+msgid "~~~~{.ignore} x; x::y::z; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:439
+msgid ""
+"Path components are usually [identifiers](#identifiers), but the trailing "
+"component of a path may be an angle-bracket-enclosed list of type arguments. "
+"In [expression](#expressions) context, the type argument list is given after "
+"a final (`::`) namespace qualifier in order to disambiguate it from a "
+"relational expression involving the less-than symbol (`<`). In type "
+"expression context, the final namespace qualifier is omitted."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:441
+msgid "Two examples of paths with type arguments:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:450
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# use std::hashmap::HashMap;\n"
+"# fn f() {\n"
+"# fn id<T>(t: T) -> T { t }\n"
+"type t = HashMap<int,~str>;  // Type arguments used in a type expression\n"
+"let x = id::<int>(10);         // Type arguments used in a call expression\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:452
+msgid "# Syntax extensions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:457
+msgid ""
+"A number of minor features of Rust are not central enough to have their own "
+"syntax, and yet are not implementable as functions. Instead, they are given "
+"names, and invoked through a consistent syntax: `name!(...)`. Examples "
+"include:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`fmt!` : format data into a string"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`env!` : look up an environment variable's value at compile time"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`stringify!` : pretty-print the Rust expression given as an argument"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`proto!` : define a protocol for inter-task communication"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`include!` : include the Rust expression in the given file"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`include_str!` : include the contents of the given file as a string"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid ""
+"`include_bin!` : include the contents of the given file as a binary blob"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:466
+msgid "`error!`, `warn!`, `info!`, `debug!` : provide diagnostic information."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:469
+msgid ""
+"All of the above extensions, with the exception of `proto!`, are expressions "
+"with values. `proto!` is an item, defining a new name."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:471
+msgid "## Macros"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:484
+#, no-wrap
+msgid ""
+"expr_macro_rules : \"macro_rules\" '!' ident '(' macro_rule * ')'\n"
+"macro_rule : '(' matcher * ')' \"=>\" '(' transcriber * ')' ';'\n"
+"matcher : '(' matcher * ')' | '[' matcher * ']'\n"
+"        | '{' matcher * '}' | '$' ident ':' ident\n"
+"        | '$' '(' matcher * ')' sep_token? [ '*' | '+' ]\n"
+"        | non_special_token\n"
+"transcriber : '(' transcriber * ')' | '[' transcriber * ']'\n"
+"            | '{' transcriber * '}' | '$' ident\n"
+"            | '$' '(' transcriber * ')' sep_token? [ '*' | '+' ]\n"
+"            | non_special_token\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:490
+msgid ""
+"User-defined syntax extensions are called \"macros\", and the `macro_rules` "
+"syntax extension defines them.  Currently, user-defined macros can expand to "
+"expressions, statements, or items."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:493
+msgid ""
+"(A `sep_token` is any token other than `*` and `+`.  A `non_special_token` "
+"is any token other than a delimiter or `$`.)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:499
+msgid ""
+"The macro expander looks up macro invocations by name, and tries each macro "
+"rule in turn.  It transcribes the first successful match.  Matching and "
+"transcription are closely related to each other, and we will describe them "
+"together."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:501
+msgid "### Macro By Example"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:504
+msgid ""
+"The macro expander matches and transcribes every token that does not begin "
+"with a `$` literally, including delimiters.  For parsing reasons, delimiters "
+"must be balanced, but they are otherwise not special."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:510
+msgid ""
+"In the matcher, `$` _name_ `:` _designator_ matches the nonterminal in the "
+"Rust syntax named by _designator_. Valid designators are `item`, `block`, "
+"`stmt`, `pat`, `expr`, `ty` (type), `ident`, `path`, `matchers` (lhs of the "
+"`=>` in macro rules), `tt` (rhs of the `=>` in macro rules). In the "
+"transcriber, the designator is already known, and so only the name of a "
+"matched nonterminal comes after the dollar sign."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:519
+msgid ""
+"In both the matcher and transcriber, the Kleene star-like operator indicates "
+"repetition.  The Kleene star operator consists of `$` and parens, optionally "
+"followed by a separator token, followed by `*` or `+`.  `*` means zero or "
+"more repetitions, `+` means at least one repetition.  The parens are not "
+"matched or transcribed.  On the matcher side, a name is bound to _all_ of "
+"the names it matches, in a structure that mimics the structure of the "
+"repetition encountered on a successful match. The job of the transcriber is "
+"to sort that structure out."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:525
+msgid ""
+"The rules for transcription of these repetitions are called \"Macro By "
+"Example\".  Essentially, one \"layer\" of repetition is discharged at a "
+"time, and all of them must be discharged by the time a name is transcribed. "
+"Therefore, `( $( $i:ident ),* ) => ( $i )` is an invalid macro, but `( $( $i:"
+"ident ),* ) => ( $( $i:ident ),* )` is acceptable (if trivial)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:533
+msgid ""
+"When Macro By Example encounters a repetition, it examines all of the `$` "
+"_name_ s that occur in its body. At the \"current layer\", they all must "
+"repeat the same number of times, so ` ( $( $i:ident ),* ; $( $j:ident ),* ) "
+"=> ( $( ($i,$j) ),* )` is valid if given the argument `(a,b,c ; d,e,f)`, but "
+"not `(a,b,c ; d,e)`. The repetition walks through the choices at that layer "
+"in lockstep, so the former input transcribes to `( (a,d), (b,e), (c,f) )`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:535
+msgid "Nested repetitions are allowed."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:537
+msgid "### Parsing limitations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:540
+msgid ""
+"The parser used by the macro system is reasonably powerful, but the parsing "
+"of Rust syntax is restricted in two ways:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:546
+#, no-wrap
+msgid ""
+"1. The parser will always parse as much as possible. If it attempts to match\n"
+"`$i:expr [ , ]` against `8 [ , ]`, it will attempt to parse `i` as an array\n"
+"index operation and fail. Adding a separator can solve this problem.\n"
+"2. The parser must have eliminated all ambiguity by the time it reaches a `$` _name_ `:` _designator_.\n"
+"This requirement most often affects name-designator pairs when they occur at the beginning of, or immediately after, a `$(...)*`; requiring a distinctive token in front can solve the problem.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:549
+msgid "## Syntax extensions useful for the macro author"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:554
+msgid "`log_syntax!` : print out the arguments at compile time"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:554
+msgid ""
+"`trace_macros!` : supply `true` or `false` to enable or disable macro "
+"expansion logging"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:554
+msgid "`stringify!` : turn the identifier argument into a string literal"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:554
+msgid ""
+"`concat_idents!` : create a new identifier by concatenating the arguments"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:556
+msgid "# Crates and source files"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:563
+msgid ""
+"Rust is a *compiled* language.  Its semantics obey a *phase distinction* "
+"between compile-time and run-time.  Those semantic rules that have a *static "
+"interpretation* govern the success or failure of compilation.  We refer to "
+"these rules as \"static semantics\".  Semantic rules called \"dynamic "
+"semantics\" govern the behavior of programs at run-time.  A program that "
+"fails to compile due to violation of a compile-time rule has no defined "
+"dynamic semantics; the compiler should halt with an error report, and "
+"produce no executable artifact."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:569
+msgid ""
+"The compilation model centres on artifacts called _crates_.  Each "
+"compilation processes a single crate in source form, and if successful, "
+"produces a single crate in binary form: either an executable or a library."
+"^[A crate is somewhat analogous to an *assembly* in the ECMA-335 CLI model, "
+"a *library* in the SML/NJ Compilation Manager, a *unit* in the Owens and "
+"Flatt module system, or a *configuration* in Mesa.]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:573
+msgid ""
+"A _crate_ is a unit of compilation and linking, as well as versioning, "
+"distribution and runtime loading.  A crate contains a _tree_ of nested "
+"[module](#modules) scopes.  The top level of this tree is a module that is "
+"anonymous (from the point of view of paths within the module) and any item "
+"within a crate has a canonical [module path](#paths) denoting its location "
+"within the crate's module tree."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:577
+msgid ""
+"The Rust compiler is always invoked with a single source file as input, and "
+"always produces a single output crate.  The processing of that source file "
+"may result in other source files being loaded as modules.  Source files have "
+"the extension `.rs`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:582
+msgid ""
+"A Rust source file describes a module, the name and location of which -- in "
+"the module tree of the current crate -- are defined from outside the source "
+"file: either by an explicit `mod_item` in a referencing source file, or by "
+"the name of the crate itself."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:587
+msgid ""
+"Each source file contains a sequence of zero or more `item` definitions, and "
+"may optionally begin with any number of `attributes` that apply to the "
+"containing module.  Atributes on the anonymous crate module define important "
+"metadata that influences the behavior of the compiler."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:593
+#, no-wrap
+msgid ""
+"~~~~~~~~\n"
+"// Linkage attributes\n"
+"#[ link(name = \"projx\",\n"
+"        vers = \"2.5\",\n"
+"        uuid = \"9cccc5d5-aceb-4af5-8285-811211826b82\") ];\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:598
+msgid ""
+"// Additional metadata attributes #[ desc = \"Project X\" ]; #[ license = "
+"\"BSD\" ]; #[ author = \"Jane Doe\" ];"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:601
+msgid "// Specify the output type #[ crate_type = \"lib\" ];"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:605
+msgid "// Turn on a warning #[ warn(non_camel_case_types) ]; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:608
+msgid ""
+"A crate that contains a `main` function can be compiled to an executable.  "
+"If a `main` function is present, its return type must be [`unit`](#primitive-"
+"types) and it must take no arguments."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:611
+msgid "# Items and attributes"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:614
+msgid ""
+"Crates contain [items](#items), each of which may have some number of "
+"[attributes](#attributes) attached to it."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:616
+msgid "## Items"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:621
+#, no-wrap
+msgid ""
+"~~~~~~~~ {.ebnf .gram}\n"
+"item : mod_item | fn_item | type_item | struct_item | enum_item\n"
+"     | static_item | trait_item | impl_item | extern_block ;\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:627
+msgid ""
+"An _item_ is a component of a crate; some module items can be defined in "
+"crate files, but most are defined in source files. Items are organized "
+"within a crate by a nested set of [modules](#modules). Every crate has a "
+"single \"outermost\" anonymous module; all further items within the crate "
+"have [paths](#paths) within the module tree of the crate."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:630
+msgid ""
+"Items are entirely determined at compile-time, generally remain fixed during "
+"execution, and may reside in read-only memory."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:632
+msgid "There are several kinds of item:"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[modules](#modules)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[functions](#functions)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[type definitions](#type-definitions)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[structures](#structures)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[enumerations](#enumerations)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[static items](#static-items)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[traits](#traits)"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:641
+msgid "[implementations](#implementations)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:651
+msgid ""
+"Some items form an implicit scope for the declaration of sub-items. In other "
+"words, within a function or module, declarations of items can (in many "
+"cases)  be mixed with the statements, control blocks, and similar artifacts "
+"that otherwise compose the item body. The meaning of these scoped items is "
+"the same as if the item was declared outside the scope -- it is still a "
+"static item -- except that the item's *path name* within the module "
+"namespace is qualified by the name of the enclosing item, or is private to "
+"the enclosing item (in the case of functions).  The grammar specifies the "
+"exact locations in which sub-item declarations may appear."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:653
+msgid "### Type Parameters"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:662
+msgid ""
+"All items except modules may be *parameterized* by type. Type parameters are "
+"given as a comma-separated list of identifiers enclosed in angle brackets "
+"(`<...>`), after the name of the item and before its definition.  The type "
+"parameters of an item are considered \"part of the name\", not part of the "
+"type of the item.  A referencing [path](#paths) must (in principle) provide "
+"type arguments as a list of comma-separated types enclosed within angle "
+"brackets, in order to refer to the type-parameterized item.  In practice, "
+"the type-inference system can usually infer such argument types from "
+"context.  There are no general type-parametric types, only type-parametric "
+"items.  That is, Rust has no notion of type abstraction: there are no first-"
+"class \"forall\" types."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:664
+msgid "### Modules"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:669
+msgid ""
+"~~~~~~~~ {.ebnf .gram} mod_item : \"mod\" ident ( ';' | '{' mod '}' ); mod : "
+"[ view_item | item ] * ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:674
+msgid ""
+"A module is a container for zero or more [view items](#view-items) and zero "
+"or more [items](#items). The view items manage the visibility of the items "
+"defined within the module, as well as the visibility of names from outside "
+"the module when referenced from inside the module."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:678
+msgid ""
+"A _module item_ is a module, surrounded in braces, named, and prefixed with "
+"the keyword `mod`. A module item introduces a new, named module into the "
+"tree of modules making up a crate. Modules can nest arbitrarily."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:680
+msgid "An example of a module:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:698
+#, no-wrap
+msgid ""
+"~~~~~~~~\n"
+"mod math {\n"
+"    type complex = (f64, f64);\n"
+"    fn sin(f: f64) -> f64 {\n"
+"        ...\n"
+"# fail!();\n"
+"    }\n"
+"    fn cos(f: f64) -> f64 {\n"
+"        ...\n"
+"# fail!();\n"
+"    }\n"
+"    fn tan(f: f64) -> f64 {\n"
+"        ...\n"
+"# fail!();\n"
+"    }\n"
+"}\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:703
+msgid ""
+"Modules and types share the same namespace.  Declaring a named type that has "
+"the same name as a module in scope is forbidden: that is, a type definition, "
+"trait, struct, enumeration, or type parameter can't shadow the name of a "
+"module in scope, or vice versa."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:708
+msgid ""
+"A module without a body is loaded from an external file, by default with the "
+"same name as the module, plus the `.rs` extension.  When a nested submodule "
+"is loaded from an external file, it is loaded from a subdirectory path that "
+"mirrors the module hierarchy."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:712
+msgid "~~~ {.xfail-test} // Load the `vec` module from `vec.rs` mod vec;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:718
+#, no-wrap
+msgid ""
+"mod task {\n"
+"    // Load the `local_data` module from `task/local_data.rs`\n"
+"    mod local_data;\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:721
+msgid ""
+"The directories and files used for loading external file modules can be "
+"influenced with the `path` attribute."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:730
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"#[path = \"task_files\"]\n"
+"mod task {\n"
+"    // Load the `local_data` module from `task_files/tls.rs`\n"
+"    #[path = \"tls.rs\"]\n"
+"    mod local_data;\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:732
+msgid "#### View items"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:736
+msgid ""
+"~~~~~~~~ {.ebnf .gram} view_item : extern_mod_decl | use_decl ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:740
+msgid ""
+"A view item manages the namespace of a module.  View items do not define new "
+"items, but rather, simply change other items' visibility.  There are several "
+"kinds of view item:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: doc/rust.md:743
+msgid "[`extern mod` declarations](#extern-mod-declarations)"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: doc/rust.md:743
+msgid "[`use` declarations](#use-declarations)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:745
+msgid "##### Extern mod declarations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:751
+msgid ""
+"~~~~~~~~ {.ebnf .gram} extern_mod_decl : \"extern\" \"mod\" ident [ '(' "
+"link_attrs ')' ] ? [ '=' string_lit ] ? ; link_attrs : link_attr [ ',' "
+"link_attrs ] + ; link_attr : ident '=' literal ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:755
+msgid ""
+"An _`extern mod` declaration_ specifies a dependency on an external crate.  "
+"The external crate is then bound into the declaring scope as the `ident` "
+"provided in the `extern_mod_decl`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:765
+msgid ""
+"The external crate is resolved to a specific `soname` at compile time, and a "
+"runtime linkage requirement to that `soname` is passed to the linker for "
+"loading at runtime.  The `soname` is resolved at compile time by scanning "
+"the compiler's library path and matching the `link_attrs` provided in the "
+"`use_decl` against any `#link` attributes that were declared on the external "
+"crate when it was compiled.  If no `link_attrs` are provided, a default "
+"`name` attribute is assumed, equal to the `ident` given in the `use_decl`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:775
+msgid ""
+"Optionally, an identifier in an `extern mod` declaration may be followed by "
+"an equals sign, then a string literal denoting a relative path on the "
+"filesystem.  This path should exist in one of the directories in the Rust "
+"path, which by default contains the `.rust` subdirectory of the current "
+"directory and each of its parents, as well as any directories in the colon-"
+"separated (or semicolon-separated on Windows)  list of paths that is the "
+"`RUST_PATH` environment variable.  The meaning of `extern mod a = \"b/c/d\";"
+"`, supposing that `/a` is in the RUST_PATH, is that the name `a` should be "
+"taken as a reference to the crate whose absolute location is `/a/b/c/d`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:777
+msgid "Four examples of `extern mod` declarations:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:780
+msgid ""
+"~~~~~~~~{.xfail-test} extern mod pcre (uuid = \"54aba0f8-"
+"a7b1-4beb-92f1-4cf625264841\");"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:782
+msgid ""
+"extern mod extra; // equivalent to: extern mod extra ( name = \"extra\" );"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:784
+msgid ""
+"extern mod rustextra (name = \"extra\"); // linking to 'extra' under another "
+"name"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:787
+msgid "extern mod complicated_mod = \"some-file/in/the-rust/path\"; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:789
+msgid "##### Use declarations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:793
+#, no-wrap
+msgid ""
+"~~~~~~~~ {.ebnf .gram}\n"
+"use_decl : \"pub\"? \"use\" ident [ '=' path\n"
+"                          | \"::\" path_glob ] ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:798
+#, no-wrap
+msgid ""
+"path_glob : ident [ \"::\" path_glob ] ?\n"
+"          | '*'\n"
+"          | '{' ident [ ',' ident ] * '}'\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:802
+msgid ""
+"A _use declaration_ creates one or more local name bindings synonymous with "
+"some other [path](#paths).  Usually a `use` declaration is used to shorten "
+"the path required to refer to a module item."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:806
+#, no-wrap
+msgid ""
+"*Note*: Unlike in many languages,\n"
+"`use` declarations in Rust do *not* declare linkage dependency with external crates.\n"
+"Rather, [`extern mod` declarations](#extern-mod-declarations) declare linkage dependencies.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:808
+msgid "Use declarations support a number of convenient shortcuts:"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:813
+msgid ""
+"Rebinding the target name as a new local name, using the syntax `use x = p::"
+"q::r;`."
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:813
+msgid ""
+"Simultaneously binding a list of paths differing only in their final "
+"element, using the glob-like brace syntax `use a::b::{c,d,e,f};`"
+msgstr ""
+
+#. type: Bullet: '  * '
+#: doc/rust.md:813
+msgid ""
+"Binding all paths matching a given prefix, using the asterisk wildcard "
+"syntax `use a::b::*;`"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:815
+msgid "An example of `use` declarations:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:819
+msgid "~~~~ use std::num::sin; use std::option::{Some, None};"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:823
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    // Equivalent to 'info!(std::num::sin(1.0));'\n"
+"    info!(sin(1.0));\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:828
+#, no-wrap
+msgid ""
+"    // Equivalent to 'info!(~[std::option::Some(1.0), std::option::None]);'\n"
+"    info!(~[Some(1.0), None]);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:836
+msgid ""
+"Like items, `use` declarations are private to the containing module, by "
+"default.  Also like items, a `use` declaration can be public, if qualified "
+"by the `pub` keyword.  Such a `use` declaration serves to _re-export_ a "
+"name.  A public `use` declaration can therefore _redirect_ some public name "
+"to a different target definition: even a definition with a private canonical "
+"path, inside a different module.  If a sequence of such redirections form a "
+"cycle or cannot be resolved unambiguously, they represent a compile-time "
+"error."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:842
+#, no-wrap
+msgid ""
+"An example of re-exporting:\n"
+"~~~~\n"
+"# fn main() { }\n"
+"mod quux {\n"
+"    pub use quux::foo::*;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:849
+#, no-wrap
+msgid ""
+"    pub mod foo {\n"
+"        pub fn bar() { }\n"
+"        pub fn baz() { }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:851
+msgid ""
+"In this example, the module `quux` re-exports all of the public names "
+"defined in `foo`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:854
+msgid ""
+"Also note that the paths contained in `use` items are relative to the crate "
+"root.  So, in the previous example, the `use` refers to `quux::foo::*`, and "
+"not simply to `foo::*`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:856
+msgid "### Functions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:860
+msgid ""
+"A _function item_ defines a sequence of [statements](#statements) and an "
+"optional final [expression](#expressions), along with a name and a set of "
+"parameters.  Functions are declared with the keyword `fn`.  Functions "
+"declare a set of *input* [*slots*](#memory-slots) as parameters, through "
+"which the caller passes arguments into the function, and an *output* [*slot*]"
+"(#memory-slots) through which the function passes results back to the caller."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:865
+msgid ""
+"A function may also be copied into a first class *value*, in which case the "
+"value has the corresponding [*function type*](#function-types), and can be "
+"used otherwise exactly as a function item (with a minor additional cost of "
+"calling the function indirectly)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:871
+msgid ""
+"Every control path in a function logically ends with a `return` expression "
+"or a diverging expression. If the outermost block of a function has a value-"
+"producing expression in its final-expression position, that expression is "
+"interpreted as an implicit `return` expression applied to the final-"
+"expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:873
+msgid "An example of a function:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:879
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn add(x: int, y: int) -> int {\n"
+"    return x + y;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:882
+msgid ""
+"As with `let` bindings, function arguments are irrefutable patterns, so any "
+"pattern that is valid in a let binding is also valid as an argument."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:886
+msgid "~~~ fn first((value, _): (int, int)) -> int { value } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:889
+msgid "#### Generic functions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:894
+msgid ""
+"A _generic function_ allows one or more _parameterized types_ to appear in "
+"its signature. Each type parameter must be explicitly declared, in an angle-"
+"bracket-enclosed, comma-separated list following the function name."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:905
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"fn iter<T>(seq: &[T], f: &fn(T)) {\n"
+"    for elt in seq.iter() { f(elt); }\n"
+"}\n"
+"fn map<T, U>(seq: &[T], f: &fn(T) -> U) -> ~[U] {\n"
+"    let mut acc = ~[];\n"
+"    for elt in seq.iter() { acc.push(f(elt)); }\n"
+"    acc\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:908
+msgid ""
+"Inside the function signature and body, the name of the type parameter can "
+"be used as a type name."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:914
+msgid ""
+"When a generic function is referenced, its type is instantiated based on the "
+"context of the reference. For example, calling the `iter` function defined "
+"above on `[1, 2]` will instantiate type parameter `T` with `int`, and "
+"require the closure parameter to have type `fn(int)`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:919
+msgid ""
+"The type parameters can also be explicitly supplied in a trailing [path]"
+"(#paths) component after the function name. This might be necessary if there "
+"is not sufficient context to determine the type parameters. For example, "
+"`sys::size_of::<u32>() == 4`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:923
+msgid ""
+"Since a parameter type is opaque to the generic function, the set of "
+"operations that can be performed on it is limited. Values of parameter type "
+"can only be moved, not copied."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:927
+msgid "~~~~ fn id<T>(x: T) -> T { x } ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:931
+msgid ""
+"Similarly, [trait](#traits) bounds can be specified for type parameters to "
+"allow methods with that trait to be called on values of that type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:934
+msgid "#### Unsafe functions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:937
+msgid ""
+"Unsafe functions are those containing unsafe operations that are not "
+"contained in an [`unsafe` block](#unsafe-blocks).  Such a function must be "
+"prefixed with the keyword `unsafe`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:940
+msgid ""
+"Unsafe operations are those that potentially violate the memory-safety "
+"guarantees of Rust's static semantics.  Specifically, the following "
+"operations are considered unsafe:"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:944
+msgid "Dereferencing a [raw pointer](#pointer-types)."
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:944
+msgid "Casting a [raw pointer](#pointer-types) to a safe pointer type."
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:944
+msgid "Calling an unsafe function."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:946
+msgid "##### Unsafe blocks"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:950
+msgid ""
+"A block of code can also be prefixed with the `unsafe` keyword, to permit a "
+"sequence of unsafe operations in an otherwise-safe function.  This facility "
+"exists because the static semantics of Rust are a necessary approximation of "
+"the dynamic semantics.  When a programmer has sufficient conviction that a "
+"sequence of unsafe operations is actually safe, they can encapsulate that "
+"sequence (taken as a whole) within an `unsafe` block. The compiler will "
+"consider uses of such code \"safe\", to the surrounding context."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:953
+msgid "#### Diverging functions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:956
+msgid ""
+"A special kind of function can be declared with a `!` character where the "
+"output slot type would normally be. For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:963
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn my_err(s: &str) -> ! {\n"
+"    info!(s);\n"
+"    fail!();\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:970
+msgid ""
+"We call such functions \"diverging\" because they never return a value to "
+"the caller. Every control path in a diverging function must end with a `fail!"
+"()` or a call to another diverging function on every control path. The `!` "
+"annotation does *not* denote a type. Rather, the result type of a diverging "
+"function is a special type called $\\bot$ (\"bottom\") that unifies with any "
+"type. Rust has no syntax for $\\bot$."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:976
+msgid ""
+"It might be necessary to declare a diverging function because as mentioned "
+"previously, the typechecker checks that every control path in a function "
+"ends with a [`return`](#return-expressions) or diverging expression. So, if "
+"`my_err` were declared without the `!` annotation, the following code would "
+"not typecheck:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:979
+msgid "~~~~ # fn my_err(s: &str) -> ! { fail!() }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:989
+#, no-wrap
+msgid ""
+"fn f(i: int) -> int {\n"
+"   if i == 42 {\n"
+"     return 42;\n"
+"   }\n"
+"   else {\n"
+"     my_err(\"Bad number!\");\n"
+"   }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:997
+msgid ""
+"This will not compile without the `!` annotation on `my_err`, since the "
+"`else` branch of the conditional in `f` does not return an `int`, as "
+"required by the signature of `f`.  Adding the `!` annotation to `my_err` "
+"informs the typechecker that, should control ever enter `my_err`, no further "
+"type judgments about `f` need to hold, since control will never resume in "
+"any context that relies on those judgments.  Thus the return type on `f` "
+"only needs to reflect the `if` branch of the conditional."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1000
+msgid "#### Extern functions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1007
+msgid ""
+"Extern functions are part of Rust's foreign function interface, providing "
+"the opposite functionality to [external blocks](#external-blocks).  Whereas "
+"external blocks allow Rust code to call foreign code, extern functions with "
+"bodies defined in Rust code _can be called by foreign code_. They are "
+"defined in the same way as any other Rust function, except that they have "
+"the `extern` modifier."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1011
+msgid "~~~ extern fn new_vec() -> ~[int] { ~[] } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1014
+msgid ""
+"Extern functions may not be called from Rust code, but Rust code may take "
+"their value as a raw `u8` pointer."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1019
+msgid ""
+"~~~ # extern fn new_vec() -> ~[int] { ~[] } let fptr: *u8 = new_vec; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1023
+msgid ""
+"The primary motivation for extern functions is to create callbacks for "
+"foreign functions that expect to receive function pointers."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1025
+msgid "### Type definitions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1029
+msgid ""
+"A _type definition_ defines a new name for an existing [type](#types). Type "
+"definitions are declared with the keyword `type`. Every value has a single, "
+"specific type; the type-specified aspects of a value include:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1035
+msgid "Whether the value is composed of sub-values or is indivisible."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1035
+msgid "Whether the value represents textual or numerical information."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1035
+msgid "Whether the value represents integral or floating-point information."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1035
+msgid "The sequence of memory operations required to access the value."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1035
+msgid "The [kind](#type-kinds) of the type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1038
+msgid ""
+"For example, the type `(u8, u8)` defines the set of immutable values that "
+"are composite pairs, each containing two unsigned 8-bit integers accessed by "
+"pattern-matching and laid out in memory with the `x` component preceding the "
+"`y` component."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1040
+msgid "### Structures"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1042
+msgid ""
+"A _structure_ is a nominal [structure type](#structure-types) defined with "
+"the keyword `struct`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1044
+msgid "An example of a `struct` item and its use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1050
+msgid ""
+"~~~~ struct Point {x: int, y: int} let p = Point {x: 10, y: 11}; let px: int "
+"= p.x; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1053
+msgid ""
+"A _tuple structure_ is a nominal [tuple type](#tuple-types), also defined "
+"with the keyword `struct`.  For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1059
+msgid ""
+"~~~~ struct Point(int, int); let p = Point(10, 11); let px: int = match p "
+"{ Point(x, _) => x }; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1063
+msgid ""
+"A _unit-like struct_ is a structure without any fields, defined by leaving "
+"off the list of fields entirely.  Such types will have a single value, just "
+"like the [unit value `()`](#unit-and-boolean-literals) of the unit type.  "
+"For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1068
+msgid "~~~~ struct Cookie; let c = [Cookie, Cookie, Cookie, Cookie]; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1070
+msgid "### Enumerations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1073
+msgid ""
+"An _enumeration_ is a simultaneous definition of a nominal [enumerated type]"
+"(#enumerated-types) as well as a set of *constructors*, that can be used to "
+"create or pattern-match values of the corresponding enumerated type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1075
+msgid "Enumerations are declared with the keyword `enum`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1077
+msgid "An example of an `enum` item and its use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1083
+#, no-wrap
+msgid ""
+"~~~~\n"
+"enum Animal {\n"
+"  Dog,\n"
+"  Cat\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1087
+msgid "let mut a: Animal = Dog; a = Cat; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1094
+#, no-wrap
+msgid ""
+"Enumeration constructors can have either named or unnamed fields:\n"
+"~~~~\n"
+"enum Animal {\n"
+"    Dog (~str, float),\n"
+"    Cat { name: ~str, weight: float }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1098
+msgid ""
+"let mut a: Animal = Dog(~\"Cocoa\", 37.2); a = Cat{ name: ~\"Spotty\", "
+"weight: 2.7 }; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1101
+msgid ""
+"In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is "
+"simply called an enum variant."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1103
+msgid "### Static items"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1107
+msgid ""
+"~~~~~~~~ {.ebnf .gram} static_item : \"static\" ident ':' type '=' expr "
+"';' ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1114
+msgid ""
+"A *static item* is a named _constant value_ stored in the global data "
+"section of a crate.  Immutable static items are stored in the read-only data "
+"section.  The constant value bound to a static item is, like all constant "
+"values, evaluated at compile time.  Static items have the `static` lifetime, "
+"which outlives all other lifetimes in a Rust program.  Static items are "
+"declared with the `static` keyword.  A static item must have a _constant "
+"expression_ giving its definition."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1119
+msgid ""
+"Static items must be explicitly typed.  The type may be ```bool```, "
+"```char```, a number, or a type derived from those primitive types.  The "
+"derived types are borrowed pointers with the `'static` lifetime, fixed-size "
+"arrays, tuples, and structs."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1123
+msgid "~~~~ static BIT1: uint = 1 << 0; static BIT2: uint = 1 << 1;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1126
+msgid ""
+"static BITS: [uint, ..2] = [BIT1, BIT2]; static STRING: &'static str = "
+"\"bitstring\";"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1131
+#, no-wrap
+msgid ""
+"struct BitsNStrings<'self> {\n"
+"    mybits: [uint, ..2],\n"
+"    mystring: &'self str\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1137
+#, no-wrap
+msgid ""
+"static bits_n_strings: BitsNStrings<'static> = BitsNStrings {\n"
+"    mybits: BITS,\n"
+"    mystring: STRING\n"
+"};\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1139
+msgid "#### Mutable statics"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1147
+msgid ""
+"If a static item is declared with the ```mut``` keyword, then it is allowed "
+"to be modified by the program. One of Rust's goals is to make concurrency "
+"bugs hard to run into, and this is obviously a very large source of race "
+"conditions or other bugs. For this reason, an ```unsafe``` block is required "
+"when either reading or writing a mutable static variable. Care should be "
+"taken to ensure that modifications to a mutable static are safe with respect "
+"to other tasks running in the same process."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1150
+msgid ""
+"Mutable statics are still very useful, however. They can be used with C "
+"libraries and can also be bound from C libraries (in an ```extern``` block)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1153
+msgid "~~~ # fn atomic_add(_: &mut uint, _: uint) -> uint { 2 }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1155
+msgid "static mut LEVELS: uint = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1163
+#, no-wrap
+msgid ""
+"// This violates the idea of no shared state, and this doesn't internally\n"
+"// protect against races, so this function is `unsafe`\n"
+"unsafe fn bump_levels_unsafe1() -> uint {\n"
+"    let ret = LEVELS;\n"
+"    LEVELS += 1;\n"
+"    return ret;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1170
+#, no-wrap
+msgid ""
+"// Assuming that we have an atomic_add function which returns the old value,\n"
+"// this function is \"safe\" but the meaning of the return value may not be what\n"
+"// callers expect, so it's still marked as `unsafe`\n"
+"unsafe fn bump_levels_unsafe2() -> uint {\n"
+"    return atomic_add(&mut LEVELS, 1);\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1172
+msgid "~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1174
+msgid "### Traits"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1176
+msgid "A _trait_ describes a set of method types."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1181
+msgid ""
+"Traits can include default implementations of methods, written in terms of "
+"some unknown [`self` type](#self-types); the `self` type may either be "
+"completely unspecified, or constrained by some other trait."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1183
+msgid ""
+"Traits are implemented for specific types through separate [implementations]"
+"(#implementations)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1187
+msgid "~~~~ # type Surface = int; # type BoundingBox = int;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1193
+#, no-wrap
+msgid ""
+"trait Shape {\n"
+"    fn draw(&self, Surface);\n"
+"    fn bounding_box(&self) -> BoundingBox;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1197
+msgid ""
+"This defines a trait with two methods.  All values that have "
+"[implementations](#implementations) of this trait in scope can have their "
+"`draw` and `bounding_box` methods called, using `value.bounding_box()` "
+"[syntax](#method-call-expressions)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1200
+msgid ""
+"Type parameters can be specified for a trait to make it generic.  These "
+"appear after the trait name, using the same syntax used in [generic "
+"functions](#generic-functions)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1208
+#, no-wrap
+msgid ""
+"~~~~\n"
+"trait Seq<T> {\n"
+"   fn len(&self) -> uint;\n"
+"   fn elt_at(&self, n: uint) -> T;\n"
+"   fn iter(&self, &fn(T));\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1214
+msgid ""
+"Generic functions may use traits as _bounds_ on their type parameters.  This "
+"will have two effects: only types that have the trait may instantiate the "
+"parameter, and within the generic function, the methods of the trait can be "
+"called on values that have the parameter's type.  For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1218
+msgid "~~~~ # type Surface = int; # trait Shape { fn draw(&self, Surface); }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1224
+#, no-wrap
+msgid ""
+"fn draw_twice<T: Shape>(surface: Surface, sh: T) {\n"
+"    sh.draw(surface);\n"
+"    sh.draw(surface);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1229
+msgid ""
+"Traits also define an [object type](#object-types) with the same name as the "
+"trait.  Values of this type are created by [casting](#type-cast-expressions) "
+"pointer values (pointing to a type for which an implementation of the given "
+"trait is in scope)  to pointers to the trait name, used as a type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1234
+msgid "~~~~ # trait Shape { } # impl Shape for int { } # let mycircle = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1237
+msgid "let myshape: @Shape = @mycircle as @Shape; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1243
+msgid ""
+"The resulting value is a managed box containing the value that was cast, "
+"along with information that identifies the methods of the implementation "
+"that was used.  Values with a trait type can have [methods called](#method-"
+"call-expressions) on them, for any method in the trait, and can be used to "
+"instantiate type parameters that are bounded by the trait."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1251
+msgid ""
+"Trait methods may be static, which means that they lack a `self` argument.  "
+"This means that they can only be called with function call syntax (`f(x)`)  "
+"and not method call syntax (`obj.f()`).  The way to refer to the name of a "
+"static method is to qualify it with the trait name, treating the trait name "
+"like a module.  For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1261
+#, no-wrap
+msgid ""
+"~~~~\n"
+"trait Num {\n"
+"    fn from_int(n: int) -> Self;\n"
+"}\n"
+"impl Num for float {\n"
+"    fn from_int(n: int) -> float { n as float }\n"
+"}\n"
+"let x: float = Num::from_int(42);\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1263
+msgid "Traits may inherit from other traits. For example, in"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1268
+msgid ""
+"~~~~ trait Shape { fn area() -> float; } trait Circle : Shape { fn radius() -"
+"> float; } ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1273
+msgid ""
+"the syntax `Circle : Shape` means that types that implement `Circle` must "
+"also have an implementation for `Shape`.  Multiple supertraits are separated "
+"by spaces, `trait Circle : Shape Eq { }`.  In an implementation of `Circle` "
+"for a given type `T`, methods can refer to `Shape` methods, since the "
+"typechecker checks that any type with an implementation of `Circle` also has "
+"an implementation of `Shape`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1277 doc/tutorial.md:2176
+msgid ""
+"In type-parameterized functions, methods of the supertrait may be called on "
+"values of subtrait-bound type parameters.  Refering to the previous example "
+"of `trait Circle : Shape`:"
+msgstr ""
+"型パラメータを持つ関数では、サブトレイトの境界型パラメータの値によりスーパー"
+"トレイトのメソッドを呼び出すことになります。前の例の `trait Circle : Shape` "
+"を参照してください。"
+
+#. type: Plain text
+#: doc/rust.md:1286 doc/tutorial.md:2185
+#, no-wrap
+msgid ""
+"~~~\n"
+"# trait Shape { fn area(&self) -> float; }\n"
+"# trait Circle : Shape { fn radius(&self) -> float; }\n"
+"fn radius_times_area<T: Circle>(c: T) -> float {\n"
+"    // `c` is both a Circle and a Shape\n"
+"    c.radius() * c.area()\n"
+"}\n"
+"~~~\n"
+msgstr ""
+"~~~\n"
+"# trait Shape { fn area(&self) -> float; }\n"
+"# trait Circle : Shape { fn radius(&self) -> float; }\n"
+"fn radius_times_area<T: Circle>(c: T) -> float {\n"
+"    // `c` は Circle でもあり、Shape でもある\n"
+"    c.radius() * c.area()\n"
+"}\n"
+"~~~\n"
+
+#. type: Plain text
+#: doc/rust.md:1288 doc/tutorial.md:2187
+msgid "Likewise, supertrait methods may also be called on trait objects."
+msgstr ""
+"同様に、スーパートレイトのメソッドは、トレイトオブジェクトについても呼び出す"
+"ことが可能です。"
+
+#. type: Plain text
+#: doc/rust.md:1295
+msgid ""
+"~~~ {.xfail-test} # trait Shape { fn area(&self) -> float; } # trait "
+"Circle : Shape { fn radius(&self) -> float; } # impl Shape for int { fn "
+"area(&self) -> float { 0.0 } } # impl Circle for int { fn radius(&self) -> "
+"float { 0.0 } } # let mycircle = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1299
+msgid ""
+"let mycircle: Circle = @mycircle as @Circle; let nonsense = mycircle."
+"radius() * mycircle.area(); ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1301
+msgid "### Implementations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1303
+msgid ""
+"An _implementation_ is an item that implements a [trait](#traits) for a "
+"specific type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1305
+msgid "Implementations are defined with the keyword `impl`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1312
+msgid ""
+"~~~~ # struct Point {x: float, y: float}; # type Surface = int; # struct "
+"BoundingBox {x: float, y: float, width: float, height: float}; # trait Shape "
+"{ fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; } # fn "
+"do_draw_circle(s: Surface, c: Circle) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1317
+#, no-wrap
+msgid ""
+"struct Circle {\n"
+"    radius: float,\n"
+"    center: Point,\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1327
+#, no-wrap
+msgid ""
+"impl Shape for Circle {\n"
+"    fn draw(&self, s: Surface) { do_draw_circle(s, *self); }\n"
+"    fn bounding_box(&self) -> BoundingBox {\n"
+"        let r = self.radius;\n"
+"        BoundingBox{x: self.center.x - r, y: self.center.y - r,\n"
+"         width: 2.0 * r, height: 2.0 * r}\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1334
+msgid ""
+"It is possible to define an implementation without referring to a trait.  "
+"The methods in such an implementation can only be used as direct calls on "
+"the values of the type that the implementation targets.  In such an "
+"implementation, the trait type and `for` after `impl` are omitted.  Such "
+"implementations are limited to nominal types (enums, structs), and the "
+"implementation must appear in the same module or a sub-module as the `self` "
+"type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1338
+msgid ""
+"When a trait _is_ specified in an `impl`, all methods declared as part of "
+"the trait must be implemented, with matching types and type parameter counts."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1342
+msgid ""
+"An implementation can take type parameters, which can be different from the "
+"type parameters taken by the trait it implements.  Implementation parameters "
+"are written after the `impl` keyword."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1345
+msgid "~~~~ # trait Seq<T> { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1353
+#, no-wrap
+msgid ""
+"impl<T> Seq<T> for ~[T] {\n"
+"   ...\n"
+"}\n"
+"impl Seq<bool> for u32 {\n"
+"   /* Treat the integer as a sequence of bits */\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1355
+msgid "### External blocks"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1360
+msgid ""
+"~~~ {.ebnf .gram} extern_block_item : \"extern\" '{' extern_block '} ; "
+"extern_block : [ foreign_fn ] * ; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1364
+msgid ""
+"External blocks form the basis for Rust's foreign function interface.  "
+"Declarations in an external block describe symbols in external, non-Rust "
+"libraries."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1369
+msgid ""
+"Functions within external blocks are declared in the same way as other Rust "
+"functions, with the exception that they may not have a body and are instead "
+"terminated by a semicolon."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1373
+msgid "~~~ # use std::libc::{c_char, FILE}; # #[nolink]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1378
+#, no-wrap
+msgid ""
+"extern {\n"
+"    fn fopen(filename: *c_char, mode: *c_char) -> *FILE;\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1383
+msgid ""
+"Functions within external blocks may be called by Rust code, just like "
+"functions defined in Rust.  The Rust compiler automatically translates "
+"between the Rust ABI and the foreign ABI."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1386
+msgid ""
+"A number of [attributes](#attributes) control the behavior of external "
+"blocks."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1390
+msgid ""
+"By default external blocks assume that the library they are calling uses the "
+"standard C \"cdecl\" ABI.  Other ABIs may be specified using the `abi` "
+"attribute as in"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1396
+msgid ""
+"~~~{.xfail-test} // Interface to the Windows API #[abi = \"stdcall\"] extern "
+"{ } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1398
+msgid ""
+"The `link_name` attribute allows the name of the library to be specified."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1403
+msgid "~~~{.xfail-test} #[link_name = \"crypto\"] extern { } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1409
+msgid ""
+"The `nolink` attribute tells the Rust compiler not to do any linking for the "
+"external block.  This is particularly useful for creating external blocks "
+"for libc, which tends to not follow standard library naming conventions and "
+"is linked to all Rust programs anyway."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1411
+msgid "## Attributes"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1418
+#, no-wrap
+msgid ""
+"~~~~~~~~{.ebnf .gram}\n"
+"attribute : '#' '[' attr_list ']' ;\n"
+"attr_list : attr [ ',' attr_list ]*\n"
+"attr : ident [ '=' literal\n"
+"             | '(' attr_list ')' ] ? ;\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1424
+msgid ""
+"Static entities in Rust -- crates, modules and items -- may have "
+"_attributes_ applied to them. ^[Attributes in Rust are modeled on Attributes "
+"in ECMA-335, C#] An attribute is a general, free-form metadatum that is "
+"interpreted according to name, convention, and language and compiler "
+"version.  Attributes may appear as any of"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1428
+msgid "A single identifier, the attribute name"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1428
+msgid ""
+"An identifier followed by the equals sign '=' and a literal, providing a key/"
+"value pair"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1428
+msgid ""
+"An identifier followed by a parenthesized list of sub-attribute arguments"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1431
+msgid ""
+"Attributes terminated by a semi-colon apply to the entity that the attribute "
+"is declared within. Attributes that are not terminated by a semi-colon apply "
+"to the next entity."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1433
+msgid "An example of attributes:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1437
+msgid ""
+"~~~~~~~~{.xfail-test} // General metadata applied to the enclosing module or "
+"crate.  #[license = \"BSD\"];"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1443
+#, no-wrap
+msgid ""
+"// A function marked as a unit test\n"
+"#[test]\n"
+"fn test_foo() {\n"
+"  ...\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1449
+#, no-wrap
+msgid ""
+"// A conditionally-compiled module\n"
+"#[cfg(target_os=\"linux\")]\n"
+"mod bar {\n"
+"  ...\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1454
+msgid ""
+"// A lint attribute used to suppress a warning/error "
+"#[allow(non_camel_case_types)] pub type int8_t = i8; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1457
+msgid ""
+"> **Note:** In future versions of Rust, user-provided extensions to the "
+"compiler will be able to interpret attributes.  > When this facility is "
+"provided, the compiler will distinguish between language-reserved and user-"
+"available attributes."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1460
+msgid ""
+"At present, only the Rust compiler interprets attributes, so all attribute "
+"names are effectively reserved. Some significant attributes include:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid "The `doc` attribute, for documenting code in-place."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid ""
+"The `cfg` attribute, for conditional-compilation by build-configuration."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid ""
+"The `lang` attribute, for custom definitions of traits and functions that "
+"are known to the Rust compiler (see [Language items](#language-items))."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid "The `link` attribute, for describing linkage metadata for a crate."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid "The `test` attribute, for marking functions as unit tests."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid ""
+"The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint "
+"checks (see [Lint check attributes](#lint-check-attributes))."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid ""
+"The `deriving` attribute, for automatically generating implementations of "
+"certain traits."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1471
+msgid ""
+"The `static_assert` attribute, for asserting that a static bool is true at "
+"compiletime"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1473
+msgid ""
+"Other attributes may be added or removed during development of the language."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1475
+msgid "### Lint check attributes"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1479
+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:1481
+msgid "For any lint check `C`:"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: doc/rust.md:1488
+msgid "`warn(C)` warns about violations of `C` but continues compilation,"
+msgstr ""
+
+#. type: Bullet: ' * '
+#: doc/rust.md:1488
+msgid "`deny(C)` signals an error after encountering a violation of `C`,"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1488
+#, 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:1491
+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:1497
+#, 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:1501
+#, 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:1507
+#, 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:1510
+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:1518
+#, no-wrap
+msgid ""
+"~~~{.xfail-test}\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:1524
+#, 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:1529
+#, 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:1532
+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:1542
+#, 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:1544
+msgid "### Language items"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1550
+msgid ""
+"Some primitive Rust operations are defined in Rust code, rather than being "
+"implemented directly in C or assembly language.  The definitions of these "
+"operations have to be easy for the compiler to find.  The `lang` attribute "
+"makes it possible to declare these operations.  For example, the `str` "
+"module in the Rust standard library defines the string equality function:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1557
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"#[lang=\"str_eq\"]\n"
+"pub fn eq_slice(a: &str, b: &str) -> bool {\n"
+"    // details elided\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1561
+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 "
+"generating calls to the string equality function."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1563
+msgid "A complete list of the built-in language items follows:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1565
+msgid "#### Traits"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1604
+#, no-wrap
+msgid ""
+"`const`\n"
+"  : Cannot be mutated.\n"
+"`owned`\n"
+"  : Are uniquely owned.\n"
+"`durable`\n"
+"  : Contain borrowed pointers.\n"
+"`drop`\n"
+"  : Have finalizers.\n"
+"`add`\n"
+"  : Elements can be added (for example, integers and floats).\n"
+"`sub`\n"
+"  : Elements can be subtracted.\n"
+"`mul`\n"
+"  : Elements can be multiplied.\n"
+"`div`\n"
+"  : Elements have a division operation.\n"
+"`rem`\n"
+"  : Elements have a remainder operation.\n"
+"`neg`\n"
+"  : Elements can be negated arithmetically.\n"
+"`not`\n"
+"  : Elements can be negated logically.\n"
+"`bitxor`\n"
+"  : Elements have an exclusive-or operation.\n"
+"`bitand`\n"
+"  : Elements have a bitwise `and` operation.\n"
+"`bitor`\n"
+"  : Elements have a bitwise `or` operation.\n"
+"`shl`\n"
+"  : Elements have a left shift operation.\n"
+"`shr`\n"
+"  : Elements have a right shift operation.\n"
+"`index`\n"
+"  : Elements can be indexed.\n"
+"`eq`\n"
+"  : Elements can be compared for equality.\n"
+"`ord`\n"
+"  : Elements have a partial ordering.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1606
+msgid "#### Operations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1636
+#, no-wrap
+msgid ""
+"`str_eq`\n"
+"  : Compare two strings for equality.\n"
+"`uniq_str_eq`\n"
+"  : Compare two owned strings for equality.\n"
+"`annihilate`\n"
+"  : Destroy a box before freeing it.\n"
+"`log_type`\n"
+"  : Generically print a string representation of any type.\n"
+"`fail_`\n"
+"  : Abort the program with an error.\n"
+"`fail_bounds_check`\n"
+"  : Abort the program with a bounds check error.\n"
+"`exchange_malloc`\n"
+"  : Allocate memory on the exchange heap.\n"
+"`exchange_free`\n"
+"  : Free memory that was allocated on the exchange heap.\n"
+"`malloc`\n"
+"  : Allocate memory on the managed heap.\n"
+"`free`\n"
+"  : Free memory that was allocated on the managed heap.\n"
+"`borrow_as_imm`\n"
+"  : Create an immutable borrowed pointer to a mutable value.\n"
+"`return_to_mut`\n"
+"  : Release a borrowed pointer created with `return_to_mut`\n"
+"`check_not_borrowed`\n"
+"  : Fail if a value has existing borrowed pointers to it.\n"
+"`strdup_uniq`\n"
+"  : Return a new unique string\n"
+"    containing a copy of the contents of a unique string.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1639
+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:1641
+msgid "### Deriving"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1647
+msgid ""
+"The `deriving` attribute allows certain traits to be automatically "
+"implemented for data structures. For example, the following will create an "
+"`impl` for the `Eq` and `Clone` traits for `Foo`, the type parameter `T` "
+"will be given the `Eq` or `Clone` constraints for the appropriate `impl`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1655
+#, no-wrap
+msgid ""
+"~~~\n"
+"#[deriving(Eq, Clone)]\n"
+"struct Foo<T> {\n"
+"    a: int,\n"
+"    b: T\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1657
+msgid "The generated `impl` for `Eq` is equivalent to"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1664
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Foo<T> { a: int, b: T }\n"
+"impl<T: Eq> Eq for Foo<T> {\n"
+"    fn eq(&self, other: &Foo<T>) -> bool {\n"
+"        self.a == other.a && self.b == other.b\n"
+"    }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1670
+#, no-wrap
+msgid ""
+"    fn ne(&self, other: &Foo<T>) -> bool {\n"
+"        self.a != other.a || self.b != other.b\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1672
+msgid "Supported traits for `deriving` are:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "Serialization: `Encodable`, `Decodable`. These require `extra`."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "`Clone` and `DeepClone`, to perform (deep) copies."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "`IterBytes`, to iterate over the bytes in a data type."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "`Rand`, to create a random instance of a data type."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+msgid "`Zero`, to create an zero (or empty) instance of a data type."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:1683
+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 "
+"each constituent field of the type must also implement `ToStr` and will have "
+"`field.to_str()` invoked to build up the result."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1685
+msgid "# Statements and expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1692
+msgid ""
+"Rust is _primarily_ an expression language. This means that most forms of "
+"value-producing or effect-causing evaluation are directed by the uniform "
+"syntax category of _expressions_. Each kind of expression can typically "
+"_nest_ within each other kind of expression, and rules for evaluation of "
+"expressions involve specifying both the value produced by the expression and "
+"the order in which its sub-expressions are themselves evaluated."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1695
+msgid ""
+"In contrast, statements in Rust serve _mostly_ to contain and explicitly "
+"sequence expression evaluation."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1697
+msgid "## Statements"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1700
+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:1704
+msgid ""
+"Rust has two kinds of statement: [declaration statements](#declaration-"
+"statements) and [expression statements](#expression-statements)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1706
+msgid "### Declaration statements"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1709
+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 "
+"new items."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1711
+msgid "#### Item declarations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1718
+msgid ""
+"An _item declaration statement_ has a syntactic form identical to an [item]"
+"(#items) declaration within a module. Declaring an item -- a function, "
+"enumeration, structure, type, static, trait, implementation or module -- "
+"locally within a statement block is simply a way of restricting its scope to "
+"a narrow region containing all of its uses; it is otherwise identical in "
+"meaning to declaring the item outside the statement block."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1721
+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:1724
+msgid "#### Slot declarations"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1729
+msgid ""
+"~~~~~~~~{.ebnf .gram} let_decl : \"let\" pat [':' type ] ? [ init ] ? ';' ; "
+"init : [ '=' ] expr ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1735
+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 "
+"expression.  When no type annotation is given, the compiler will infer the "
+"type, or signal an error if insufficient type information is available for "
+"definite inference.  Any slots introduced by a slot declaration are visible "
+"from the point of declaration until the end of the enclosing block scope."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1737
+msgid "### Expression statements"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1742
+msgid ""
+"An _expression statement_ is one that evaluates an [expression]"
+"(#expressions)  and ignores its result.  The type of an expression statement "
+"`e;` is always `()`, regardless of the type of `e`.  As a rule, an "
+"expression statement's purpose is to trigger the effects of evaluating its "
+"expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1744
+msgid "## Expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1753
+#, no-wrap
+msgid ""
+"An expression may have two roles: it always produces a *value*, and it may have *effects*\n"
+"(otherwise known as \"side effects\").\n"
+"An expression *evaluates to* a value, and has effects during *evaluation*.\n"
+"Many expressions contain sub-expressions (operands).\n"
+"The meaning of each kind of expression dictates several things:\n"
+"  * Whether or not to evaluate the sub-expressions when evaluating the expression\n"
+"  * The order in which to evaluate the sub-expressions\n"
+"  * How to combine the sub-expressions' values to obtain the value of the expression.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1758
+msgid ""
+"In this way, the structure of expressions dictates the structure of "
+"execution.  Blocks are just another kind of expression, so blocks, "
+"statements, expressions, and blocks again can recursively nest inside each "
+"other to an arbitrary depth."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1760
+msgid "#### Lvalues, rvalues and temporaries"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1764
+msgid ""
+"Expressions are divided into two main categories: _lvalues_ and _rvalues_.  "
+"Likewise within each expression, sub-expressions may occur in _lvalue "
+"context_ or _rvalue context_.  The evaluation of an expression depends both "
+"on its own category and the context it occurs within."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1767
+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:1775
+msgid ""
+"The left operand of an [assignment](#assignment-expressions), [binary move]"
+"(#binary-move-expressions) or [compound-assignment](#compound-assignment-"
+"expressions) expression is an lvalue context, as is the single operand of a "
+"unary [borrow](#unary-operator-expressions), or [move](#unary-move-"
+"expressions) expression, and _both_ operands of a [swap](#swap-expressions) "
+"expression.  All other expression contexts are rvalue contexts."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1778
+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 "
+"_in_ that memory location."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1781
+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 "
+"lifetime of any borrowed pointer that points to it."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1783
+msgid "#### Moved and copied types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1792
+msgid ""
+"When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-"
+"rvalues-and-temporaries)  the variable will either be [moved](#move-"
+"expressions) or copied, depending on its type.  For types that contain "
+"[owning pointers](#owning-pointers)  or values that implement the special "
+"trait `Drop`, the variable is moved.  All other types are copied."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1795
+msgid "### Literal expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1799
+msgid ""
+"A _literal expression_ consists of one of the [literal](#literals)  forms "
+"described earlier. It directly describes a number, character, string, "
+"boolean value, or the unit value."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1806
+#, no-wrap
+msgid ""
+"~~~~~~~~ {.literals}\n"
+"();        // unit type\n"
+"\"hello\";   // string type\n"
+"'5';       // character type\n"
+"5;         // integer type\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1808
+msgid "### Path expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1811
+msgid ""
+"A [path](#paths) used as an expression context denotes either a local "
+"variable or an item.  Path expressions are [lvalues](#lvalues-rvalues-and-"
+"temporaries)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1813
+msgid "### Tuple expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1817
+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:1823
+msgid "~~~~~~~~ {.tuple} (0,); (0f, 4.5f); (\"a\", 4u, true); ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1825
+msgid "### Structure expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1834
+#, no-wrap
+msgid ""
+"~~~~~~~~{.ebnf .gram}\n"
+"struct_expr : expr_path '{' ident ':' expr\n"
+"                      [ ',' ident ':' expr ] *\n"
+"                      [ \"..\" expr ] '}' |\n"
+"              expr_path '(' expr\n"
+"                      [ ',' expr ] * ')' |\n"
+"              expr_path\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1841
+msgid ""
+"There are several forms of structure expressions.  A _structure expression_ "
+"consists of the [path](#paths) of a [structure item](#structures), followed "
+"by a brace-enclosed list of one or more comma-separated name-value pairs, "
+"providing the field values of a new instance of the structure.  A field name "
+"can be any identifier, and is separated from its value expression by a "
+"colon.  The location denoted by a structure field is mutable if and only if "
+"the enclosing structure is mutable."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1846
+msgid ""
+"A _tuple structure expression_ consists of the [path](#paths) of a "
+"[structure item](#structures), followed by a parenthesized list of one or "
+"more comma-separated expressions (in other words, the path of a structure "
+"item followed by a tuple expression).  The structure item must be a tuple "
+"structure item."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1848
+msgid ""
+"A _unit-like structure expression_ consists only of the [path](#paths) of a "
+"[structure item](#structures)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1850
+msgid "The following are examples of structure expressions:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1861
+msgid ""
+"~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, "
+"float); # mod game { pub struct User<'self> { name: &'self str, age: uint, "
+"score: uint } } # struct Cookie; fn some_fn<T>(t: T) {} Point {x: 10f, y: "
+"20f}; TuplePoint(10f, 20f); let u = game::User {name: \"Joe\", age: 35, "
+"score: 100_000}; some_fn::<Cookie>(Cookie); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1864
+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 "
+"value."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1871
+msgid ""
+"A structure expression can terminate with the syntax `..` followed by an "
+"expression to denote a functional update.  The expression following `..` "
+"(the base) must have the same structure type as the new structure type being "
+"formed.  The entire expression denotes the result of allocating a new "
+"structure (with the same type as the base expression)  with the given values "
+"for the fields that were explicitly specified and the values in the base "
+"record for all other fields."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1877
+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:1879
+msgid "### Record expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1885
+#, no-wrap
+msgid ""
+"~~~~~~~~{.ebnf .gram}\n"
+"rec_expr : '{' ident ':' expr\n"
+"               [ ',' ident ':' expr ] *\n"
+"               [ \"..\" expr ] '}'\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1887
+msgid "### Method-call expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1891
+msgid ""
+"~~~~~~~~{.ebnf .gram} method_call_expr : expr '.' ident paren_expr_list ; "
+"~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1896
+msgid ""
+"A _method call_ consists of an expression followed by a single dot, an "
+"identifier, and a parenthesized expression-list.  Method calls are resolved "
+"to methods on specific traits, either statically dispatching to a method if "
+"the exact `self`-type of the left-hand-side is known, or dynamically "
+"dispatching if the left-hand-side expression is an indirect [object type]"
+"(#object-types)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1899
+msgid "### Field expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1903
+msgid "~~~~~~~~{.ebnf .gram} field_expr : expr '.' ident ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1907
+msgid ""
+"A _field expression_ consists of an expression followed by a single dot and "
+"an identifier, when not immediately followed by a parenthesized expression-"
+"list (the latter is a [method call expression](#method-call-expressions)).  "
+"A field expression denotes a field of a [structure](#structure-types)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1912
+msgid "~~~~~~~~ {.field} myrecord.myfield; {a: 10, b: 20}.a; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1915
+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 "
+"[assigned](#assignment-expressions) to."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1918
+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 "
+"access possible."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1921
+msgid "### Vector expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1924
+msgid "~~~~~~~~{.ebnf .gram} vec_expr : '[' \"mut\"? vec_elems? ']'"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1927
+msgid "vec_elems : [expr [',' expr]*] | [expr ',' \"..\" expr] ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1930
+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:1934
+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 "
+"[literal](#literals) or a [static item](#static-items)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1941
+#, no-wrap
+msgid ""
+"~~~~\n"
+"[1, 2, 3, 4];\n"
+"[\"a\", \"b\", \"c\", \"d\"];\n"
+"[0, ..128];             // vector with 128 zeros\n"
+"[0u8, 0u8, 0u8, 0u8];\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1943
+msgid "### Index expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1947
+msgid "~~~~~~~~{.ebnf .gram} idx_expr : expr '[' expr ']' ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1952
+msgid ""
+"[Vector](#vector-types)-typed expressions can be indexed by writing a square-"
+"bracket-enclosed expression (the index) after them. When the vector is "
+"mutable, the resulting [lvalue](#lvalues-rvalues-and-temporaries) can be "
+"assigned to."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1956
+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 "
+"_failing state_."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1960
+msgid "~~~~ # use std::task; # do task::spawn_unlinked {"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1963
+msgid "([1, 2, 3, 4])[0]; ([\"a\", \"b\"])[10]; // fails"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1966 doc/tutorial-tasks.md:648
+msgid "# } ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1968
+msgid "### Unary operator expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1972
+msgid ""
+"Rust defines six symbolic unary operators.  They are all written as prefix "
+"operators, before the expression they apply to."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1991
+#, no-wrap
+msgid ""
+"`-`\n"
+"  : Negation. May only be applied to numeric types.\n"
+"`*`\n"
+"  : Dereference. When applied to a [pointer](#pointer-types) it denotes the pointed-to location.\n"
+"    For pointers to mutable locations, the resulting [lvalue](#lvalues-rvalues-and-temporaries) can be assigned to.\n"
+"    For [enums](#enumerated-types) that have only a single variant, containing a single parameter,\n"
+"    the dereference operator accesses this parameter.\n"
+"`!`\n"
+"  : Logical negation. On the boolean type, this flips between `true` and\n"
+"    `false`. On integer types, this inverts the individual bits in the\n"
+"    two's complement representation of the value.\n"
+"`@` and `~`\n"
+"  :  [Boxing](#pointer-types) operators. Allocate a box to hold the value they are applied to,\n"
+"     and store the value in it. `@` creates a managed box, whereas `~` creates an owned box.\n"
+"`&`\n"
+"  : Borrow operator. Returns a borrowed pointer, pointing to its operand.\n"
+"    The operand of a borrowed pointer is statically proven to outlive the resulting pointer.\n"
+"    If the borrow-checker cannot prove this, it is a compilation error.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1993
+msgid "### Binary operator expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1997
+msgid "~~~~~~~~{.ebnf .gram} binop_expr : expr binop expr ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2000
+msgid ""
+"Binary operators expressions are given in terms of [operator precedence]"
+"(#operator-precedence)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2002
+msgid "#### Arithmetic operators"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2007
+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 "
+"that arithmetic operators can be overridden for user-defined types.  The "
+"default meaning of the operators on standard types is given here."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2023
+#, no-wrap
+msgid ""
+"`+`\n"
+"  : Addition and vector/string concatenation.\n"
+"    Calls the `add` method on the `std::ops::Add` trait.\n"
+"`-`\n"
+"  : Subtraction.\n"
+"    Calls the `sub` method on the `std::ops::Sub` trait.\n"
+"`*`\n"
+"  : Multiplication.\n"
+"    Calls the `mul` method on the `std::ops::Mul` trait.\n"
+"`/`\n"
+"  : Quotient.\n"
+"    Calls the `div` method on the `std::ops::Div` trait.\n"
+"`%`\n"
+"  : Remainder.\n"
+"    Calls the `rem` method on the `std::ops::Rem` trait.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2025
+msgid "#### Bitwise operators"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2030
+msgid ""
+"Like the [arithmetic operators](#arithmetic-operators), bitwise operators "
+"are syntactic sugar for calls to methods of built-in traits.  This means "
+"that bitwise operators can be overridden for user-defined types.  The "
+"default meaning of the operators on standard types is given here."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2046
+#, no-wrap
+msgid ""
+"`&`\n"
+"  : And.\n"
+"    Calls the `bitand` method of the `std::ops::BitAnd` trait.\n"
+"`|`\n"
+"  : Inclusive or.\n"
+"    Calls the `bitor` method of the `std::ops::BitOr` trait.\n"
+"`^`\n"
+"  : Exclusive or.\n"
+"    Calls the `bitxor` method of the `std::ops::BitXor` trait.\n"
+"`<<`\n"
+"  : Logical left shift.\n"
+"    Calls the `shl` method of the `std::ops::Shl` trait.\n"
+"`>>`\n"
+"  : Logical right shift.\n"
+"    Calls the `shr` method of the `std::ops::Shr` trait.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2048
+msgid "#### Lazy boolean operators"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2055
+msgid ""
+"The operators `||` and `&&` may be applied to operands of boolean type.  The "
+"`||` operator denotes logical 'or', and the `&&` operator denotes logical "
+"'and'.  They differ from `|` and `&` in that the right-hand operand is only "
+"evaluated when the left-hand operand does not already determine the result "
+"of the expression.  That is, `||` only evaluates its right-hand operand when "
+"the left-hand operand evaluates to `false`, and `&&` only when it evaluates "
+"to `true`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2057
+msgid "#### Comparison operators"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2063
+msgid ""
+"Comparison operators are, like the [arithmetic operators](#arithmetic-"
+"operators), and [bitwise operators](#bitwise-operators), syntactic sugar for "
+"calls to built-in traits.  This means that comparison operators can be "
+"overridden for user-defined types.  The default meaning of the operators on "
+"standard types is given here."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2082
+#, no-wrap
+msgid ""
+"`==`\n"
+"  : Equal to.\n"
+"    Calls the `eq` method on the `std::cmp::Eq` trait.\n"
+"`!=`\n"
+"  : Unequal to.\n"
+"    Calls the `ne` method on the `std::cmp::Eq` trait.\n"
+"`<`\n"
+"  : Less than.\n"
+"    Calls the `lt` method on the `std::cmp::Ord` trait.\n"
+"`>`\n"
+"  : Greater than.\n"
+"    Calls the `gt` method on the `std::cmp::Ord` trait.\n"
+"`<=`\n"
+"  : Less than or equal.\n"
+"    Calls the `le` method on the `std::cmp::Ord` trait.\n"
+"`>=`\n"
+"  : Greater than or equal.\n"
+"    Calls the `ge` method on the `std::cmp::Ord` trait.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2085
+msgid "#### Type cast expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2087
+msgid "A type cast expression is denoted with the binary operator `as`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2090
+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:2094
+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 "
+"unsupported and will fail to compile."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2096
+msgid "An example of an `as` expression:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2100
+msgid ""
+"~~~~ # fn sum(v: &[float]) -> float { 0.0 } # fn len(v: &[float]) -> int "
+"{ 0 }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2107
+#, no-wrap
+msgid ""
+"fn avg(v: &[float]) -> float {\n"
+"  let sum: float = sum(v);\n"
+"  let sz: float = len(v) as float;\n"
+"  return sum / sz;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2109
+msgid "#### Assignment expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2112
+msgid ""
+"An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-"
+"temporaries) expression followed by an equals sign (`=`) and an [rvalue]"
+"(#lvalues-rvalues-and-temporaries) expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2114
+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:2118
+msgid "~~~~ # let mut x = 0; # let y = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2121
+msgid "x = y; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2123
+msgid "#### Compound assignment expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2128
+msgid ""
+"The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be "
+"composed with the `=` operator. The expression `lval OP= val` is equivalent "
+"to `lval = lval OP val`. For example, `x = x + 1` may be written as `x += 1`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2130
+msgid "Any such expression always has the [`unit`](#primitive-types) type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2132
+msgid "#### Operator precedence"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2135
+msgid ""
+"The precedence of Rust binary operators is ordered as follows, going from "
+"strong to weak:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2148
+#, no-wrap
+msgid ""
+"~~~~ {.precedence}\n"
+"* / %\n"
+"as\n"
+"+ -\n"
+"<< >>\n"
+"&\n"
+"^\n"
+"|\n"
+"< > <= >=\n"
+"== !=\n"
+"&&\n"
+"||\n"
+"=\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2150 doc/rust.md:2237 doc/tutorial-macros.md:323
+msgid "~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2153
+msgid ""
+"Operators at the same precedence level are evaluated left-to-right. [Unary "
+"operators](#unary-operator-expressions)  have the same precedence level and "
+"it is stronger than any of the binary operators'."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2155
+msgid "### Grouped expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2159
+msgid ""
+"An expression enclosed in parentheses evaluates to the result of the "
+"enclosed expression.  Parentheses can be used to explicitly specify "
+"evaluation order within an expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2163
+msgid "~~~~~~~~{.ebnf .gram} paren_expr : '(' expr ')' ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2165
+msgid "An example of a parenthesized expression:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2169
+msgid "~~~~ let x = (2 + 3) * 4; ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2172
+msgid "### Call expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2178
+msgid ""
+"~~~~~~~~ {.abnf .gram} expr_list : [ expr [ ',' expr ]* ] ? ; "
+"paren_expr_list : '(' expr_list ')' ; call_expr : expr paren_expr_list ; "
+"~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2183
+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 "
+"the `lval` on the right hand side of the call. If the function eventually "
+"returns, then the expression completes."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2185
+msgid "Some examples of call expressions:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2189
+msgid ""
+"~~~~ # use std::from_str::FromStr; # fn add(x: int, y: int) -> int { 0 }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2193
+msgid ""
+"let x: int = add(1, 2); let pi = FromStr::from_str::<f32>(\"3.14\"); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2195
+msgid "### Lambda expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2200
+msgid ""
+"~~~~~~~~ {.abnf .gram} ident_list : [ ident [ ',' ident ]* ] ? ; "
+"lambda_expr : '|' ident_list '|' expr ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2204
+msgid ""
+"A _lambda expression_ (sometimes called an \"anonymous function expression"
+"\") defines a function and denotes it as a value, in a single expression.  A "
+"lambda expression is a pipe-symbol-delimited (`|`) list of identifiers "
+"followed by an expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2209
+msgid ""
+"A lambda expression denotes a function that maps a list of parameters "
+"(`ident_list`)  onto the expression that follows the `ident_list`.  The "
+"identifiers in the `ident_list` are the parameters to the function.  These "
+"parameters' types need not be specified, as the compiler infers them from "
+"context."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2212
+msgid ""
+"Lambda expressions are most useful when passing functions as arguments to "
+"other functions, as an abbreviation for defining and capturing a separate "
+"function."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2221
+msgid ""
+"Significantly, lambda expressions _capture their environment_, which regular "
+"[function definitions](#functions) do not.  The exact type of capture "
+"depends on the [function type](#function-types) inferred for the lambda "
+"expression.  In the simplest and least-expensive form (analogous to a "
+"```&fn() { }``` expression), the lambda expression captures its environment "
+"by reference, effectively borrowing pointers to all outer variables "
+"mentioned inside the function.  Alternately, the compiler may infer that a "
+"lambda expression should copy or move values (depending on their type.)  "
+"from the environment into the lambda expression's captured environment."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2224
+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:2233
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn ten_times(f: &fn(int)) {\n"
+"    let mut i = 0;\n"
+"    while i < 10 {\n"
+"        f(i);\n"
+"        i += 1;\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2235
+msgid "ten_times(|j| println(fmt!(\"hello, %d\", j)));"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2239
+msgid "### While loops"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2243
+msgid ""
+"~~~~~~~~{.ebnf .gram} while_expr : \"while\" expr '{' block '}' ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2248
+msgid ""
+"A `while` loop begins by evaluating the boolean loop conditional "
+"expression.  If the loop conditional expression evaluates to `true`, the "
+"loop body block executes and control returns to the loop conditional "
+"expression. If the loop conditional expression evaluates to `false`, the "
+"`while` expression completes."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2250
+msgid "An example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2253
+msgid "~~~~ let mut i = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2259
+#, no-wrap
+msgid ""
+"while i < 10 {\n"
+"    println(\"hello\\n\");\n"
+"    i = i + 1;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2261
+msgid "### Infinite loops"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2265
+msgid ""
+"The keyword `loop` in Rust appears both in _loop expressions_ and in "
+"_continue expressions_.  A loop expression denotes an infinite loop; see "
+"[Continue expressions](#continue-expressions) for continue expressions."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2269
+msgid ""
+"~~~~~~~~{.ebnf .gram} loop_expr : [ lifetime ':' ] \"loop\" '{' block '}'; "
+"~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2274
+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 "
+"out of this loop or return control to its head.  See [Break expressions]"
+"(#break-expressions)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2276
+msgid "### Break expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2280
+msgid "~~~~~~~~{.ebnf .gram} break_expr : \"break\" [ lifetime ]; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2287
+msgid ""
+"A `break` expression has an optional `label`.  If the label is absent, then "
+"executing a `break` expression immediately terminates the innermost loop "
+"enclosing it.  It is only permitted in the body of a loop.  If the label is "
+"present, then `break foo` terminates the loop with label `foo`, which need "
+"not be the innermost label enclosing the `break` expression, but must "
+"enclose it."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2289
+msgid "### Continue expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2293
+msgid "~~~~~~~~{.ebnf .gram} continue_expr : \"loop\" [ lifetime ]; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2304
+msgid ""
+"A continue expression, written `loop`, also has an optional `label`.  If the "
+"label is absent, then executing a `loop` expression immediately terminates "
+"the current iteration of the innermost loop enclosing it, returning control "
+"to the loop *head*.  In the case of a `while` loop, the head is the "
+"conditional expression controlling the loop.  In the case of a `for` loop, "
+"the head is the call-expression controlling the loop.  If the label is "
+"present, then `loop foo` returns control to the head of the loop with label "
+"`foo`, which need not be the innermost label enclosing the `break` "
+"expression, but must enclose it."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2306
+msgid "A `loop` expression is only permitted in the body of a loop."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2309
+msgid "### Do expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2313
+msgid ""
+"~~~~~~~~{.ebnf .gram} do_expr : \"do\" expr [ '|' ident_list '|' ] ? '{' "
+"block '}' ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2316
+msgid ""
+"A _do expression_ provides a more-familiar block-syntax for a [lambda "
+"expression](#lambda-expressions), including a special translation of [return "
+"expressions](#return-expressions) inside the supplied block."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2324
+msgid ""
+"Any occurrence of a [return expression](#return-expressions)  inside this "
+"`block` expression is rewritten as a reference to an (anonymous) flag set in "
+"the caller's environment, which is checked on return from the `expr` and, if "
+"set, causes a corresponding return from the caller.  In this way, the "
+"meaning of `return` statements in language built-in control blocks is "
+"preserved, if they are rewritten using lambda functions and `do` expressions "
+"as abstractions."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2327
+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 "
+"missing, an empty `ident_list` is implied."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2333
+msgid ""
+"The lambda expression is then provided as a _trailing argument_ to the "
+"outermost [call](#call-expressions) or [method call](#method-call-"
+"expressions) expression in the `expr` following `do`.  If the `expr` is a "
+"[path expression](#path-expressions), it is parsed as though it is a call "
+"expression.  If the `expr` is a [field expression](#field-expressions), it "
+"is parsed as though it is a method call expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2335
+msgid "In this example, both calls to `f` are equivalent:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2339
+msgid "~~~~ # fn f(f: &fn(int)) { } # fn g(i: int) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2341
+msgid "f(|j| g(j));"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2346
+#, no-wrap
+msgid ""
+"do f |j| {\n"
+"    g(j);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2348
+msgid ""
+"In this example, both calls to the (binary) function `k` are equivalent:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2352
+msgid "~~~~ # fn k(x:int, f: &fn(int)) { } # fn l(i: int) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2354
+msgid "k(3, |j| l(j));"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2359
+#, no-wrap
+msgid ""
+"do k(3) |j| {\n"
+"   l(j);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2362
+msgid "### For expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2366
+msgid ""
+"~~~~~~~~{.ebnf .gram} for_expr : \"for\" expr [ '|' ident_list '|' ] ? '{' "
+"block '}' ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2370
+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 "
+"passing the `block` function to a higher-order function implementing a loop."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2376
+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 "
+"return a boolean. The `for` expression accommodates this by implicitly "
+"returning `true` at the end of each block, unless a `break` expression is "
+"evaluated."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2383
+msgid ""
+"In addition, [`break`](#break-expressions) and [`loop`](#loop-expressions) "
+"expressions are rewritten inside `for` expressions in the same way that "
+"`return` expressions are, with a combination of local flag variables, and "
+"early boolean-valued returns from the `block` function, such that the "
+"meaning of `break` and `loop` is preserved in a primitive loop when "
+"rewritten as a `for` loop controlled by a higher order function."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2385
+msgid "An example of a for loop over the contents of a vector:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2392
+msgid ""
+"~~~~ # type foo = int; # fn bar(f: foo) { } # let a = 0; # let b = 0; # let "
+"c = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2394
+msgid "let v: &[foo] = &[a, b, c];"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2399
+#, no-wrap
+msgid ""
+"for e in v.iter() {\n"
+"    bar(*e);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2401
+msgid "An example of a for loop over a series of integers:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2408
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# fn bar(b:uint) { }\n"
+"for i in range(0u, 256) {\n"
+"    bar(i);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2410
+msgid "### If expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2414
+#, no-wrap
+msgid ""
+"~~~~~~~~{.ebnf .gram}\n"
+"if_expr : \"if\" expr '{' block '}'\n"
+"          else_tail ? ;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2418
+#, no-wrap
+msgid ""
+"else_tail : \"else\" [ if_expr\n"
+"                   | '{' block '}' ] ;\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2429
+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 "
+"block, any number of `else if` conditions and blocks, and an optional "
+"trailing `else` block. The condition expressions must have type `bool`. If a "
+"condition expression evaluates to `true`, the consequent block is executed "
+"and any subsequent `else if` or `else` block is skipped. If a condition "
+"expression evaluates to `false`, the consequent block is skipped and any "
+"subsequent `else if` condition is evaluated. If all `if` and `else if` "
+"conditions evaluate to `false` then any `else` block is executed."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2432
+msgid "### Match expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2435
+msgid ""
+"~~~~~~~~{.ebnf .gram} match_expr : \"match\" expr '{' match_arm [ '|' "
+"match_arm ] * '}' ;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2437
+msgid "match_arm : match_pat '=>' [ expr \",\" | '{' block '}' ] ;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2440
+msgid "match_pat : pat [ \"..\" pat ] ? [ \"if\" expr ] ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2448
+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 "
+"literals, destructured enum constructors, structures, records and tuples, "
+"variable binding specifications, wildcards (`*`), and placeholders (`_`). A "
+"`match` expression has a *head expression*, which is the value to compare to "
+"the patterns. The type of the patterns must equal the type of the head "
+"expression."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2452
+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* "
+"the fields of a particular variant. For example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2455
+msgid "~~~~ enum List<X> { Nil, Cons(X, @List<X>) }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2457 doc/rust.md:2486
+msgid "let x: List<int> = Cons(10, @Cons(11, @Nil));"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2464
+#, no-wrap
+msgid ""
+"match x {\n"
+"    Cons(_, @Nil) => fail!(\"singleton list\"),\n"
+"    Cons(*)       => return,\n"
+"    Nil           => fail!(\"empty list\")\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2469
+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 "
+"constructed with `Cons`, ignoring the values of its arguments. The "
+"difference between `_` and `*` is that the pattern `C(_)` is only type-"
+"correct if `C` has exactly one argument, while the pattern `C(*)` is type-"
+"correct for any enum variant `C`, regardless of how many arguments `C` has."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2475
+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 "
+"match is found. The first arm with a matching pattern is chosen as the "
+"branch target of the `match`, any variables bound by the pattern are "
+"assigned to local variables in the arm's block, and control enters the block."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2477
+msgid "An example of an `match` expression:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2482
+msgid "~~~~ # fn process_pair(a: int, b: int) { } # fn process_ten() { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2484
+msgid "enum List<X> { Nil, Cons(X, @List<X>) }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2502
+#, no-wrap
+msgid ""
+"match x {\n"
+"    Cons(a, @Cons(b, _)) => {\n"
+"        process_pair(a,b);\n"
+"    }\n"
+"    Cons(10, _) => {\n"
+"        process_ten();\n"
+"    }\n"
+"    Nil => {\n"
+"        return;\n"
+"    }\n"
+"    _ => {\n"
+"        fail!();\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2509
+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 changed "
+"to bind to a borrowed pointer by using the ```ref``` keyword, or to a "
+"mutable borrowed pointer using ```ref mut```."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2520
+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 "
+"variable.  The compiler resolves this ambiguity by forbidding variable "
+"bindings that occur in ```match``` patterns from shadowing names of variants "
+"that are in scope.  For example, wherever ```List``` is in scope, a "
+"```match``` pattern would not be able to bind ```Nil``` as a new name.  The "
+"compiler interprets a variable pattern `x` as a binding _only_ if there is "
+"no variant named `x` in scope.  A convention you can use to avoid conflicts "
+"is simply to name variants with upper-case letters, and local variables with "
+"lower-case letters."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2524
+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:2527
+msgid "~~~~ # let x = 2;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2534
+#, no-wrap
+msgid ""
+"let message = match x {\n"
+"  0 | 1  => \"not many\",\n"
+"  2 .. 9 => \"a few\",\n"
+"  _      => \"lots\"\n"
+"};\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2538
+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 "
+"not be a sub-range of another range pattern inside the same `match`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2543
+msgid ""
+"Finally, match patterns can accept *pattern guards* to further refine the "
+"criteria for matching a case. Pattern guards appear after the pattern and "
+"consist of a bool-typed expression following the `if` keyword. A pattern "
+"guard may refer to the variables bound within the pattern they follow."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2548
+msgid ""
+"~~~~ # let maybe_digit = Some(0); # fn process_digit(i: int) { } # fn "
+"process_other(i: int) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2555
+#, no-wrap
+msgid ""
+"let message = match maybe_digit {\n"
+"  Some(x) if x < 10 => process_digit(x),\n"
+"  Some(x) => process_other(x),\n"
+"  None => fail!()\n"
+"};\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2557
+msgid "### Return expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2561
+msgid "~~~~~~~~{.ebnf .gram} return_expr : \"return\" expr ? ; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2566
+msgid ""
+"Return expressions are denoted with the keyword `return`. Evaluating a "
+"`return` expression moves its argument into the output slot of the current "
+"function, destroys the current function activation frame, and transfers "
+"control to the caller frame."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2568
+msgid "An example of a `return` expression:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2577
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn max(a: int, b: int) -> int {\n"
+"   if a > b {\n"
+"      return a;\n"
+"   }\n"
+"   return b;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2580
+msgid "# Type system"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2582
+msgid "## Types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2585
+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:2589
+msgid ""
+"Built-in types and type-constructors are tightly integrated into the "
+"language, in nontrivial ways that are not possible to emulate in user-"
+"defined types. User-defined types have limited capabilities."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2591
+msgid "### Primitive types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2593
+msgid "The primitive types are the following:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2599
+msgid ""
+"The \"unit\" type `()`, having the single \"unit\" value `()` (occasionally "
+"called \"nil\").  ^[The \"unit\" value `()` is *not* a sentinel \"null "
+"pointer\" value for reference slots; the \"unit\" type is the implicit "
+"return type from functions otherwise lacking a return type, and can be used "
+"in other contexts (such as message-sending or type-parametric code) as a "
+"zero-size type.]"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2599
+msgid "The boolean type `bool` with values `true` and `false`."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2599
+msgid "The machine types."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2599
+msgid "The machine-dependent integer and floating-point types."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2601
+msgid "#### Machine types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2603
+msgid "The machine types are the following:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2608
+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]$ "
+"and $[0, 2^{64} - 1]$ respectively."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2613
+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}), "
+"2^{15} - 1]$, $[-(2^{31}), 2^{31} - 1]$, $[-(2^{63}), 2^{63} - 1]$ "
+"respectively."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2616
+msgid ""
+"The IEEE 754-2008 `binary32` and `binary64` floating-point types: `f32` and "
+"`f64`, respectively."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2618
+msgid "#### Machine-dependent integer types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2623
+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 "
+"bits, is equal to the number of bits required to hold any memory address on "
+"the target machine."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2628
+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 "
+"size, in bits, is equal to the size of the rust type `uint` on the same "
+"target machine."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2631
+msgid "#### Machine-dependent floating point type"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2638
+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 "
+"largest floating-point type that is directly supported by hardware on the "
+"target machine, or if the target machine has no floating-point hardware "
+"support, the largest floating-point type supported by the software floating-"
+"point library used to support the other floating-point machine types."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2641
+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:2644
+msgid "### Textual types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2646
+msgid "The types `char` and `str` hold textual data."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2649
+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:2655
+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 "
+"unknown size, it is not a _first class_ type, but can only be instantiated "
+"through a pointer type, such as `&str`, `@str` or `~str`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2658
+msgid "### Tuple types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2661
+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:2664
+msgid "tuple elements cannot be mutable, unlike record fields"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:2664
+msgid ""
+"tuple elements are not named and can be accessed only by pattern-matching"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2668
+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:2671
+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:2673
+msgid "An example of a tuple type and its use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2680
+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:2683
+msgid "### Vector types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2696
+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 "
+"solely on owned vectors.)  A vector type can be annotated with a _definite_ "
+"size, written with a trailing asterisk and integer literal, such as `[int * "
+"10]`.  Such a definite-sized vector type is a first-class type, since its "
+"size is known statically.  A vector without such a size is said to be of "
+"_indefinite_ size, and is therefore not a _first-class_ type.  An indefinite-"
+"size vector can only be instantiated through a pointer type, such as `&[T]`, "
+"`@[T]` or `~[T]`.  The kind of a vector type depends on the kind of its "
+"element type, as with other simple structural types."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2700
+msgid ""
+"Expressions producing vectors of definite size cannot be evaluated in a "
+"context expecting a vector of indefinite size; one must copy the definite-"
+"sized vector contents into a distinct vector of indefinite size."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2702
+msgid "An example of a vector type and its use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2708
+msgid ""
+"~~~~ let v: &[int] = &[7, 5, 3]; let i: int = v[2]; assert!(i == 3); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2711
+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:2714
+msgid "### Structure types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2719
+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, "
+"the *record* types of the ML family, or the *structure* types of the Lisp "
+"family.]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2721
+msgid ""
+"New instances of a `struct` can be constructed with a [struct expression]"
+"(#struct-expressions)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2725
+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 "
+"resulting `struct` value will always be laid out in memory in the order "
+"specified by the corresponding *item*."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2728
+msgid ""
+"The fields of a `struct` may be qualified by [visibility modifiers]"
+"(#visibility-modifiers), to restrict access to implementation-private data "
+"in a structure."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2730
+msgid ""
+"A _tuple struct_ type is just like a structure type, except that the fields "
+"are anonymous."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2733
+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]"
+"(#structure-expression) is the only value that inhabits such a type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2735
+msgid "### Enumerated types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2740
+msgid ""
+"An *enumerated type* is a nominal, heterogeneous disjoint union type, "
+"denoted by the name of an [`enum` item](#enumerations).  ^[The `enum` type "
+"is analogous to a `data` constructor declaration in ML, or a *pick ADT* in "
+"Limbo.]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2743
+msgid ""
+"An [`enum` item](#enumerations) declares both the type and a number of "
+"*variant constructors*, each of which is independently named and takes an "
+"optional tuple of arguments."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2746
+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:2748
+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:2751
+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:2754
+msgid "### Recursive types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2758
+msgid ""
+"Nominal types -- [enumerations](#enumerated-types) and [structures]"
+"(#structure-types) -- may be recursive.  That is, each `enum` constructor or "
+"`struct` field may refer, directly or indirectly, to the enclosing `enum` or "
+"`struct` type itself.  Such recursion has restrictions:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2768
+#, no-wrap
+msgid ""
+"* Recursive types must include a nominal type in the recursion\n"
+"  (not mere [type definitions](#type-definitions),\n"
+"   or other structural types such as [vectors](#vector-types) or [tuples](#tuple-types)).\n"
+"* A recursive `enum` item must have at least one non-recursive constructor\n"
+"  (in order to give the recursion a basis case).\n"
+"* The size of a recursive type must be finite;\n"
+"  in other words the recursive fields of the type must be [pointer types](#pointer-types).\n"
+"* Recursive type definitions can cross module boundaries, but not module *visibility* boundaries,\n"
+"  or crate boundaries (in order to simplify the module system and type checker).\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2770
+msgid "An example of a *recursive* type and its use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2776
+#, no-wrap
+msgid ""
+"~~~~\n"
+"enum List<T> {\n"
+"  Nil,\n"
+"  Cons(T, @List<T>)\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2779
+msgid "let a: List<int> = Cons(7, @Cons(13, @Nil)); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2782
+msgid "### Pointer types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2786
+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 "
+"varieties of pointer in Rust:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2796
+#, no-wrap
+msgid ""
+"Managed pointers (`@`)\n"
+"  : These point to managed heap allocations (or \"boxes\") in the task-local, managed heap.\n"
+"    Managed pointers are written `@content`,\n"
+"    for example `@int` means a managed pointer to a managed box containing an integer.\n"
+"    Copying a managed pointer is a \"shallow\" operation:\n"
+"    it involves only copying the pointer itself\n"
+"    (as well as any reference-count or GC-barriers required by the managed heap).\n"
+"    Dropping a managed pointer does not necessarily release the box it points to;\n"
+"    the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2805
+#, no-wrap
+msgid ""
+"Owning pointers (`~`)\n"
+"  : These point to owned heap allocations (or \"boxes\") in the shared, inter-task heap.\n"
+"    Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times.\n"
+"    Owning pointers are written `~content`,\n"
+"    for example `~int` means an owning pointer to an owned box containing an integer.\n"
+"    Copying an owned box is a \"deep\" operation:\n"
+"    it involves allocating a new owned box and copying the contents of the old box into the new box.\n"
+"    Releasing an owning pointer immediately releases its corresponding owned box.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2818
+#, no-wrap
+msgid ""
+"Borrowed pointers (`&`)\n"
+"  : These point to memory _owned by some other value_.\n"
+"    Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers,\n"
+"    or by applying the borrowing operator `&` to some other value,\n"
+"    including [lvalues, rvalues or temporaries](#lvalues-rvalues-and-temporaries).\n"
+"    Borrowed pointers are written `&content`, or in some cases `&f/content` for some lifetime-variable `f`,\n"
+"    for example `&int` means a borrowed pointer to an integer.\n"
+"    Copying a borrowed pointer is a \"shallow\" operation:\n"
+"    it involves only copying the pointer itself.\n"
+"    Releasing a borrowed pointer typically has no effect on the value it points to,\n"
+"    with the exception of temporary values,\n"
+"    which are released when the last borrowed pointer to them is released.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2828
+#, no-wrap
+msgid ""
+"Raw pointers (`*`)\n"
+"  : Raw pointers are pointers without safety or liveness guarantees.\n"
+"    Raw pointers are written `*content`,\n"
+"    for example `*int` means a raw pointer to an integer.\n"
+"    Copying or dropping a raw pointer is has no effect on the lifecycle of any other value.\n"
+"    Dereferencing a raw pointer or converting it to any other pointer type is an [`unsafe` operation](#unsafe-functions).\n"
+"    Raw pointers are generally discouraged in Rust code;\n"
+"    they exist to support interoperability with foreign code,\n"
+"    and writing performance-critical or low-level functions.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2831
+msgid "### Function types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2835
+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 "
+"`unsafe` or `extern`), a sequence of input types and an output type."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2837
+msgid "An example of a `fn` type:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2842
+#, no-wrap
+msgid ""
+"~~~~~~~~\n"
+"fn add(x: int, y: int) -> int {\n"
+"  return x + y;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2844
+msgid "let mut x = add(5,7);"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2849
+msgid ""
+"type Binop<'self> = &'self fn(int,int) -> int; let bo: Binop = add; x = "
+"bo(5,7); ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2851
+msgid "### Object types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2858
+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 "
+"types permit \"late binding\" of methods, dispatched using _virtual method "
+"tables_ (\"vtables\").  Whereas most calls to trait methods are \"early bound"
+"\" (statically resolved) to specific implementations at compile time, a call "
+"to a method on an object type is only resolved to a vtable entry at compile "
+"time.  The actual implementation for each vtable entry can vary on an object-"
+"by-object basis."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2863
+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`, "
+"`~R` or `@R` results in a value of the _object type_ `R`.  This result is "
+"represented as a pair of pointers: the vtable pointer for the `T` "
+"implementation of `R`, and the pointer value of `E`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2865
+msgid "An example of an object type:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2871
+#, no-wrap
+msgid ""
+"~~~~~~~~\n"
+"# use std::int;\n"
+"trait Printable {\n"
+"  fn to_str(&self) -> ~str;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2875
+#, no-wrap
+msgid ""
+"impl Printable for int {\n"
+"  fn to_str(&self) -> ~str { int::to_str(*self) }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2879
+#, no-wrap
+msgid ""
+"fn print(a: @Printable) {\n"
+"   println(a.to_str());\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2884
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"   print(@10 as @Printable);\n"
+"}\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2887
+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:2889
+msgid "### Type parameters"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2891
+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:2902
+#, no-wrap
+msgid ""
+"~~~~~~~\n"
+"fn map<A: Clone, B: Clone>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {\n"
+"    if xs.len() == 0 {\n"
+"       return ~[];\n"
+"    }\n"
+"    let first: B = f(xs[0].clone());\n"
+"    let rest: ~[B] = map(f, xs.slice(1, xs.len()));\n"
+"    return ~[first] + rest;\n"
+"}\n"
+"~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2905
+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:2907
+msgid "### Self types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2911
+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:2916
+#, no-wrap
+msgid ""
+"~~~~~~~~\n"
+"trait Printable {\n"
+"  fn make_string(&self) -> ~str;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2923
+#, no-wrap
+msgid ""
+"impl Printable for ~str {\n"
+"    fn make_string(&self) -> ~str {\n"
+"        (*self).clone()\n"
+"    }\n"
+"}\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2926
+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:2928
+msgid "## Type kinds"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2931
+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:2957
+#, no-wrap
+msgid ""
+"`Freeze`\n"
+"  : Types of this kind are deeply immutable;\n"
+"    they contain no mutable memory locations\n"
+"    directly or indirectly via pointers.\n"
+"`Send`\n"
+"  : Types of this kind can be safely sent between tasks.\n"
+"    This kind includes scalars, owning pointers, owned closures, and\n"
+"    structural types containing only other owned types.\n"
+"    All `Send` types are `'static`.\n"
+"`'static`\n"
+"  : Types of this kind do not contain any borrowed pointers;\n"
+"    this can be a useful guarantee for code\n"
+"    that breaks borrowing assumptions\n"
+"    using [`unsafe` operations](#unsafe-functions).\n"
+"`Drop`\n"
+"  : This is not strictly a kind,\n"
+"    but its presence interacts with kinds:\n"
+"    the `Drop` trait provides a single method `drop`\n"
+"    that takes no parameters,\n"
+"    and is run when values of the type are dropped.\n"
+"    Such a method is called a \"destructor\",\n"
+"    and are always executed in \"top-down\" order:\n"
+"    a value is completely destroyed\n"
+"    before any of the values it owns run their destructors.\n"
+"    Only `Send` types can implement `Drop`.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2964
+#, no-wrap
+msgid ""
+"_Default_\n"
+"  : Types with destructors, closure environments,\n"
+"    and various other _non-first-class_ types,\n"
+"    are not copyable at all.\n"
+"    Such types can usually only be accessed through pointers,\n"
+"    or in some cases, moved between mutable locations.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2967
+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:2973
+msgid ""
+"By default, type parameters do not carry any assumed kind-bounds at all.  "
+"When instantiating a type parameter, the kind bounds on the parameter are "
+"checked to be the same or narrower than the kind of the type that it is "
+"instantiated with."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2978
+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 "
+"values to sendable."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2980
+msgid "# Memory and concurrency models"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2985
+msgid ""
+"Rust has a memory model centered around concurrently-executing _tasks_. Thus "
+"its memory model and its concurrency model are best discussed "
+"simultaneously, as parts of each only make sense when considered from the "
+"perspective of the other."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2990
+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 "
+"their isolation and communication mechanisms are only possible due to the "
+"ownership and lifetime semantics of the memory model."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2992
+msgid "## Memory model"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2996
+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 "
+"heap may be shared between tasks, mutable portions may not."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:2999
+msgid ""
+"Allocations in the stack consist of *slots*, and allocations in the heap "
+"consist of *boxes*."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3002
+msgid "### Memory allocation and lifetime"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3007
+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 "
+"image of the rust process. Items are neither dynamically allocated nor freed."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3011
+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 "
+"when control leaves the frame containing it."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3018
+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 "
+"boxes.  The lifetime of an allocation in the heap depends on the lifetime of "
+"the box values pointing to it. Since box values may themselves be passed in "
+"and out of frames, or stored in the heap, heap allocations may outlive the "
+"frame they are allocated within."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3020
+msgid "### Memory ownership"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3023
+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:3030
+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 "
+"statically guaranteed by the combined use of \"move semantics\", and the "
+"compiler-checked _meaning_ of the `Send` trait: it is only instantiated for "
+"(transitively) sendable kinds of data constructor and pointers, never "
+"including managed or borrowed pointers."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3033
+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:3039
+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 "
+"be deferred until task-local garbage collection can reclaim it. Code can "
+"ensure no such delayed deallocation occurs by restricting itself to owned "
+"boxes and similar unmanaged kinds of data."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3042
+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:3045
+msgid "### Memory slots"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3047
+msgid "A task's stack contains slots."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3050
+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:3053
+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:3058
+msgid ""
+"Local variables are immutable unless declared with `let mut`.  The `mut` "
+"keyword applies to all local variables declared within that declaration (so "
+"`let mut (x, y) = ...` declares two mutable variables, `x` and `y`)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3063
+msgid ""
+"Function parameters are immutable unless declared with `mut`. The `mut` "
+"keyword applies only to the following parameter (so `|mut x, y|` and `fn "
+"f(mut x: ~int, y: ~int)` declare one mutable variable `x` and one immutable "
+"variable `y`)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3069
+msgid ""
+"Local variables are not initialized when allocated; the entire frame worth "
+"of local variables are allocated at once, on frame-entry, in an "
+"uninitialized state. Subsequent statements within a function may or may not "
+"initialize the local variables. Local variables can be used only after they "
+"have been initialized; this is enforced by the compiler."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3072
+msgid "### Memory boxes"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3075
+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:3077
+msgid ""
+"A _managed box_ type or value is constructed by the prefix *at* sigil `@`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3079
+msgid ""
+"An _owned box_ type or value is constructed by the prefix *tilde* sigil `~`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3084
+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 "
+"incrementing a reference count, if the managed box is implemented through "
+"reference-counting)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3086
+msgid ""
+"Owned box values exist in 1:1 correspondence with their heap allocation."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3089
+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:3094
+msgid "~~~~~~~~ let x: @int = @10; let x: ~int = ~10; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3097
+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:3103
+msgid ""
+"~~~~~~~~ struct Foo { y: int } let x = @Foo{y: 10}; assert!(x.y == 10); "
+"~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3109
+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 "
+"dereference of the box value. Explicitly dereferencing a box is indicated "
+"with the unary *star* operator `*`. Examples of such _explicit dereference_ "
+"operations are:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3112
+msgid "copying box values (`x = y`)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3112
+msgid "passing box values to functions (`f(x,y)`)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3115
+msgid ""
+"An example of an explicit-dereference operation performed on box values:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3119
+msgid "~~~~~~~~ fn takes_boxed(b: @int) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3122
+msgid "fn takes_unboxed(b: int) { }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3129
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    let x: @int = @10;\n"
+"    takes_boxed(x);\n"
+"    takes_unboxed(*x);\n"
+"}\n"
+"~~~~~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3131
+msgid "## Tasks"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3139
+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 "
+"channels and incoming communication ports, and ownership of some portion of "
+"the heap of a single operating-system process.  (We expect that many "
+"programs will not use channels and ports directly, but will instead use "
+"higher-level abstractions provided in standard libraries, such as pipes.)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3154
+msgid ""
+"Multiple Rust tasks may coexist in a single operating-system process.  The "
+"runtime scheduler maps tasks to a certain number of operating-system "
+"threads.  By default, the scheduler chooses the number of threads based on "
+"the number of concurrent physical CPUs detected at startup.  It's also "
+"possible to override this choice at runtime.  When the number of tasks "
+"exceeds the number of threads -- which is likely -- the scheduler "
+"multiplexes the tasks onto threads.^[ This is an M:N scheduler, which is "
+"known to give suboptimal results for CPU-bound concurrency problems.  In "
+"such cases, running with the same number of threads and tasks can yield "
+"better results.  Rust has M:N scheduling in order to support very large "
+"numbers of tasks in contexts where threads are too resource-intensive to use "
+"in large number.  The cost of threads varies substantially per operating "
+"system, and is sometimes quite low, so this flexibility is not always worth "
+"exploiting.]"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3157
+msgid "### Communication between tasks"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3162
+msgid ""
+"Rust tasks are isolated and generally unable to interfere with one another's "
+"memory directly, except through [`unsafe` code](#unsafe-functions).  All "
+"contact between tasks is mediated by safe forms of ownership transfer, and "
+"data races on memory are prohibited by the type system."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3165
+msgid ""
+"Inter-task communication and co-ordination facilities are provided in the "
+"standard library.  These include:"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:3169
+msgid ""
+"synchronous and asynchronous communication channels with various "
+"communication topologies"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:3169
+msgid ""
+"read-only and read-write shared variables with various safe mutual exclusion "
+"patterns"
+msgstr ""
+
+#. type: Bullet: '  - '
+#: doc/rust.md:3169
+msgid "simple locks and semaphores"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3174
+msgid ""
+"When such facilities carry values, the values are restricted to the [`Send` "
+"type-kind](#type-kinds).  Restricting communication interfaces to this kind "
+"ensures that no borrowed or managed pointers move between tasks.  Thus "
+"access to an entire data structure can be mediated through its owning \"root"
+"\" value; no further locking or copying is required to avoid data races "
+"within the substructure of such a value."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3177
+msgid "### Task lifecycle"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3180
+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:3185
+msgid "running"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3185
+msgid "blocked"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3185
+msgid "failing"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3185
+msgid "dead"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3189
+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 "
+"any functions called by the entry function."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3195
+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 "
+"-- when a message arrives at a sender, or a buffer opens to receive a "
+"message -- then the blocked task will unblock and transition back to "
+"*running*."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3214
+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!()` "
+"macro. Once *failing*, a task unwinds its stack and transitions to the "
+"*dead* state. Unwinding the stack of a task is done by the task itself, on "
+"its own control stack. If a value with a destructor is freed during "
+"unwinding, the code for the destructor is run, also on the task's control "
+"stack. Running the destructor code causes a temporary transition to a "
+"*running* state, and allows the destructor code to cause any subsequent "
+"state transitions.  The original task of unwinding and failing thereby may "
+"suspend temporarily, and may involve (recursive) unwinding of the stack of a "
+"failed destructor. Nonetheless, the outermost unwinding activity will "
+"continue until the stack is unwound and the task transitions to the *dead* "
+"state. There is no way to \"recover\" from task failure.  Once a task has "
+"temporarily suspended its unwinding in the *failing* state, failure "
+"occurring from within this destructor results in *hard* failure.  The "
+"unwinding procedure of hard failure frees resources but does not execute "
+"destructors.  The original (soft) failure is still resumed at the point "
+"where it was temporarily suspended."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3218
+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 "
+"reclamation when the last reference to it drops."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3221
+msgid "### Task scheduling"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3225
+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 "
+"preemption point, and another task within is scheduled, pseudo-randomly."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3229
+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-"
+"executing state (blocked, dead) similarly deschedules the task."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3232
+msgid "# Runtime services, linkage and debugging"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3239
+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-"
+"time. It is smaller and simpler than many modern language runtimes. It is "
+"tightly integrated into the language's execution model of memory, tasks, "
+"communication and logging."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3241
+msgid ""
+"> **Note:** The runtime library will merge with the `std` library in future "
+"versions of Rust."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3243
+msgid "### Memory allocation"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3249
+msgid ""
+"The runtime memory-management system is based on a _service-provider "
+"interface_, through which the runtime requests blocks of memory from its "
+"environment and releases them back to its environment when they are no "
+"longer needed.  The default implementation of the service-provider interface "
+"consists of the C runtime functions `malloc` and `free`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3253
+msgid ""
+"The runtime memory-management system, in turn, supplies Rust tasks with "
+"facilities for allocating, extending and releasing stacks, as well as "
+"allocating and freeing heap data."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3255
+msgid "### Built in types"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3259
+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, "
+"channels, tasks)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3262
+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:3266
+msgid "### Task scheduling and communication"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3272
+msgid ""
+"The runtime provides code to manage inter-task communication.  This includes "
+"the system of task-lifecycle state transitions depending on the contents of "
+"queues, as well as code to copy values between queues and their recipients "
+"and to serialize values for transmission over operating-system inter-process "
+"communication facilities."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3275
+msgid "### Logging system"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3279
+msgid ""
+"The runtime contains a system for directing [logging expressions](#log-"
+"expressions) to a logging console and/or internal logging buffers. Logging "
+"can be enabled per module."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3286
+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 "
+"of paths, with optional log levels. For each module containing log "
+"expressions, if `RUST_LOG` contains the path to that module or a parent of "
+"that module, then logs of the appropriate level will be output to the "
+"console."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3294
+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 "
+"level can be appended to the module path with an equals sign (`=`) followed "
+"by the log level, from 1 to 4, inclusive. Level 1 is the error level, 2 is "
+"warning, 3 info, and 4 debug. Any logs less than or equal to the specified "
+"level will be output. If not specified then log level 4 is assumed."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3300
+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` "
+"[attribute](#attributes)). To narrow down the logs to just crate resolution, "
+"you would set it to `rustc::metadata::creader`. To see just error logging "
+"use `rustc=0`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3305
+msgid ""
+"Note that when compiling source files that don't specify a crate name the "
+"crate is given a default name that matches the source file, with the "
+"extension removed. In that case, to turn on logging for a program compiled "
+"from, e.g. `helloworld.rs`, `RUST_LOG` should be set to `helloworld`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3309
+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 "
+"simply output a list of loaded modules containing log expressions, then exit."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3314
+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, "
+"and can be enabled just like the logs for any standard module. The full list "
+"of runtime logging modules follows."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::mem` Memory management"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::comm` Messaging and task communication"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::task` Task management"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::dom` Task scheduling"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::trace` Unused"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::cache` Type descriptor cache"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::upcall` Compiler-generated runtime calls"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::timer` The scheduler timer"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::gc` Garbage collection"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::stdlib` Functions used directly by the standard library"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::kern` The runtime kernel"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::backtrace` Log a backtrace on task failure"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3328
+msgid "`::rt::callback` Unused"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3330
+msgid "#### Logging Expressions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3333
+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:3342
+#, no-wrap
+msgid ""
+"```rust\n"
+"fn main() {\n"
+"    error!(\"This is an error log\")\n"
+"    warn!(\"This is a warn log\")\n"
+"    info!(\"this is an info log\")\n"
+"    debug!(\"This is a debug log\")\n"
+"}\n"
+"```\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3344
+msgid ""
+"These four log levels correspond to levels 1-4, as controlled by `RUST_LOG`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3351
+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\\\"\" "
+"```"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3353
+msgid "# Appendix: Rationales and design tradeoffs"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3355
+#, no-wrap
+msgid "*TODO*.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3357
+msgid "# Appendix: Influences and further references"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3359
+msgid "## Influences"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3368
+msgid ""
+"> The essential problem that must be solved in making a fault-tolerant > "
+"software system is therefore that of fault-isolation. Different programmers "
+"> will write different modules, some modules will be correct, others will "
+"have > errors. We do not want the errors in one module to adversely affect "
+"the > behaviour of a module which does not have any errors.  > > &mdash; Joe "
+"Armstrong"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3380
+msgid ""
+"> In our approach, all data is private to some process, and processes can > "
+"only communicate through communications channels. *Security*, as used > in "
+"this paper, is the property which guarantees that processes in a system > "
+"cannot affect each other except by explicit communication.  > > When "
+"security is absent, nothing which can be proven about a single module > in "
+"isolation can be guaranteed to hold when that module is embedded in a > "
+"system [...] > > &mdash; Robert Strom and Shaula Yemini"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3388
+msgid ""
+"> Concurrent and applicative programming complement each other. The > "
+"ability to send messages on channels provides I/O without side effects, > "
+"while the avoidance of shared data helps keep concurrent processes from > "
+"colliding.  > > &mdash; Rob Pike"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3395
+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 "
+"\"historical\" languages that have, with a few exceptions, fallen out of "
+"favour. Five prominent lineages contribute the most, though their influences "
+"have come and gone during the course of Rust's development:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3399
+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 "
+"Watson Research Center (Yorktown Heights, NY, USA)."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3403
+msgid ""
+"The Erlang (1987) language, developed by Joe Armstrong, Robert Virding, "
+"Claes Wikstr&ouml;m, Mike Williams and others in their group at the Ericsson "
+"Computer Science Laboratory (&Auml;lvsj&ouml;, Stockholm, Sweden) ."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3408
+msgid ""
+"The Sather (1990) language, developed by Stephen Omohundro, Chu-Cheow Lim, "
+"Heinz Schmidt and others in their group at The International Computer "
+"Science Institute of the University of California, Berkeley (Berkeley, CA, "
+"USA)."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3413
+msgid ""
+"The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These languages "
+"were developed by Rob Pike, Phil Winterbottom, Sean Dorward and others in "
+"their group at Bell Labs Computing Sciences Research Center (Murray Hill, "
+"NJ, USA)."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3417
+msgid ""
+"The Napier (1985) and Napier88 (1988) family. These languages were developed "
+"by Malcolm Atkinson, Ron Morrison and others in their group at the "
+"University of St. Andrews (St. Andrews, Fife, UK)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:3419
+msgid ""
+"Additional specific influences can be seen from the following languages:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The stack-growth implementation of Go."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The structural algebraic types and compilation manager of SML."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The attribute and assembly systems of C#."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The references and deterministic destructor system of C++."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The memory region systems of the ML Kit and Cyclone."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The typeclass system of Haskell."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The lexical identifier rule of Python."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rust.md:3427
+msgid "The block syntax of Ruby."
+msgstr ""
diff --git a/doc/po/ja/rustpkg.md.po b/doc/po/ja/rustpkg.md.po
new file mode 100644 (file)
index 0000000..b633d8a
--- /dev/null
@@ -0,0 +1,323 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-07-30 07:07+0900\n"
+"PO-Revision-Date: 2013-07-28 20:32+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/rust.md:30 doc/rustpkg.md:8
+msgid "## Disclaimer"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:2
+msgid "% Rustpkg Reference Manual"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:6
+msgid ""
+"This document is the reference manual for the Rustpkg packaging and build "
+"tool for the Rust programming language."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:12
+msgid ""
+"Rustpkg is a work in progress, as is this reference manual.  If the actual "
+"behavior of rustpkg differs from the behavior described in this reference, "
+"that reflects either an incompleteness or a bug in rustpkg."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:14
+msgid "# Package searching"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:17
+msgid ""
+"rustpkg searches for packages using the `RUST_PATH` environment variable, "
+"which is a colon-separated list (semicolon-separated on Windows) of "
+"directories."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:19
+msgid "Each directory in this list is a *workspace* for rustpkg."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:30
+msgid ""
+"`RUST_PATH` implicitly contains an entry for `./.rust` (as well as `../."
+"rust`, `../../.rust`, and so on for every parent of `.` up to the filesystem "
+"root).  That means that if `RUST_PATH` is not set, then rustpkg will still "
+"search for workspaces in `./.rust` and so on.  `RUST_PATH` also implicitly "
+"contains an entry for the system path: `/usr/local` or the equivalent on "
+"Windows.  This entry comes after the implicit entries for `./.rust` and so "
+"on.  Finally, the last implicit entry in `RUST_PATH` is `~/.rust` or the "
+"equivalent on Windows."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:32
+msgid "Each workspace may contain one or more packages."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:38
+msgid ""
+"When building code that contains one or more directives of the form `extern "
+"mod P`, rustpkg automatically searches for packages named `P` in the "
+"`RUST_PATH` (as described above).  It builds those dependencies if "
+"necessary.  Thus, when using rustpkg, there is no need for `-L` flags to "
+"tell the linker where to find libraries for external crates."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:40
+msgid "# Package structure"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:42
+msgid "A valid workspace must contain each of the following subdirectories:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rustpkg.md:44
+msgid ""
+"'src/': contains one subdirectory per package. Each subdirectory contains "
+"source files for a given package."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:49
+#, no-wrap
+msgid ""
+"     For example, if `foo` is a workspace containing the package `bar`,\n"
+"     then `foo/src/bar/main.rs` could be the `main` entry point for\n"
+"     building a `bar` executable.\n"
+"* 'lib/': `rustpkg install` installs libraries into a target-specific subdirectory of this directory.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:56
+#, no-wrap
+msgid ""
+"     For example, on a 64-bit machine running Mac OS X,\n"
+"     if `foo` is a workspace containing the package `bar`,\n"
+"     rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`.\n"
+"     The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`,\n"
+"     where [hash] is a hash of the package ID.\n"
+"* 'bin/': `rustpkg install` installs executable binaries into a target-specific subdirectory of this directory.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:63
+#, no-wrap
+msgid ""
+"     For example, on a 64-bit machine running Mac OS X,\n"
+"     if `foo` is a workspace, containing the package `bar`,\n"
+"     rustpkg will install executables for `bar` to\n"
+"     `foo/bin/x86_64-apple-darwin/`.\n"
+"     The executables will have names of the form `foo/bin/x86_64-apple-darwin/bar`.\n"
+"* 'build/': `rustpkg build` stores temporary build artifacts in a target-specific subdirectory of this directory.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:67
+#, no-wrap
+msgid ""
+"     For example, on a 64-bit machine running Mac OS X,\n"
+"     if `foo` is a workspace containing the package `bar` and `foo/src/bar/main.rs` exists,\n"
+"     then `rustpkg build` will create `foo/build/x86_64-apple-darwin/bar/main.o`.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:69
+msgid "# Package identifiers"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:87
+msgid ""
+"A package identifier identifies a package uniquely.  A package can be stored "
+"in a workspace on the local file system, or on a remote Web server, in which "
+"case the package ID resembles a URL.  For example, `github.com/mozilla/rust` "
+"is a package ID that would refer to the git repository browsable at `http://"
+"github.com/mozilla/rust`.  A package ID can also specify a version, like: "
+"`github.com/mozilla/rust#0.3`.  In this case, `rustpkg` will check that the "
+"repository `github.com/mozilla/rust` has a tag named `0.3`, and report an "
+"error otherwise.  A package ID can also specify a particular revision of a "
+"repository, like: `github.com/mozilla/rust#release-0.7`.  When the refspec "
+"(portion of the package ID after the `#`) can't be parsed as a decimal "
+"number, rustpkg passes the refspec along to the version control system "
+"without interpreting it.  rustpkg also interprets any dependencies on such a "
+"package ID literally (as opposed to versions, where a newer version "
+"satisfies a dependency on an older version).  Thus, `github.com/mozilla/"
+"rust#5c4cd30f80` is also a valid package ID, since git can deduce that "
+"5c4cd30f80 refers to a revision of the desired repository."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:89
+msgid "## Source files"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:91
+msgid ""
+"rustpkg searches for four different fixed filenames in order to determine "
+"the crates to build:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rustpkg.md:96
+msgid "`main.rs`: Assumed to be a main entry point for building an executable."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rustpkg.md:96
+msgid "`lib.rs`: Assumed to be a library crate."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rustpkg.md:96
+msgid ""
+"`test.rs`: Assumed to contain tests declared with the `#[test]` attribute."
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/rustpkg.md:96
+msgid ""
+"`bench.rs`: Assumed to contain benchmarks declared with the `#[bench]` "
+"attribute."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:98
+msgid "## Versions"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:105
+msgid ""
+"`rustpkg` packages do not need to declare their versions with an attribute "
+"inside one of the source files, because `rustpkg` infers it from the version "
+"control system.  When building a package that is in a `git` repository, "
+"`rustpkg` assumes that the most recent tag specifies the current version.  "
+"When building a package that is not under version control, or that has no "
+"tags, `rustpkg` assumes the intended version is 0.1."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:107
+msgid "# Dependencies"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:111
+msgid ""
+"rustpkg infers dependencies from `extern mod` directives.  Thus, there "
+"should be no need to pass a `-L` flag to rustpkg to tell it where to find a "
+"library.  (In the future, it will also be possible to write an `extern mod` "
+"directive referring to a remote package.)"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:113
+msgid "# Custom build scripts"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:117
+msgid ""
+"A file called `pkg.rs` at the root level in a workspace is called a *package "
+"script*.  If a package script exists, rustpkg executes it to build the "
+"package rather than inferring crates as described previously."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:121
+msgid ""
+"Inside `pkg.rs`, it's possible to call back into rustpkg to finish up the "
+"build.  `rustpkg::api` contains functions to build, install, or clean "
+"libraries and executables in the way rustpkg normally would without custom "
+"build logic."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:123
+msgid "# Command reference"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:125
+msgid "## build"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:131
+msgid ""
+"`rustpkg build foo` searches for a package with ID `foo` and builds it in "
+"any workspace(s) where it finds one.  Supposing such packages are found in "
+"workspaces X, Y, and Z, the command leaves behind files in `X`'s, `Y`'s, and "
+"`Z`'s `build` directories, but not in their `lib` or `bin` directories."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:133
+msgid "## clean"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:135
+msgid "`rustpkg clean foo` deletes the contents of `foo`'s `build` directory."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:137
+msgid "## install"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:141
+msgid ""
+"`rustpkg install foo` builds the libraries and/or executables that are "
+"targets for `foo`, and then installs them either into `foo`'s `lib` and "
+"`bin` directories, or into the `lib` and `bin` subdirectories of the first "
+"entry in `RUST_PATH`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:143
+msgid "## test"
+msgstr ""
+
+#. type: Plain text
+#: doc/rustpkg.md:145
+msgid ""
+"`rustpkg test foo` builds `foo`'s `test.rs` file if necessary, then runs the "
+"resulting test executable."
+msgstr ""
diff --git a/doc/po/ja/tutorial-borrowed-ptr.md.po b/doc/po/ja/tutorial-borrowed-ptr.md.po
new file mode 100644 (file)
index 0000000..110d712
--- /dev/null
@@ -0,0 +1,1071 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-07-22 23:37+0900\n"
+"PO-Revision-Date: 2013-07-28 20:32+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/tutorial.md:1108 doc/tutorial-borrowed-ptr.md:72
+msgid "Now we can call `compute_distance()` in various ways:"
+msgstr ""
+"上記の `compute_distance()` 関数は、様々な方法で呼び出すことができます。"
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:2
+msgid "% Rust Borrowed Pointers Tutorial"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:14
+msgid ""
+"Borrowed pointers are one of the more flexible and powerful tools available "
+"in Rust. A borrowed pointer can point anywhere: into the managed or exchange "
+"heap, into the stack, and even into the interior of another data structure. "
+"A borrowed pointer is as flexible as a C pointer or C++ reference. However, "
+"unlike C and C++ compilers, the Rust compiler includes special static checks "
+"that ensure that programs use borrowed pointers safely. Another advantage of "
+"borrowed pointers is that they are invisible to the garbage collector, so "
+"working with borrowed pointers helps reduce the overhead of automatic memory "
+"management."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:18
+msgid ""
+"Despite their complete safety, a borrowed pointer's representation at "
+"runtime is the same as that of an ordinary pointer in a C program. They "
+"introduce zero overhead. The compiler does all safety checks at compile time."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:24
+msgid ""
+"Although borrowed pointers have rather elaborate theoretical underpinnings "
+"(region pointers), the core concepts will be familiar to anyone who has "
+"worked with C or C++. Therefore, the best way to explain how they are used—"
+"and their limitations—is probably just to work through several examples."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:26
+msgid "# By example"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:31
+msgid ""
+"Borrowed pointers are called *borrowed* because they are only valid for a "
+"limited duration. Borrowed pointers never claim any kind of ownership over "
+"the data that they point to: instead, they are used for cases where you "
+"would like to use data for a short time."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:33
+msgid "As an example, consider a simple struct type `Point`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:37
+msgid "~~~ struct Point {x: float, y: float} ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:41
+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 "
+"point, but allocated in a different place:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:48
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}\n"
+"let on_the_stack :  Point =  Point {x: 3.0, y: 4.0};\n"
+"let managed_box  : @Point = @Point {x: 5.0, y: 1.0};\n"
+"let owned_box    : ~Point = ~Point {x: 7.0, y: 9.0};\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:60
+msgid ""
+"Suppose we wanted to write a procedure that computed the distance between "
+"any two points, no matter where they were stored. For example, we might like "
+"to compute the distance between `on_the_stack` and `managed_box`, or between "
+"`managed_box` and `owned_box`. One option is to define a function that takes "
+"two arguments of type `Point`—that is, it takes the points by value. But if "
+"we define it this way, calling the function will cause the points to be "
+"copied. For points, this is probably not so bad, but often copies are "
+"expensive. Worse, if the data type contains mutable fields, copying can "
+"change the semantics of your program in unexpected ways. So we'd like to "
+"define a function that takes the points by pointer. We can use borrowed "
+"pointers to do this:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:70
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}\n"
+"# fn sqrt(f: float) -> float { 0f }\n"
+"fn compute_distance(p1: &Point, p2: &Point) -> float {\n"
+"    let x_d = p1.x - p2.x;\n"
+"    let y_d = p1.y - p2.y;\n"
+"    sqrt(x_d * x_d + y_d * y_d)\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:82
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}\n"
+"# let on_the_stack :  Point =  Point{x: 3.0, y: 4.0};\n"
+"# let managed_box  : @Point = @Point{x: 5.0, y: 1.0};\n"
+"# let owned_box    : ~Point = ~Point{x: 7.0, y: 9.0};\n"
+"# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }\n"
+"compute_distance(&on_the_stack, managed_box);\n"
+"compute_distance(managed_box, owned_box);\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:89
+msgid ""
+"Here, the `&` operator takes the address of the variable `on_the_stack`; "
+"this is because `on_the_stack` has the type `Point` (that is, a struct "
+"value) and we have to take its address to get a value. We also call this "
+"_borrowing_ the local variable `on_the_stack`, because we have created an "
+"alias: that is, another name for the same data."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:95
+msgid ""
+"In contrast, we can pass the boxes `managed_box` and `owned_box` to "
+"`compute_distance` directly. The compiler automatically converts a box like "
+"`@Point` or `~Point` to a borrowed pointer like `&Point`. This is another "
+"form of borrowing: in this case, the caller lends the contents of the "
+"managed or owned box to the callee."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:105
+msgid ""
+"Whenever a caller lends data to a callee, there are some limitations on what "
+"the caller can do with the original. For example, if the contents of a "
+"variable have been lent out, you cannot send that variable to another task. "
+"In addition, the compiler will reject any code that might cause the borrowed "
+"value to be freed or overwrite its component fields with values of different "
+"types (I'll get into what kinds of actions those are shortly). This rule "
+"should make intuitive sense: you must wait for a borrower to return the "
+"value that you lent it (that is, wait for the borrowed pointer to go out of "
+"scope)  before you can make full use of it again."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:107
+msgid "# Other uses for the & operator"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:109
+msgid "In the previous example, the value `on_the_stack` was defined like so:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:114
+msgid ""
+"~~~ # struct Point {x: float, y: float} let on_the_stack: Point = Point {x: "
+"3.0, y: 4.0}; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:119
+msgid ""
+"This declaration means that code can only pass `Point` by value to other "
+"functions. As a consequence, we had to explicitly take the address of "
+"`on_the_stack` to get a borrowed pointer. Sometimes however it is more "
+"convenient to move the & operator into the definition of `on_the_stack`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:124
+msgid ""
+"~~~ # struct Point {x: float, y: float} let on_the_stack2: &Point = &Point "
+"{x: 3.0, y: 4.0}; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:128
+msgid ""
+"Applying `&` to an rvalue (non-assignable location) is just a convenient "
+"shorthand for creating a temporary and taking its address. A more verbose "
+"way to write the same code is:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:134
+msgid ""
+"~~~ # struct Point {x: float, y: float} let tmp = Point {x: 3.0, y: 4.0}; "
+"let on_the_stack2 : &Point = &tmp; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:136
+msgid "# Taking the address of fields"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:141
+msgid ""
+"As in C, the `&` operator is not limited to taking the address of local "
+"variables. It can also take the address of fields or individual array "
+"elements. For example, consider this type definition for `rectangle`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:147
+msgid ""
+"~~~ struct Point {x: float, y: float} // as before struct Size {w: float, h: "
+"float} // as before struct Rectangle {origin: Point, size: Size} ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:149
+msgid "Now, as before, we can define rectangles in a few different ways:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:161
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}\n"
+"# struct Size {w: float, h: float} // as before\n"
+"# struct Rectangle {origin: Point, size: Size}\n"
+"let rect_stack   = &Rectangle {origin: Point {x: 1f, y: 2f},\n"
+"                               size: Size {w: 3f, h: 4f}};\n"
+"let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f},\n"
+"                               size: Size {w: 3f, h: 4f}};\n"
+"let rect_owned   = ~Rectangle {origin: Point {x: 5f, y: 6f},\n"
+"                               size: Size {w: 3f, h: 4f}};\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:164
+msgid ""
+"In each case, we can extract out individual subcomponents with the `&` "
+"operator. For example, I could write:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:175
+msgid ""
+"~~~ # struct Point {x: float, y: float} // as before # struct Size {w: "
+"float, h: float} // as before # struct Rectangle {origin: Point, size: Size} "
+"# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: "
+"3f, h: 4f}}; # let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, "
+"size: Size {w: 3f, h: 4f}}; # let rect_owned = ~Rectangle {origin: Point {x: "
+"5f, y: 6f}, size: Size {w: 3f, h: 4f}}; # fn compute_distance(p1: &Point, "
+"p2: &Point) -> float { 0f } compute_distance(&rect_stack.origin, "
+"&rect_managed.origin); ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:178
+msgid ""
+"which would borrow the field `origin` from the rectangle on the stack as "
+"well as from the managed box, and then compute the distance between them."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:180
+msgid "# Borrowing managed boxes and rooting"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:186
+msgid ""
+"We’ve seen a few examples so far of borrowing heap boxes, both managed and "
+"owned. Up till this point, we’ve glossed over issues of safety. As stated in "
+"the introduction, at runtime a borrowed pointer is simply a pointer, nothing "
+"more. Therefore, avoiding C's problems with dangling pointers requires a "
+"compile-time safety check."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:197
+msgid ""
+"The basis for the check is the notion of _lifetimes_. A lifetime is a static "
+"approximation of the span of execution during which the pointer is valid: it "
+"always corresponds to some expression or block within the program. Code "
+"inside that expression can use the pointer without restrictions. But if the "
+"pointer escapes from that expression (for example, if the expression "
+"contains an assignment expression that assigns the pointer to a mutable "
+"field of a data structure with a broader scope than the pointer itself), the "
+"compiler reports an error. We'll be discussing lifetimes more in the "
+"examples to come, and a more thorough introduction is also available."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:202
+msgid ""
+"When the `&` operator creates a borrowed pointer, the compiler must ensure "
+"that the pointer remains valid for its entire lifetime. Sometimes this is "
+"relatively easy, such as when taking the address of a local variable or a "
+"field that is stored on the stack:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:211
+#, no-wrap
+msgid ""
+"~~~\n"
+"struct X { f: int }\n"
+"fn example1() {\n"
+"    let mut x = X { f: 3 };\n"
+"    let y = &mut x.f;  // -+ L\n"
+"    ...                //  |\n"
+"}                      // -+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:216
+msgid ""
+"Here, the lifetime of the borrowed pointer `y` is simply L, the remainder of "
+"the function body. The compiler need not do any other work to prove that "
+"code will not free `x.f`. This is true even if the code mutates `x`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:218
+msgid "The situation gets more complex when borrowing data inside heap boxes:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:227
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct X { f: int }\n"
+"fn example2() {\n"
+"    let mut x = @X { f: 3 };\n"
+"    let y = &x.f;      // -+ L\n"
+"    ...                //  |\n"
+"}                      // -+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:238
+msgid ""
+"In this example, the value `x` is a heap box, and `y` is therefore a pointer "
+"into that heap box. Again the lifetime of `y` is L, the remainder of the "
+"function body. But there is a crucial difference: suppose `x` were to be "
+"reassigned during the lifetime L? If the compiler isn't careful, the managed "
+"box could become *unrooted*, and would therefore be subject to garbage "
+"collection. A heap box that is unrooted is one such that no pointer values "
+"in the heap point to it. It would violate memory safety for the box that was "
+"originally assigned to `x` to be garbage-collected, since a non-heap pointer "
+"*`y`* still points into it."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:241
+msgid ""
+"> ***Note:*** Our current implementation implements the garbage collector > "
+"using reference counting and cycle detection."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:247
+msgid ""
+"For this reason, whenever an `&` expression borrows the interior of a "
+"managed box stored in a mutable location, the compiler inserts a temporary "
+"that ensures that the managed box remains live for the entire lifetime. So, "
+"the above example would be compiled as if it were written"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:257
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct X { f: int }\n"
+"fn example2() {\n"
+"    let mut x = @X {f: 3};\n"
+"    let x1 = x;\n"
+"    let y = &x1.f;     // -+ L\n"
+"    ...                //  |\n"
+"}                      // -+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:260
+msgid ""
+"Now if `x` is reassigned, the pointer `y` will still remain valid. This "
+"process is called *rooting*."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:262
+msgid "# Borrowing owned boxes"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:268
+msgid ""
+"The previous example demonstrated *rooting*, the process by which the "
+"compiler ensures that managed boxes remain live for the duration of a "
+"borrow. Unfortunately, rooting does not work for borrows of owned boxes, "
+"because it is not possible to have two references to a owned box."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:274
+msgid ""
+"For owned boxes, therefore, the compiler will only allow a borrow *if the "
+"compiler can guarantee that the owned box will not be reassigned or moved "
+"for the lifetime of the pointer*. This does not necessarily mean that the "
+"owned box is stored in immutable memory. For example, the following function "
+"is legal:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:289
+#, no-wrap
+msgid ""
+"~~~\n"
+"# fn some_condition() -> bool { true }\n"
+"# struct Foo { f: int }\n"
+"fn example3() -> int {\n"
+"    let mut x = ~Foo {f: 3};\n"
+"    if some_condition() {\n"
+"        let y = &x.f;      // -+ L\n"
+"        return *y;         //  |\n"
+"    }                      // -+\n"
+"    x = ~Foo {f: 4};\n"
+"    ...\n"
+"# return 0;\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:295
+msgid ""
+"Here, as before, the interior of the variable `x` is being borrowed and `x` "
+"is declared as mutable. However, the compiler can prove that `x` is not "
+"assigned anywhere in the lifetime L of the variable `y`. Therefore, it "
+"accepts the function, even though `x` is mutable and in fact is mutated "
+"later in the function."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:301
+msgid ""
+"It may not be clear why we are so concerned about mutating a borrowed "
+"variable. The reason is that the runtime system frees any owned box _as soon "
+"as its owning reference changes or goes out of scope_. Therefore, a program "
+"like this is illegal (and would be rejected by the compiler):"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:310
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"fn example3() -> int {\n"
+"    let mut x = ~X {f: 3};\n"
+"    let y = &x.f;\n"
+"    x = ~X {f: 4};  // Error reported here.\n"
+"    *y\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:313
+msgid ""
+"To make this clearer, consider this diagram showing the state of memory "
+"immediately before the re-assignment of `x`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:316 doc/tutorial-borrowed-ptr.md:330
+#, no-wrap
+msgid ""
+"~~~ {.notrust}\n"
+"    Stack               Exchange Heap\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:325
+#, no-wrap
+msgid ""
+"  x +----------+\n"
+"    | ~{f:int} | ----+\n"
+"  y +----------+     |\n"
+"    | &int     | ----+\n"
+"    +----------+     |    +---------+\n"
+"                     +--> |  f: 3   |\n"
+"                          +---------+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:327
+msgid "Once the reassignment occurs, the memory will look like this:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:339
+#, no-wrap
+msgid ""
+"  x +----------+          +---------+\n"
+"    | ~{f:int} | -------> |  f: 4   |\n"
+"  y +----------+          +---------+\n"
+"    | &int     | ----+\n"
+"    +----------+     |    +---------+\n"
+"                     +--> | (freed) |\n"
+"                          +---------+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:342
+msgid ""
+"Here you can see that the variable `y` still points at the old box, which "
+"has been freed."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:348
+msgid ""
+"In fact, the compiler can apply the same kind of reasoning to any memory "
+"that is _(uniquely) owned by the stack frame_. So we could modify the "
+"previous example to introduce additional owned pointers and structs, and the "
+"compiler will still be able to detect possible mutations:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:353
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"fn example3() -> int {\n"
+"    struct R { g: int }\n"
+"    struct S { f: ~R }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:361
+#, no-wrap
+msgid ""
+"    let mut x = ~S {f: ~R {g: 3}};\n"
+"    let y = &x.f.g;\n"
+"    x = ~S {f: ~R {g: 4}};  // Error reported here.\n"
+"    x.f = ~R {g: 5};        // Error reported here.\n"
+"    *y\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:365
+msgid ""
+"In this case, two errors are reported, one when the variable `x` is modified "
+"and another when `x.f` is modified. Either modification would invalidate the "
+"pointer `y`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:367
+msgid "# Borrowing and enums"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:373
+msgid ""
+"The previous example showed that the type system forbids any borrowing of "
+"owned boxes found in aliasable, mutable memory. This restriction prevents "
+"pointers from pointing into freed memory. There is one other case where the "
+"compiler must be very careful to ensure that pointers remain valid: pointers "
+"into the interior of an `enum`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:376
+msgid ""
+"As an example, let’s look at the following `shape` type that can represent "
+"both rectangles and circles:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:385
+#, no-wrap
+msgid ""
+"~~~\n"
+"struct Point {x: float, y: float}; // as before\n"
+"struct Size {w: float, h: float}; // as before\n"
+"enum Shape {\n"
+"    Circle(Point, float),   // origin, radius\n"
+"    Rectangle(Point, Size)  // upper-left, dimensions\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:389
+msgid ""
+"Now we might write a function to compute the area of a shape. This function "
+"takes a borrowed pointer to a shape, to avoid the need for copying."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:405
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}; // as before\n"
+"# struct Size {w: float, h: float}; // as before\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),   // origin, radius\n"
+"#     Rectangle(Point, Size)  // upper-left, dimensions\n"
+"# }\n"
+"# static tau: float = 6.28f;\n"
+"fn compute_area(shape: &Shape) -> float {\n"
+"    match *shape {\n"
+"        Circle(_, radius) => 0.5 * tau * radius * radius,\n"
+"        Rectangle(_, ref size) => size.w * size.h\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:410
+msgid ""
+"The first case matches against circles. Here, the pattern extracts the "
+"radius from the shape variant and the action uses it to compute the area of "
+"the circle. (Like any up-to-date engineer, we use the [tau circle constant]"
+"[tau] and not that dreadfully outdated notion of pi)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:412
+msgid "[tau]: http://www.math.utah.edu/~palais/pi.html"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:418
+msgid ""
+"The second match is more interesting. Here we match against a rectangle and "
+"extract its size: but rather than copy the `size` struct, we use a by-"
+"reference binding to create a pointer to it. In other words, a pattern "
+"binding like `ref size` binds the name `size` to a pointer of type `&size` "
+"into the _interior of the enum_."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:421
+msgid ""
+"To make this more clear, let's look at a diagram of memory layout in the "
+"case where `shape` points at a rectangle:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:424 doc/tutorial-borrowed-ptr.md:449
+#, no-wrap
+msgid ""
+"~~~ {.notrust}\n"
+"Stack             Memory\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:433
+#, no-wrap
+msgid ""
+"+-------+         +---------------+\n"
+"| shape | ------> | rectangle(    |\n"
+"+-------+         |   {x: float,  |\n"
+"| size  | -+      |    y: float}, |\n"
+"+-------+  +----> |   {w: float,  |\n"
+"                  |    h: float}) |\n"
+"                  +---------------+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:440
+msgid ""
+"Here you can see that rectangular shapes are composed of five words of "
+"memory. The first is a tag indicating which variant this enum is "
+"(`rectangle`, in this case). The next two words are the `x` and `y` fields "
+"for the point and the remaining two are the `w` and `h` fields for the size. "
+"The binding `size` is then a pointer into the inside of the shape."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:446
+msgid ""
+"Perhaps you can see where the danger lies: if the shape were somehow to be "
+"reassigned, perhaps to a circle, then although the memory used to store that "
+"shape value would still be valid, _it would have a different type_! The "
+"following diagram shows what memory would look like if code overwrote "
+"`shape` with a circle:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:458
+#, no-wrap
+msgid ""
+"+-------+         +---------------+\n"
+"| shape | ------> | circle(       |\n"
+"+-------+         |   {x: float,  |\n"
+"| size  | -+      |    y: float}, |\n"
+"+-------+  +----> |   float)      |\n"
+"                  |               |\n"
+"                  +---------------+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:463
+msgid ""
+"As you can see, the `size` pointer would be pointing at a `float` instead of "
+"a struct. This is not good: dereferencing the second field of a `float` as "
+"if it were a struct with two fields would be a memory safety violation."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:475
+msgid ""
+"So, in fact, for every `ref` binding, the compiler will impose the same "
+"rules as the ones we saw for borrowing the interior of a owned box: it must "
+"be able to guarantee that the `enum` will not be overwritten for the "
+"duration of the borrow.  In fact, the compiler would accept the example we "
+"gave earlier. The example is safe because the shape pointer has type "
+"`&Shape`, which means \"borrowed pointer to immutable memory containing a "
+"`shape`\". If, however, the type of that pointer were `&mut Shape`, then the "
+"ref binding would be ill-typed.  Just as with owned boxes, the compiler will "
+"permit `ref` bindings into data owned by the stack frame even if the data "
+"are mutable, but otherwise it requires that the data reside in immutable "
+"memory."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:477
+msgid "# Returning borrowed pointers"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:483
+msgid ""
+"So far, all of the examples we have looked at, use borrowed pointers in a "
+"“downward” direction. That is, a method or code block creates a borrowed "
+"pointer, then uses it within the same scope. It is also possible to return "
+"borrowed pointers as the result of a function, but as we'll see, doing so "
+"requires some explicit annotation."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:485
+msgid "For example, we could write a subroutine like this:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:490
+msgid ""
+"~~~ struct Point {x: float, y: float} fn get_x<'r>(p: &'r Point) -> &'r "
+"float { &p.x } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:498
+msgid ""
+"Here, the function `get_x()` returns a pointer into the structure it was "
+"given. The type of the parameter (`&'r Point`) and return type (`&'r float`) "
+"both use a new syntactic form that we have not seen so far.  Here the "
+"identifier `r` names the lifetime of the pointer explicitly. So in effect, "
+"this function declares that it takes a pointer with lifetime `r` and returns "
+"a pointer with that same lifetime."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:504
+msgid ""
+"In general, it is only possible to return borrowed pointers if they are "
+"derived from a parameter to the procedure. In that case, the pointer result "
+"will always have the same lifetime as one of the parameters; named lifetimes "
+"indicate which parameter that is."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:510
+msgid ""
+"In the previous examples, function parameter types did not include a "
+"lifetime name. In those examples, the compiler simply creates a fresh name "
+"for the lifetime automatically: that is, the lifetime name is guaranteed to "
+"refer to a distinct lifetime from the lifetimes of all other parameters."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:518
+msgid ""
+"Named lifetimes that appear in function signatures are conceptually the same "
+"as the other lifetimes we have seen before, but they are a bit abstract: "
+"they don’t refer to a specific expression within `get_x()`, but rather to "
+"some expression within the *caller of `get_x()`*.  The lifetime `r` is "
+"actually a kind of *lifetime parameter*: it is defined by the caller to "
+"`get_x()`, just as the value for the parameter `p` is defined by that caller."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:523
+msgid ""
+"In any case, whatever the lifetime of `r` is, the pointer produced by `&p.x` "
+"always has the same lifetime as `p` itself: a pointer to a field of a struct "
+"is valid as long as the struct is valid. Therefore, the compiler accepts the "
+"function `get_x()`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:526
+msgid ""
+"To emphasize this point, let’s look at a variation on the example, this time "
+"one that does not compile:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:533
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"struct Point {x: float, y: float}\n"
+"fn get_x_sh(p: @Point) -> &float {\n"
+"    &p.x // Error reported here\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:541
+msgid ""
+"Here, the function `get_x_sh()` takes a managed box as input and returns a "
+"borrowed pointer. As before, the lifetime of the borrowed pointer that will "
+"be returned is a parameter (specified by the caller). That means that "
+"`get_x_sh()` promises to return a borrowed pointer that is valid for as long "
+"as the caller would like: this is subtly different from the first example, "
+"which promised to return a pointer that was valid for as long as its pointer "
+"argument was valid."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:552
+msgid ""
+"Within `get_x_sh()`, we see the expression `&p.x` which takes the address of "
+"a field of a managed box. The presence of this expression implies that the "
+"compiler must guarantee that, so long as the resulting pointer is valid, the "
+"managed box will not be reclaimed by the garbage collector. But recall that "
+"`get_x_sh()` also promised to return a pointer that was valid for as long as "
+"the caller wanted it to be. Clearly, `get_x_sh()` is not in a position to "
+"make both of these guarantees; in fact, it cannot guarantee that the pointer "
+"will remain valid at all once it returns, as the parameter `p` may or may "
+"not be live in the caller. Therefore, the compiler will report an error here."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:559
+msgid ""
+"In general, if you borrow a managed (or owned) box to create a borrowed "
+"pointer, the pointer will only be valid within the function and cannot be "
+"returned. This is why the typical way to return borrowed pointers is to take "
+"borrowed pointers as input (the only other case in which it can be legal to "
+"return a borrowed pointer is if the pointer points at a static constant)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:561
+msgid "# Named lifetimes"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:565
+msgid ""
+"Let's look at named lifetimes in more detail. Named lifetimes allow for "
+"grouping of parameters by lifetime. For example, consider this function:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:579
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}; // as before\n"
+"# struct Size {w: float, h: float}; // as before\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),   // origin, radius\n"
+"#     Rectangle(Point, Size)  // upper-left, dimensions\n"
+"# }\n"
+"# fn compute_area(shape: &Shape) -> float { 0f }\n"
+"fn select<'r, T>(shape: &'r Shape, threshold: float,\n"
+"                 a: &'r T, b: &'r T) -> &'r T {\n"
+"    if compute_area(shape) > threshold {a} else {b}\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:585
+msgid ""
+"This function takes three borrowed pointers and assigns each the same "
+"lifetime `r`.  In practice, this means that, in the caller, the lifetime `r` "
+"will be the *intersection of the lifetime of the three region parameters*. "
+"This may be overly conservative, as in this example:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:607
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}; // as before\n"
+"# struct Size {w: float, h: float}; // as before\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),   // origin, radius\n"
+"#     Rectangle(Point, Size)  // upper-left, dimensions\n"
+"# }\n"
+"# fn compute_area(shape: &Shape) -> float { 0f }\n"
+"# fn select<'r, T>(shape: &Shape, threshold: float,\n"
+"#                  a: &'r T, b: &'r T) -> &'r T {\n"
+"#     if compute_area(shape) > threshold {a} else {b}\n"
+"# }\n"
+"                                                     // -+ r\n"
+"fn select_based_on_unit_circle<'r, T>(               //  |-+ B\n"
+"    threshold: float, a: &'r T, b: &'r T) -> &'r T { //  | |\n"
+"                                                     //  | |\n"
+"    let shape = Circle(Point {x: 0., y: 0.}, 1.);    //  | |\n"
+"    select(&shape, threshold, a, b)                  //  | |\n"
+"}                                                    //  |-+\n"
+"                                                     // -+\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:617
+msgid ""
+"In this call to `select()`, the lifetime of the first parameter shape is B, "
+"the function body. Both of the second two parameters `a` and `b` share the "
+"same lifetime, `r`, which is a lifetime parameter of "
+"`select_based_on_unit_circle()`. The caller will infer the intersection of "
+"these two lifetimes as the lifetime of the returned value, and hence the "
+"return value of `select()` will be assigned a lifetime of B. This will in "
+"turn lead to a compilation error, because `select_based_on_unit_circle()` is "
+"supposed to return a value with the lifetime `r`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:622
+msgid ""
+"To address this, we can modify the definition of `select()` to distinguish "
+"the lifetime of the first parameter from the lifetime of the latter two. "
+"After all, the first parameter is not being returned. Here is how the new "
+"`select()` might look:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:636
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}; // as before\n"
+"# struct Size {w: float, h: float}; // as before\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),   // origin, radius\n"
+"#     Rectangle(Point, Size)  // upper-left, dimensions\n"
+"# }\n"
+"# fn compute_area(shape: &Shape) -> float { 0f }\n"
+"fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: float,\n"
+"                       a: &'r T, b: &'r T) -> &'r T {\n"
+"    if compute_area(shape) > threshold {a} else {b}\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:641
+msgid ""
+"Here you can see that `shape`'s lifetime is now named `tmp`. The parameters "
+"`a`, `b`, and the return value all have the lifetime `r`.  However, since "
+"the lifetime `tmp` is not returned, it would be more concise to just omit "
+"the named lifetime for `shape` altogether:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:655
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point {x: float, y: float}; // as before\n"
+"# struct Size {w: float, h: float}; // as before\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),   // origin, radius\n"
+"#     Rectangle(Point, Size)  // upper-left, dimensions\n"
+"# }\n"
+"# fn compute_area(shape: &Shape) -> float { 0f }\n"
+"fn select<'r, T>(shape: &Shape, threshold: float,\n"
+"                 a: &'r T, b: &'r T) -> &'r T {\n"
+"    if compute_area(shape) > threshold {a} else {b}\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:657
+msgid "This is equivalent to the previous definition."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:659
+msgid "# Conclusion"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-borrowed-ptr.md:663
+msgid ""
+"So there you have it: a (relatively) brief tour of the borrowed pointer "
+"system. For more details, we refer to the (yet to be written) reference "
+"document on borrowed pointers, which will explain the full notation and give "
+"more examples."
+msgstr ""
diff --git a/doc/po/ja/tutorial-container.md.po b/doc/po/ja/tutorial-container.md.po
new file mode 100644 (file)
index 0000000..9e6df68
--- /dev/null
@@ -0,0 +1,673 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-08-05 19:40+0900\n"
+"PO-Revision-Date: 2013-07-28 20:32+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. type: Plain text
+#: doc/tutorial-container.md:2
+msgid "% Containers and iterators"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:4
+msgid "# Containers"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:6
+msgid "The container traits are defined in the `std::container` module."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:8
+msgid "## Unique and managed vectors"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:12
+msgid ""
+"Vectors have `O(1)` indexing and removal from the end, along with `O(1)` "
+"amortized insertion. Vectors are the most common container in Rust, and are "
+"flexible enough to fit many use cases."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:16
+msgid ""
+"Vectors can also be sorted and used as efficient lookup tables with the "
+"`std::vec::bsearch` function, if all the elements are inserted at one time "
+"and deletions are unnecessary."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:18
+msgid "## Maps and sets"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:22
+msgid ""
+"Maps are collections of unique keys with corresponding values, and sets are "
+"just unique keys without a corresponding value. The `Map` and `Set` traits "
+"in `std::container` define the basic interface."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:24
+msgid "The standard library provides three owned map/set types:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:30
+msgid ""
+"`std::hashmap::HashMap` and `std::hashmap::HashSet`, requiring the keys to "
+"implement `Eq` and `Hash`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:30
+msgid ""
+"`std::trie::TrieMap` and `std::trie::TrieSet`, requiring the keys to be "
+"`uint`"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:30
+msgid ""
+"`extra::treemap::TreeMap` and `extra::treemap::TreeSet`, requiring the keys "
+"to implement `TotalOrd`"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:34
+msgid ""
+"These maps do not use managed pointers so they can be sent between tasks as "
+"long as the key and value types are sendable. Neither the key or value type "
+"has to be copyable."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:37
+msgid ""
+"The `TrieMap` and `TreeMap` maps are ordered, while `HashMap` uses an "
+"arbitrary order."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:42
+msgid ""
+"Each `HashMap` instance has a random 128-bit key to use with a keyed hash, "
+"making the order of a set of keys in a given hash table randomized. Rust "
+"provides a [SipHash](https://131002.net/siphash/) implementation for any "
+"type implementing the `IterBytes` trait."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:44
+msgid "## Double-ended queues"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:49
+msgid ""
+"The `extra::deque` module implements a double-ended queue with `O(1)` "
+"amortized inserts and removals from both ends of the container. It also has "
+"`O(1)` indexing like a vector. The contained elements are not required to be "
+"copyable, and the queue will be sendable if the contained type is sendable."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:51
+msgid "## Priority queues"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:55
+msgid ""
+"The `extra::priority_queue` module implements a queue ordered by a key.  The "
+"contained elements are not required to be copyable, and the queue will be "
+"sendable if the contained type is sendable."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:61
+msgid ""
+"Insertions have `O(log n)` time complexity and checking or popping the "
+"largest element is `O(1)`. Converting a vector to a priority queue can be "
+"done in-place, and has `O(n)` complexity. A priority queue can also be "
+"converted to a sorted vector in-place, allowing it to be used for an `O(n "
+"log n)` in-place heapsort."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:63
+msgid "# Iterators"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:65
+msgid "## Iteration protocol"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:69
+msgid ""
+"The iteration protocol is defined by the `Iterator` trait in the `std::"
+"iterator` module. The minimal implementation of the trait is a `next` "
+"method, yielding the next element from an iterator object:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:73
+msgid "~~~ /// An infinite stream of zeroes struct ZeroStream;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:80
+#, no-wrap
+msgid ""
+"impl Iterator<int> for ZeroStream {\n"
+"    fn next(&mut self) -> Option<int> {\n"
+"        Some(0)\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:83
+msgid ""
+"Reaching the end of the iterator is signalled by returning `None` instead of "
+"`Some(item)`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:89 doc/tutorial-container.md:262
+#, no-wrap
+msgid ""
+"~~~\n"
+"/// A stream of N zeroes\n"
+"struct ZeroStream {\n"
+"    priv remaining: uint\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:95
+#, no-wrap
+msgid ""
+"impl ZeroStream {\n"
+"    fn new(n: uint) -> ZeroStream {\n"
+"        ZeroStream { remaining: n }\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:107 doc/tutorial-container.md:284
+#, no-wrap
+msgid ""
+"impl Iterator<int> for ZeroStream {\n"
+"    fn next(&mut self) -> Option<int> {\n"
+"        if self.remaining == 0 {\n"
+"            None\n"
+"        } else {\n"
+"            self.remaining -= 1;\n"
+"            Some(0)\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:109
+msgid "## Container iterators"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:112
+msgid ""
+"Containers implement iteration over the contained elements by returning an "
+"iterator object. For example, vector slices several iterators available:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:116
+msgid "`iter()` and `rev_iter()`, for immutable references to the elements"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:116
+msgid ""
+"`mut_iter()` and `mut_rev_iter()`, for mutable references to the elements"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-container.md:116
+msgid ""
+"`consume_iter()` and `consume_rev_iter`, to move the elements out by-value"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:119
+msgid ""
+"A typical mutable container will implement at least `iter()`, `mut_iter()` "
+"and `consume_iter()` along with the reverse variants if it maintains an "
+"order."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:121
+msgid "### Freezing"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:125
+msgid ""
+"Unlike most other languages with external iterators, Rust has no *iterator "
+"invalidation*. As long an iterator is still in scope, the compiler will "
+"prevent modification of the container through another handle."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:130
+#, no-wrap
+msgid ""
+"~~~\n"
+"let mut xs = [1, 2, 3];\n"
+"{\n"
+"    let _it = xs.iter();\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:136
+#, no-wrap
+msgid ""
+"    // the vector is frozen for this scope, the compiler will statically\n"
+"    // prevent modification\n"
+"}\n"
+"// the vector becomes unfrozen again at the end of the scope\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:139
+msgid ""
+"These semantics are due to most container iterators being implemented with "
+"`&` and `&mut`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:141
+msgid "## Iterator adaptors"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:145
+msgid ""
+"The `IteratorUtil` trait implements common algorithms as methods extending "
+"every `Iterator` implementation. For example, the `fold` method will "
+"accumulate the items yielded by an `Iterator` into a single value:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:151
+msgid ""
+"~~~ let xs = [1, 9, 2, 3, 14, 12]; let result = xs.iter().fold(0, |"
+"accumulator, item| accumulator - *item); assert_eq!(result, -41); ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:153
+msgid ""
+"Some adaptors return an adaptor object implementing the `Iterator` trait "
+"itself:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:160
+msgid ""
+"~~~ let xs = [1, 9, 2, 3, 14, 12]; let ys = [5, 2, 1, 8]; let sum = xs."
+"iter().chain_(ys.iter()).fold(0, |a, b| a + *b); assert_eq!(sum, 57); ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:164
+msgid ""
+"Note that some adaptors like the `chain_` method above use a trailing "
+"underscore to work around an issue with method resolve. The underscores will "
+"be dropped when they become unnecessary."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:166
+msgid "## For loops"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:168
+msgid ""
+"The `for` keyword can be used as sugar for iterating through any iterator:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:171
+msgid "~~~ let xs = [2, 3, 5, 7, 11, 13, 17];"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:176
+#, no-wrap
+msgid ""
+"// print out all the elements in the vector\n"
+"for x in xs.iter() {\n"
+"    println(x.to_str())\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:182
+#, no-wrap
+msgid ""
+"// print out all but the first 3 elements in the vector\n"
+"for x in xs.iter().skip(3) {\n"
+"    println(x.to_str())\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:185
+msgid ""
+"For loops are *often* used with a temporary iterator object, as above. They "
+"can also advance the state of an iterator in a mutable location:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:189
+msgid ""
+"~~~ let xs = [1, 2, 3, 4, 5]; let ys = [\"foo\", \"bar\", \"baz\", \"foobar"
+"\"];"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:192
+msgid ""
+"// create an iterator yielding tuples of elements from both vectors let mut "
+"it = xs.iter().zip(ys.iter());"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:196
+#, no-wrap
+msgid ""
+"// print out the pairs of elements up to (&3, &\"baz\")\n"
+"for (x, y) in it {\n"
+"    printfln!(\"%d %s\", *x, *y);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:201
+#, no-wrap
+msgid ""
+"    if *x == 3 {\n"
+"        break;\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:204
+msgid ""
+"// yield and print the last pair from the iterator printfln!(\"last: %?\", "
+"it.next());"
+msgstr ""
+
+#. type: Plain text
+#: 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<A, T: Iterator<A>> FromIterator<A, T> 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 x in iterator {\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<uint>) { (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<uint>) {\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(); printfln!(\"%?\", "
+"it.next()); // prints `Some(&1)` printfln!(\"%?\", it.next()); // prints "
+"`Some(&2)` printfln!(\"%?\", 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 &x in it.invert() {\n"
+"    printfln!(\"%?\", x)\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:309
+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 ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:312
+msgid ""
+"The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are "
+"`DoubleEndedIterator` implementations if the underlying iterators are."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:317
+msgid ""
+"~~~ let xs = [1, 2, 3, 4]; let ys = [5, 6, 7, 8]; let mut it = xs.iter()."
+"chain_(ys.iter()).transform(|&x| x * 2);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:319
+msgid "printfln!(\"%?\", it.next()); // prints `Some(2)`"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:325
+#, no-wrap
+msgid ""
+"// prints `16`, `14`, `12`, `10`, `8`, `6`, `4`\n"
+"for x in it.invert() {\n"
+"    printfln!(\"%?\", x);\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:327
+msgid "## Random-access iterators"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:331
+msgid ""
+"The `RandomAccessIterator` trait represents an iterator offering random "
+"access to the whole range. The `indexable` method retrieves the number of "
+"elements accessible with the `idx` method."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:334
+msgid ""
+"The `chain_` adaptor is an implementation of `RandomAccessIterator` if the "
+"underlying iterators are."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:343
+msgid ""
+"~~~ let xs = [1, 2, 3, 4, 5]; let ys = ~[7, 9, 11]; let mut it = xs.iter()."
+"chain_(ys.iter()); printfln!(\"%?\", it.idx(0)); // prints `Some(&1)` "
+"printfln!(\"%?\", it.idx(5)); // prints `Some(&7)` printfln!(\"%?\", it."
+"idx(7)); // prints `Some(&11)` printfln!(\"%?\", it.idx(8)); // prints `None`"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:348
+msgid ""
+"// yield two elements from the beginning, and one from the end it.next(); it."
+"next(); it.next_back();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:352
+msgid ""
+"printfln!(\"%?\", it.idx(0)); // prints `Some(&3)` printfln!(\"%?\", it."
+"idx(4)); // prints `Some(&9)` printfln!(\"%?\", it.idx(6)); // prints `None` "
+"~~~"
+msgstr ""
diff --git a/doc/po/ja/tutorial-ffi.md.po b/doc/po/ja/tutorial-ffi.md.po
new file mode 100644 (file)
index 0000000..8b1c4c6
--- /dev/null
@@ -0,0 +1,602 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-08-10 07:44+0900\n"
+"PO-Revision-Date: 2013-07-22 23:37+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/tutorial.md:868 doc/tutorial-ffi.md:143
+msgid "# Destructors"
+msgstr "# デストラクタ"
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:2
+msgid "% Rust Foreign Function Interface Tutorial"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:10
+msgid ""
+"This tutorial will use the [snappy](https://code.google.com/p/snappy/)  "
+"compression/decompression library as an introduction to writing bindings for "
+"foreign code. Rust is currently unable to call directly into a C++ library, "
+"but snappy includes a C interface (documented in [`snappy-c.h`](https://code."
+"google.com/p/snappy/source/browse/trunk/snappy-c.h))."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:13
+msgid ""
+"The following is a minimal example of calling a foreign function which will "
+"compile if snappy is installed:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:16
+msgid "~~~~ {.xfail-test} use std::libc::size_t;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:21
+#, no-wrap
+msgid ""
+"#[link_args = \"-lsnappy\"]\n"
+"extern {\n"
+"    fn snappy_max_compressed_length(source_length: size_t) -> size_t;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:27
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    let x = unsafe { snappy_max_compressed_length(100) };\n"
+"    println(fmt!(\"max compressed length of a 100 byte buffer: %?\", x));\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:31
+msgid ""
+"The `extern` block is a list of function signatures in a foreign library, in "
+"this case with the platform's C ABI. The `#[link_args]` attribute is used to "
+"instruct the linker to link against the snappy library so the symbols are "
+"resolved."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:37
+msgid ""
+"Foreign functions are assumed to be unsafe so calls to them need to be "
+"wrapped with `unsafe {}` as a promise to the compiler that everything "
+"contained within truly is safe. C libraries often expose interfaces that "
+"aren't thread-safe, and almost any function that takes a pointer argument "
+"isn't valid for all possible inputs since the pointer could be dangling, and "
+"raw pointers fall outside of Rust's safe memory model."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:41
+msgid ""
+"When declaring the argument types to a foreign function, the Rust compiler "
+"will not check if the declaration is correct, so specifying it correctly is "
+"part of keeping the binding correct at runtime."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:43
+msgid "The `extern` block can be extended to cover the entire snappy API:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:46
+msgid "~~~~ {.xfail-test} use std::libc::{c_int, size_t};"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:65
+#, no-wrap
+msgid ""
+"#[link_args = \"-lsnappy\"]\n"
+"extern {\n"
+"    fn snappy_compress(input: *u8,\n"
+"                       input_length: size_t,\n"
+"                       compressed: *mut u8,\n"
+"                       compressed_length: *mut size_t) -> c_int;\n"
+"    fn snappy_uncompress(compressed: *u8,\n"
+"                         compressed_length: size_t,\n"
+"                         uncompressed: *mut u8,\n"
+"                         uncompressed_length: *mut size_t) -> c_int;\n"
+"    fn snappy_max_compressed_length(source_length: size_t) -> size_t;\n"
+"    fn snappy_uncompressed_length(compressed: *u8,\n"
+"                                  compressed_length: size_t,\n"
+"                                  result: *mut size_t) -> c_int;\n"
+"    fn snappy_validate_compressed_buffer(compressed: *u8,\n"
+"                                         compressed_length: size_t) -> c_int;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:67
+msgid "# Creating a safe interface"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:71
+msgid ""
+"The raw C API needs to be wrapped to provide memory safety and make use of "
+"higher-level concepts like vectors. A library can choose to expose only the "
+"safe, high-level interface and hide the unsafe internal details."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:76
+msgid ""
+"Wrapping the functions which expect buffers involves using the `vec::raw` "
+"module to manipulate Rust vectors as pointers to memory. Rust's vectors are "
+"guaranteed to be a contiguous block of memory. The length is number of "
+"elements currently contained, and the capacity is the total size in elements "
+"of the allocated memory. The length is less than or equal to the capacity."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:84
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"pub fn validate_compressed_buffer(src: &[u8]) -> bool {\n"
+"    unsafe {\n"
+"        snappy_validate_compressed_buffer(vec::raw::to_ptr(src), src.len() as size_t) == 0\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:88
+msgid ""
+"The `validate_compressed_buffer` wrapper above makes use of an `unsafe` "
+"block, but it makes the guarantee that calling it is safe for all inputs by "
+"leaving off `unsafe` from the function signature."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:91
+msgid ""
+"The `snappy_compress` and `snappy_uncompress` functions are more complex, "
+"since a buffer has to be allocated to hold the output too."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:96
+msgid ""
+"The `snappy_max_compressed_length` function can be used to allocate a vector "
+"with the maximum required capacity to hold the compressed output. The vector "
+"can then be passed to the `snappy_compress` function as an output parameter. "
+"An output parameter is also passed to retrieve the true length after "
+"compression for setting the length."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:102
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"pub fn compress(src: &[u8]) -> ~[u8] {\n"
+"    unsafe {\n"
+"        let srclen = src.len() as size_t;\n"
+"        let psrc = vec::raw::to_ptr(src);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:106
+#, no-wrap
+msgid ""
+"        let mut dstlen = snappy_max_compressed_length(srclen);\n"
+"        let mut dst = vec::with_capacity(dstlen as uint);\n"
+"        let pdst = vec::raw::to_mut_ptr(dst);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:113
+#, no-wrap
+msgid ""
+"        snappy_compress(psrc, srclen, pdst, &mut dstlen);\n"
+"        vec::raw::set_len(&mut dst, dstlen as uint);\n"
+"        dst\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:116
+msgid ""
+"Decompression is similar, because snappy stores the uncompressed size as "
+"part of the compression format and `snappy_uncompressed_length` will "
+"retrieve the exact buffer size required."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:122
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"pub fn uncompress(src: &[u8]) -> Option<~[u8]> {\n"
+"    unsafe {\n"
+"        let srclen = src.len() as size_t;\n"
+"        let psrc = vec::raw::to_ptr(src);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:125
+#, no-wrap
+msgid ""
+"        let mut dstlen: size_t = 0;\n"
+"        snappy_uncompressed_length(psrc, srclen, &mut dstlen);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:128
+#, no-wrap
+msgid ""
+"        let mut dst = vec::with_capacity(dstlen as uint);\n"
+"        let pdst = vec::raw::to_mut_ptr(dst);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:138
+#, no-wrap
+msgid ""
+"        if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {\n"
+"            vec::raw::set_len(&mut dst, dstlen as uint);\n"
+"            Some(dst)\n"
+"        } else {\n"
+"            None // SNAPPY_INVALID_INPUT\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:141
+msgid ""
+"For reference, the examples used here are also available as an [library on "
+"GitHub](https://github.com/thestinger/rust-snappy)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:147
+msgid ""
+"Foreign libraries often hand off ownership of resources to the calling code, "
+"which should be wrapped in a destructor to provide safety and guarantee "
+"their release."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:150
+msgid ""
+"A type with the same functionality as owned boxes can be implemented by "
+"wrapping `malloc` and `free`:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:156
+msgid ""
+"~~~~ use std::cast; use std::libc::{c_void, size_t, malloc, free}; use std::"
+"ptr; use std::unstable::intrinsics;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:161
+#, no-wrap
+msgid ""
+"// a wrapper around the handle returned by the foreign code\n"
+"pub struct Unique<T> {\n"
+"    priv ptr: *mut T\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:172
+#, no-wrap
+msgid ""
+"impl<T: Send> Unique<T> {\n"
+"    pub fn new(value: T) -> Unique<T> {\n"
+"        unsafe {\n"
+"            let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;\n"
+"            assert!(!ptr::is_null(ptr));\n"
+"            // `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it\n"
+"            intrinsics::move_val_init(&mut *ptr, value);\n"
+"            Unique{ptr: ptr}\n"
+"        }\n"
+"    }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:177
+#, no-wrap
+msgid ""
+"    // the 'r lifetime results in the same semantics as `&*x` with ~T\n"
+"    pub fn borrow<'r>(&'r self) -> &'r T {\n"
+"        unsafe { cast::copy_lifetime(self, &*self.ptr) }\n"
+"    }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:183
+#, no-wrap
+msgid ""
+"    // the 'r lifetime results in the same semantics as `&mut *x` with ~T\n"
+"    pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {\n"
+"        unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) }\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:195
+#, no-wrap
+msgid ""
+"#[unsafe_destructor]\n"
+"impl<T: Send> Drop for Unique<T> {\n"
+"    fn drop(&self) {\n"
+"        unsafe {\n"
+"            let x = intrinsics::init(); // dummy value to swap in\n"
+"            // moving the object out is needed to call the destructor\n"
+"            ptr::replace_ptr(self.ptr, x);\n"
+"            free(self.ptr as *c_void)\n"
+"        }\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:202
+#, no-wrap
+msgid ""
+"// A comparison between the built-in ~ and this reimplementation\n"
+"fn main() {\n"
+"    {\n"
+"        let mut x = ~5;\n"
+"        *x = 10;\n"
+"    } // `x` is freed here\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:209
+#, no-wrap
+msgid ""
+"    {\n"
+"        let mut y = Unique::new(5);\n"
+"        *y.borrow_mut() = 10;\n"
+"    } // `y` is freed here\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:211
+msgid "# Linking"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:215
+msgid ""
+"In addition to the `#[link_args]` attribute for explicitly passing arguments "
+"to the linker, an `extern mod` block will pass `-lmodname` to the linker by "
+"default unless it has a `#[nolink]` attribute applied."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:217
+msgid "# Unsafe blocks"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:221
+msgid ""
+"Some operations, like dereferencing unsafe pointers or calling functions "
+"that have been marked unsafe are only allowed inside unsafe blocks. Unsafe "
+"blocks isolate unsafety and are a promise to the compiler that the unsafety "
+"does not leak out of the block."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:224
+msgid ""
+"Unsafe functions, on the other hand, advertise it to the world. An unsafe "
+"function is written like this:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:228
+msgid "~~~~ unsafe fn kaboom(ptr: *int) -> int { *ptr } ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:230
+msgid ""
+"This function can only be called from an `unsafe` block or another `unsafe` "
+"function."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:232
+msgid "# Accessing foreign globals"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:236
+msgid ""
+"Foreign APIs often export a global variable which could do something like "
+"track global state. In order to access these variables, you declare them in "
+"`extern` blocks with the `static` keyword:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:239
+msgid "~~~{.xfail-test} use std::libc;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:244
+#, no-wrap
+msgid ""
+"#[link_args = \"-lreadline\"]\n"
+"extern {\n"
+"    static rl_readline_version: libc::c_int;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:250
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    println(fmt!(\"You have readline version %d installed.\",\n"
+"                 rl_readline_version as int));\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:254
+msgid ""
+"Alternatively, you may need to alter global state provided by a foreign "
+"interface. To do this, statics can be declared with `mut` so rust can mutate "
+"them."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:258
+msgid "~~~{.xfail-test} use std::libc; use std::ptr;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:263
+#, no-wrap
+msgid ""
+"#[link_args = \"-lreadline\"]\n"
+"extern {\n"
+"    static mut rl_prompt: *libc::c_char;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:272
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    do \"[my-awesome-shell] $\".as_c_str |buf| {\n"
+"        unsafe { rl_prompt = buf; }\n"
+"        // get a line, process it\n"
+"        unsafe { rl_prompt = ptr::null(); }\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:274
+msgid "# Foreign calling conventions"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:279
+msgid ""
+"Most foreign code exposes a C ABI, and Rust uses the platform's C calling "
+"convention by default when calling foreign functions. Some foreign "
+"functions, most notably the Windows API, use other calling conventions. Rust "
+"provides the `abi` attribute as a way to hint to the compiler which calling "
+"convention to use:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:288
+#, no-wrap
+msgid ""
+"~~~~\n"
+"#[cfg(target_os = \"win32\")]\n"
+"#[abi = \"stdcall\"]\n"
+"#[link_name = \"kernel32\"]\n"
+"extern {\n"
+"    fn SetEnvironmentVariableA(n: *u8, v: *u8) -> int;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:292
+msgid ""
+"The `abi` attribute applies to a foreign module (it cannot be applied to a "
+"single function within a module), and must be either `\"cdecl\"` or `"
+"\"stdcall\"`. The compiler may eventually support other calling conventions."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:294
+msgid "# Interoperability with foreign code"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:298
+msgid ""
+"Rust guarantees that the layout of a `struct` is compatible with the "
+"platform's representation in C.  A `#[packed]` attribute is available, which "
+"will lay out the struct members without padding.  However, there are "
+"currently no guarantees about the layout of an `enum`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:305
+msgid ""
+"Rust's owned and managed boxes use non-nullable pointers as handles which "
+"point to the contained object. However, they should not be manually created "
+"because they are managed by internal allocators. Borrowed pointers can "
+"safely be assumed to be non-nullable pointers directly to the type. However, "
+"breaking the borrow checking or mutability rules is not guaranteed to be "
+"safe, so prefer using raw pointers (`*`) if that's needed because the "
+"compiler can't make as many assumptions about them."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:310
+msgid ""
+"Vectors and strings share the same basic memory layout, and utilities are "
+"available in the `vec` and `str` modules for working with C APIs. Strings "
+"are terminated with `\\0` for interoperability with C, but it should not be "
+"assumed because a slice will not always be nul-terminated. Instead, the "
+"`str::as_c_str` function should be used."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:312
+msgid ""
+"The standard library includes type aliases and function definitions for the "
+"C standard library in the `libc` module, and Rust links against `libc` and "
+"`libm` by default."
+msgstr ""
diff --git a/doc/po/ja/tutorial-macros.md.po b/doc/po/ja/tutorial-macros.md.po
new file mode 100644 (file)
index 0000000..2ca6a26
--- /dev/null
@@ -0,0 +1,683 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-07-28 20:32+0900\n"
+"PO-Revision-Date: 2013-07-28 20:32+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/rust.md:2136 doc/rust.md:2223 doc/tutorial-macros.md:323
+msgid "~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:2
+msgid "% Rust Macros Tutorial"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:12
+msgid ""
+"Functions are the primary tool that programmers can use to build "
+"abstractions.  Sometimes, however, programmers want to abstract over compile-"
+"time syntax rather than run-time values.  Macros provide syntactic "
+"abstraction.  For an example of how this can be useful, consider the "
+"following two code fragments, which both pattern-match on their input and "
+"both return early in one case, doing nothing otherwise:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:30
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum t { special_a(uint), special_b(uint) };\n"
+"# fn f() -> uint {\n"
+"# let input_1 = special_a(0);\n"
+"# let input_2 = special_a(0);\n"
+"match input_1 {\n"
+"    special_a(x) => { return x; }\n"
+"    _ => {}\n"
+"}\n"
+"// ...\n"
+"match input_2 {\n"
+"    special_b(x) => { return x; }\n"
+"    _ => {}\n"
+"}\n"
+"# return 0u;\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:38
+msgid ""
+"This code could become tiresome if repeated many times.  However, no "
+"function can capture its functionality to make it possible to abstract the "
+"repetition away.  Rust's macro system, however, can eliminate the "
+"repetition. Macros are lightweight custom syntax extensions, themselves "
+"defined using the `macro_rules!` syntax extension. The following "
+"`early_return` macro captures the pattern in the above code:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:59
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum t { special_a(uint), special_b(uint) };\n"
+"# fn f() -> uint {\n"
+"# let input_1 = special_a(0);\n"
+"# let input_2 = special_a(0);\n"
+"macro_rules! early_return(\n"
+"    ($inp:expr $sp:ident) => ( // invoke it like `(input_5 special_e)`\n"
+"        match $inp {\n"
+"            $sp(x) => { return x; }\n"
+"            _ => {}\n"
+"        }\n"
+"    );\n"
+")\n"
+"// ...\n"
+"early_return!(input_1 special_a);\n"
+"// ...\n"
+"early_return!(input_2 special_b);\n"
+"# return 0;\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:65
+msgid ""
+"Macros are defined in pattern-matching style: in the above example, the text "
+"`($inp:expr $sp:ident)` that appears on the left-hand side of the `=>` is "
+"the *macro invocation syntax*, a pattern denoting how to write a call to the "
+"macro. The text on the right-hand side of the `=>`, beginning with `match "
+"$inp`, is the *macro transcription syntax*: what the macro expands to."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:67
+msgid "# Invocation syntax"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:71
+msgid ""
+"The macro invocation syntax specifies the syntax for the arguments to the "
+"macro. It appears on the left-hand side of the `=>` in a macro definition. "
+"It conforms to the following rules:"
+msgstr ""
+
+#. type: Bullet: '1. '
+#: doc/tutorial-macros.md:76
+msgid "It must be surrounded by parentheses."
+msgstr ""
+
+#. type: Bullet: '2. '
+#: doc/tutorial-macros.md:76
+msgid "`$` has special meaning (described below)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:76
+#, no-wrap
+msgid ""
+"3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is\n"
+"forbidden.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:78
+msgid "Otherwise, the invocation syntax is free-form."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:83
+#, no-wrap
+msgid ""
+"To take as an argument a fragment of Rust code, write `$` followed by a name\n"
+" (for use on the right-hand side), followed by a `:`, followed by a *fragment\n"
+" specifier*. The fragment specifier denotes the sort of fragment to match. The\n"
+" most common fragment specifiers are:\n"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-macros.md:92
+msgid ""
+"`ident` (an identifier, referring to a variable or item. Examples: `f`, `x`, "
+"`foo`.)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-macros.md:92
+msgid ""
+"`expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; "
+"`f(42)`.)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-macros.md:92
+msgid "`ty` (a type. Examples: `int`, `~[(char, ~str)]`, `&T`.)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-macros.md:92
+msgid ""
+"`pat` (a pattern, usually appearing in a `match` or on the left-hand side of "
+"a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.)"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-macros.md:92
+msgid ""
+"`block` (a sequence of actions. Example: `{ log(error, \"hi\"); return 12; }"
+"`)"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:95
+msgid ""
+"The parser interprets any token that's not preceded by a `$` literally. "
+"Rust's usual rules of tokenization apply,"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:98
+msgid ""
+"So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a "
+"macro that could be invoked like: `my_macro!(i->(( 2+2 )))`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:100
+msgid "## Invocation location"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:105
+msgid ""
+"A macro invocation may take the place of (and therefore expand to)  an "
+"expression, an item, or a statement.  The Rust parser will parse the macro "
+"invocation as a \"placeholder\" for whichever of those three nonterminals is "
+"appropriate for the location."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:112
+msgid ""
+"At expansion time, the output of the macro will be parsed as whichever of "
+"the three nonterminals it stands in for. This means that a single macro "
+"might, for example, expand to an item or an expression, depending on its "
+"arguments (and cause a syntax error if it is called with the wrong argument "
+"for its location). Although this behavior sounds excessively dynamic, it is "
+"known to be useful under some circumstances."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:115
+msgid "# Transcription syntax"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:119
+msgid ""
+"The right-hand side of the `=>` follows the same rules as the left-hand "
+"side, except that a `$` need only be followed by the name of the syntactic "
+"fragment to transcribe into the macro expansion; its type need not be "
+"repeated."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:126
+msgid ""
+"The right-hand side must be enclosed by delimiters, which the transcriber "
+"ignores.  Therefore `() => ((1,2,3))` is a macro that expands to a tuple "
+"expression, `() => (let $x=$val)` is a macro that expands to a statement, "
+"and `() => (1,2,3)` is a macro that expands to a syntax error (since the "
+"transcriber interprets the parentheses on the right-hand-size as delimiters, "
+"and `1,2,3` is not a valid Rust expression on its own)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:133
+msgid ""
+"Except for permissibility of `$name` (and `$(...)*`, discussed below), the "
+"right-hand side of a macro definition is ordinary Rust syntax. In "
+"particular, macro invocations (including invocations of the macro currently "
+"being defined)  are permitted in expression, statement, and item locations. "
+"However, nothing else about the code is examined or executed by the macro "
+"system; execution still has to wait until run-time."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:135
+msgid "## Interpolation location"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:139
+msgid ""
+"The interpolation `$argument_name` may appear in any location consistent "
+"with its fragment specifier (i.e., if it is specified as `ident`, it may be "
+"used anywhere an identifier is permitted)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:141
+msgid "# Multiplicity"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:143
+msgid "## Invocation"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:150
+msgid ""
+"Going back to the motivating example, recall that `early_return` expanded "
+"into a `match` that would `return` if the `match`'s scrutinee matched the "
+"\"special case\" identifier provided as the second argument to "
+"`early_return`, and do nothing otherwise. Now suppose that we wanted to "
+"write a version of `early_return` that could handle a variable number of "
+"\"special\" cases."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:156
+msgid ""
+"The syntax `$(...)*` on the left-hand side of the `=>` in a macro definition "
+"accepts zero or more occurrences of its contents. It works much like the `*` "
+"operator in regular expressions. It also supports a separator token (a comma-"
+"separated list could be written `$(...),*`), and `+` instead of `*` to mean "
+"\"at least one\"."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:179
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum t { special_a(uint),special_b(uint),special_c(uint),special_d(uint)};\n"
+"# fn f() -> uint {\n"
+"# let input_1 = special_a(0);\n"
+"# let input_2 = special_a(0);\n"
+"macro_rules! early_return(\n"
+"    ($inp:expr, [ $($sp:ident)|+ ]) => (\n"
+"        match $inp {\n"
+"            $(\n"
+"                $sp(x) => { return x; }\n"
+"            )+\n"
+"            _ => {}\n"
+"        }\n"
+"    );\n"
+")\n"
+"// ...\n"
+"early_return!(input_1, [special_a|special_c|special_d]);\n"
+"// ...\n"
+"early_return!(input_2, [special_b]);\n"
+"# return 0;\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:181
+msgid "### Transcription"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:191
+msgid ""
+"As the above example demonstrates, `$(...)*` is also valid on the right-hand "
+"side of a macro definition. The behavior of `*` in transcription, especially "
+"in cases where multiple `*`s are nested, and multiple different names are "
+"involved, can seem somewhat magical and intuitive at first. The system that "
+"interprets them is called \"Macro By Example\". The two rules to keep in "
+"mind are (1) the behavior of `$(...)*` is to walk through one \"layer\" of "
+"repetitions for all of the `$name`s it contains in lockstep, and (2) each `"
+"$name` must be under at least as many `$(...)*`s as it was matched against.  "
+"If it is under more, it'll be repeated, as appropriate."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:193
+msgid "## Parsing limitations"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:197
+msgid ""
+"For technical reasons, there are two limitations to the treatment of syntax "
+"fragments by the macro parser:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:210
+#, no-wrap
+msgid ""
+"1. The parser will always parse as much as possible of a Rust syntactic\n"
+"fragment. For example, if the comma were omitted from the syntax of\n"
+"`early_return!` above, `input_1 [` would've been interpreted as the beginning\n"
+"of an array index. In fact, invoking the macro would have been impossible.\n"
+"2. The parser must have eliminated all ambiguity by the time it reaches a\n"
+"`$name:fragment_specifier` declaration. This limitation can result in parse\n"
+"errors when declarations occur at the beginning of, or immediately after,\n"
+"a `$(...)*`. For example, the grammar `$($t:ty)* $e:expr` will always fail to\n"
+"parse because the parser would be forced to choose between parsing `t` and\n"
+"parsing `e`. Changing the invocation syntax to require a distinctive token in\n"
+"front can solve the problem. In the above example, `$(T $t:ty)* E $e:exp`\n"
+"solves the problem.\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:212
+msgid "# Macro argument pattern matching"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:214
+msgid "Now consider code like the following:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:216
+msgid "## Motivation"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:236
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum t1 { good_1(t2, uint), bad_1 };\n"
+"# pub struct t2 { body: t3 }\n"
+"# enum t3 { good_2(uint), bad_2};\n"
+"# fn f(x: t1) -> uint {\n"
+"match x {\n"
+"    good_1(g1, val) => {\n"
+"        match g1.body {\n"
+"            good_2(result) => {\n"
+"                // complicated stuff goes here\n"
+"                return result + val;\n"
+"            },\n"
+"            _ => fail!(\"Didn't get good_2\")\n"
+"        }\n"
+"    }\n"
+"    _ => return 0 // default value\n"
+"}\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:241
+msgid ""
+"All the complicated stuff is deeply indented, and the error-handling code is "
+"separated from matches that fail. We'd like to write a macro that performs a "
+"match, but with a syntax that suits the problem better. The following macro "
+"can solve the problem:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:263
+#, no-wrap
+msgid ""
+"~~~~\n"
+"macro_rules! biased_match (\n"
+"    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead\n"
+"    ( ($e:expr) ~ ($p:pat) else $err:stmt ;\n"
+"      binds $bind_res:ident\n"
+"    ) => (\n"
+"        let $bind_res = match $e {\n"
+"            $p => ( $bind_res ),\n"
+"            _ => { $err }\n"
+"        };\n"
+"    );\n"
+"    // more than one name; use a tuple\n"
+"    ( ($e:expr) ~ ($p:pat) else $err:stmt ;\n"
+"      binds $( $bind_res:ident ),*\n"
+"    ) => (\n"
+"        let ( $( $bind_res ),* ) = match $e {\n"
+"            $p => ( $( $bind_res ),* ),\n"
+"            _ => { $err }\n"
+"        };\n"
+"    )\n"
+")\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:277
+#, no-wrap
+msgid ""
+"# enum t1 { good_1(t2, uint), bad_1 };\n"
+"# pub struct t2 { body: t3 }\n"
+"# enum t3 { good_2(uint), bad_2};\n"
+"# fn f(x: t1) -> uint {\n"
+"biased_match!((x)       ~ (good_1(g1, val)) else { return 0 };\n"
+"              binds g1, val )\n"
+"biased_match!((g1.body) ~ (good_2(result) )\n"
+"                  else { fail!(\"Didn't get good_2\") };\n"
+"              binds result )\n"
+"// complicated stuff goes here\n"
+"return result + val;\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:288
+#, no-wrap
+msgid ""
+"This solves the indentation problem. But if we have a lot of chained matches\n"
+"like this, we might prefer to write a single macro invocation. The input\n"
+"pattern we want is clear:\n"
+"~~~~\n"
+"# macro_rules! b(\n"
+"    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
+"      binds $( $bind_res:ident ),*\n"
+"    )\n"
+"# => (0))\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:291
+msgid ""
+"However, it's not possible to directly expand to nested match statements. "
+"But there is a solution."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:293
+msgid "## The recursive approach to macro writing"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:297
+msgid ""
+"A macro may accept multiple different input grammars. The first one to "
+"successfully match the actual argument to a macro invocation is the one that "
+"\"wins\"."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:301
+msgid ""
+"In the case of the example above, we want to write a recursive macro to "
+"process the semicolon-terminated lines, one-by-one. So, we want the "
+"following input patterns:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:308
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# macro_rules! b(\n"
+"    ( binds $( $bind_res:ident ),* )\n"
+"# => (0))\n"
+"~~~~\n"
+"...and:\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:317
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# macro_rules! b(\n"
+"    (    ($e     :expr) ~ ($p     :pat) else $err     :stmt ;\n"
+"      $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*\n"
+"      binds  $( $bind_res:ident ),*\n"
+"    )\n"
+"# => (0))\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:321
+msgid ""
+"The resulting macro looks like this. Note that the separation into "
+"`biased_match!` and `biased_match_rec!` occurs only because we have an outer "
+"piece of syntax (the `let`) which we only want to transcribe once."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:342
+#, no-wrap
+msgid ""
+"macro_rules! biased_match_rec (\n"
+"    // Handle the first layer\n"
+"    (   ($e     :expr) ~ ($p     :pat) else $err     :stmt ;\n"
+"     $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*\n"
+"     binds $( $bind_res:ident ),*\n"
+"    ) => (\n"
+"        match $e {\n"
+"            $p => {\n"
+"                // Recursively handle the next layer\n"
+"                biased_match_rec!($( ($e_rest) ~ ($p_rest) else $err_rest ; )*\n"
+"                                  binds $( $bind_res ),*\n"
+"                )\n"
+"            }\n"
+"            _ => { $err }\n"
+"        }\n"
+"    );\n"
+"    ( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )\n"
+")\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:364
+#, no-wrap
+msgid ""
+"// Wrap the whole thing in a `let`.\n"
+"macro_rules! biased_match (\n"
+"    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead\n"
+"    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
+"      binds $bind_res:ident\n"
+"    ) => (\n"
+"        let ( $( $bind_res ),* ) = biased_match_rec!(\n"
+"            $( ($e) ~ ($p) else $err ; )*\n"
+"            binds $bind_res\n"
+"        );\n"
+"    );\n"
+"    // more than one name: use a tuple\n"
+"    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
+"      binds  $( $bind_res:ident ),*\n"
+"    ) => (\n"
+"        let ( $( $bind_res ),* ) = biased_match_rec!(\n"
+"            $( ($e) ~ ($p) else $err ; )*\n"
+"            binds $( $bind_res ),*\n"
+"        );\n"
+"    )\n"
+")\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:378
+#, no-wrap
+msgid ""
+"# enum t1 { good_1(t2, uint), bad_1 };\n"
+"# pub struct t2 { body: t3 }\n"
+"# enum t3 { good_2(uint), bad_2};\n"
+"# fn f(x: t1) -> uint {\n"
+"biased_match!(\n"
+"    (x)       ~ (good_1(g1, val)) else { return 0 };\n"
+"    (g1.body) ~ (good_2(result) ) else { fail!(\"Didn't get good_2\") };\n"
+"    binds val, result )\n"
+"// complicated stuff goes here\n"
+"return result + val;\n"
+"# }\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:382
+msgid ""
+"This technique applies to many cases where transcribing a result all at once "
+"is not possible.  The resulting code resembles ordinary functional "
+"programming in some respects, but has some important differences from "
+"functional programming."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:390
+msgid ""
+"The first difference is important, but also easy to forget: the "
+"transcription (right-hand) side of a `macro_rules!` rule is literal syntax, "
+"which can only be executed at run-time. If a piece of transcription syntax "
+"does not itself appear inside another macro invocation, it will become part "
+"of the final program. If it is inside a macro invocation (for example, the "
+"recursive invocation of `biased_match_rec!`), it does have the opportunity "
+"to affect transcription, but only through the process of attempted pattern "
+"matching."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:398
+msgid ""
+"The second, related, difference is that the evaluation order of macros feels "
+"\"backwards\" compared to ordinary programming. Given an invocation `m1!(m2!"
+"())`, the expander first expands `m1!`, giving it as input the literal "
+"syntax `m2!()`. If it transcribes its argument unchanged into an appropriate "
+"position (in particular, not as an argument to yet another macro "
+"invocation), the expander will then proceed to evaluate `m2!()` (along with "
+"any other macro invocations `m1!(m2!())` produced)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:400
+msgid "# A final note"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-macros.md:407
+msgid ""
+"Macros, as currently implemented, are not for the faint of heart. Even "
+"ordinary syntax errors can be more difficult to debug when they occur inside "
+"a macro, and errors caused by parse problems in generated code can be very "
+"tricky. Invoking the `log_syntax!` macro can help elucidate intermediate "
+"states, invoking `trace_macros!(true)` will automatically print those "
+"intermediate states out, and passing the flag `--pretty expanded` as a "
+"command-line argument to the compiler will show the result of expansion."
+msgstr ""
diff --git a/doc/po/ja/tutorial-tasks.md.po b/doc/po/ja/tutorial-tasks.md.po
new file mode 100644 (file)
index 0000000..8566b71
--- /dev/null
@@ -0,0 +1,1070 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-08-08 22:27+0900\n"
+"PO-Revision-Date: 2013-07-28 20:32+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/rust.md:1952 doc/tutorial-tasks.md:648
+msgid "# } ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:2
+msgid "% Rust Tasks and Communication Tutorial"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:10
+msgid ""
+"Rust provides safe concurrency through a combination of lightweight, memory-"
+"isolated tasks and message passing.  This tutorial will describe the "
+"concurrency model in Rust, how it relates to the Rust type system, and "
+"introduce the fundamental library abstractions for constructing concurrent "
+"programs."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:19
+msgid ""
+"Rust tasks are not the same as traditional threads: rather, they are "
+"considered _green threads_, lightweight units of execution that the Rust "
+"runtime schedules cooperatively onto a small number of operating system "
+"threads.  On a multi-core system Rust tasks will be scheduled in parallel by "
+"default.  Because tasks are significantly cheaper to create than traditional "
+"threads, Rust can create hundreds of thousands of concurrent tasks on a "
+"typical 32-bit system.  In general, all Rust code executes inside a task, "
+"including the `main` function."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:26
+msgid ""
+"In order to make efficient use of memory Rust tasks have dynamically sized "
+"stacks.  A task begins its life with a small amount of stack space "
+"(currently in the low thousands of bytes, depending on platform), and "
+"acquires more stack as needed.  Unlike in languages such as C, a Rust task "
+"cannot accidentally write to memory beyond the end of the stack, causing "
+"crashes or worse."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:32
+msgid ""
+"Tasks provide failure isolation and recovery. When a fatal error occurs in "
+"Rust code as a result of an explicit call to `fail!()`, an assertion "
+"failure, or another invalid operation, the runtime system destroys the "
+"entire task. Unlike in languages such as Java and C++, there is no way to "
+"`catch` an exception. Instead, tasks may monitor each other for failure."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:37
+msgid ""
+"Tasks use Rust's type system to provide strong memory safety guarantees. In "
+"particular, the type system guarantees that tasks cannot share mutable state "
+"with each other. Tasks communicate with each other by transferring _owned_ "
+"data through the global _exchange heap_."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:39
+msgid "## A note about the libraries"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:44
+msgid ""
+"While Rust's type system provides the building blocks needed for safe and "
+"efficient tasks, all of the task functionality itself is implemented in the "
+"standard and extra libraries, which are still under development and do not "
+"always present a consistent or complete interface."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:47
+msgid ""
+"For your reference, these are the standard modules involved in Rust "
+"concurrency at this writing:"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid "[`std::task`] - All code relating to tasks and task scheduling,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid "[`std::comm`] - The message passing interface,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid "[`std::pipes`] - The underlying messaging infrastructure,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid "[`extra::comm`] - Additional messaging types based on `std::pipes`,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid "[`extra::sync`] - More exotic synchronization tools, including locks,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid ""
+"[`extra::arc`] - The Arc (atomically reference counted) type, for safely "
+"sharing immutable data,"
+msgstr ""
+
+#. type: Bullet: '* '
+#: doc/tutorial-tasks.md:56
+msgid ""
+"[`extra::future`] - A type representing values that may be computed "
+"concurrently and retrieved at a later time."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:64
+msgid ""
+"[`std::task`]: std/task.html [`std::comm`]: std/comm.html [`std::pipes`]: "
+"std/pipes.html [`extra::comm`]: extra/comm.html [`extra::sync`]: extra/sync."
+"html [`extra::arc`]: extra/arc.html [`extra::future`]: extra/future.html"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:66
+msgid "# Basics"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:72
+msgid ""
+"The programming interface for creating and managing tasks lives in the "
+"`task` module of the `std` library, and is thus available to all Rust code "
+"by default. At its simplest, creating a task is a matter of calling the "
+"`spawn` function with a closure argument. `spawn` executes the closure in "
+"the new task."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:76
+msgid "~~~~ # use std::io::println; # use std::task::spawn;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:80
+msgid ""
+"// Print something profound in a different task using a named function fn "
+"print_message() { println(\"I am running in a different task!\"); } "
+"spawn(print_message);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:83
+msgid ""
+"// Print something more profound in a different task using a lambda "
+"expression spawn( || println(\"I am also running in a different task!\") );"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:89
+#, no-wrap
+msgid ""
+"// The canonical way to spawn is using `do` notation\n"
+"do spawn {\n"
+"    println(\"I too am running in a different task!\");\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:95
+msgid ""
+"In Rust, there is nothing special about creating tasks: a task is not a "
+"concept that appears in the language semantics. Instead, Rust's type system "
+"provides all the tools necessary to implement safe concurrency: "
+"particularly, _owned types_. The language leaves the implementation details "
+"to the standard library."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:102
+msgid ""
+"The `spawn` function has a very simple type signature: `fn spawn(f: ~fn())`. "
+"Because it accepts only owned closures, and owned closures contain only "
+"owned data, `spawn` can safely move the entire closure and all its "
+"associated state into an entirely different task for execution. Like any "
+"closure, the function passed to `spawn` may capture an environment that it "
+"carries across tasks."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:109
+msgid ""
+"~~~ # use std::io::println; # use std::task::spawn; # fn "
+"generate_task_number() -> int { 0 } // Generate some state locally let "
+"child_task_number = generate_task_number();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:115
+#, no-wrap
+msgid ""
+"do spawn {\n"
+"   // Capture it in the remote task\n"
+"   println(fmt!(\"I am child number %d\", child_task_number));\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:119
+msgid ""
+"By default, the scheduler multiplexes tasks across the available cores, "
+"running in parallel. Thus, on a multicore machine, running the following "
+"code should interleave the output in vaguely random order."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:123
+msgid "~~~ # use std::io::print; # use std::task::spawn;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:130
+#, no-wrap
+msgid ""
+"for child_task_number in range(0, 20) {\n"
+"    do spawn {\n"
+"       print(fmt!(\"I am child number %d\\n\", child_task_number));\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:132
+msgid "## Communication"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:137
+msgid ""
+"Now that we have spawned a new task, it would be nice if we could "
+"communicate with it. Recall that Rust does not have shared mutable state, so "
+"one task may not manipulate variables owned by another task.  Instead we use "
+"*pipes*."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:142
+msgid ""
+"A pipe is simply a pair of endpoints: one for sending messages and another "
+"for receiving messages. Pipes are low-level communication building-blocks "
+"and so come in a variety of forms, each one appropriate for a different use "
+"case. In what follows, we cover the most commonly used varieties."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:148
+msgid ""
+"The simplest way to create a pipe is to use the `pipes::stream` function to "
+"create a `(Port, Chan)` pair. In Rust parlance, a *channel* is a sending "
+"endpoint of a pipe, and a *port* is the receiving endpoint. Consider the "
+"following example of calculating two results concurrently:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:152
+msgid "~~~~ # use std::task::spawn; # use std::comm::{stream, Port, Chan};"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:154
+msgid "let (port, chan): (Port<int>, Chan<int>) = stream();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:159
+#, no-wrap
+msgid ""
+"do spawn || {\n"
+"    let result = some_expensive_computation();\n"
+"    chan.send(result);\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:165
+msgid ""
+"some_other_expensive_computation(); let result = port.recv(); # fn "
+"some_expensive_computation() -> int { 42 } # fn "
+"some_other_expensive_computation() {} ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:170
+msgid ""
+"Let's examine this example in detail. First, the `let` statement creates a "
+"stream for sending and receiving integers (the left-hand side of the `let`, "
+"`(chan, port)`, is an example of a *destructuring let*: the pattern "
+"separates a tuple into its component parts)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:175
+msgid ""
+"~~~~ # use std::comm::{stream, Chan, Port}; let (port, chan): (Port<int>, "
+"Chan<int>) = stream(); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:179
+msgid ""
+"The child task will use the channel to send data to the parent task, which "
+"will wait to receive the data on the port. The next statement spawns the "
+"child task."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:190
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# use std::task::spawn;\n"
+"# use std::comm::stream;\n"
+"# fn some_expensive_computation() -> int { 42 }\n"
+"# let (port, chan) = stream();\n"
+"do spawn || {\n"
+"    let result = some_expensive_computation();\n"
+"    chan.send(result);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:196
+msgid ""
+"Notice that the creation of the task closure transfers `chan` to the child "
+"task implicitly: the closure captures `chan` in its environment. Both `Chan` "
+"and `Port` are sendable types and may be captured into tasks or otherwise "
+"transferred between them. In the example, the child task runs an expensive "
+"computation, then sends the result over the captured channel."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:200
+msgid ""
+"Finally, the parent continues with some other expensive computation, then "
+"waits for the child's result to arrive on the port:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:209
+msgid ""
+"~~~~ # use std::comm::{stream}; # fn some_other_expensive_computation() {} # "
+"let (port, chan) = stream::<int>(); # chan.send(0); "
+"some_other_expensive_computation(); let result = port.recv(); ~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:215
+msgid ""
+"The `Port` and `Chan` pair created by `stream` enables efficient "
+"communication between a single sender and a single receiver, but multiple "
+"senders cannot use a single `Chan`, and multiple receivers cannot use a "
+"single `Port`.  What if our example needed to compute multiple results "
+"across a number of tasks? The following program is ill-typed:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:221
+msgid ""
+"~~~ {.xfail-test} # use std::task::{spawn}; # use std::comm::{stream, Port, "
+"Chan}; # fn some_expensive_computation() -> int { 42 } let (port, chan) = "
+"stream();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:225
+#, no-wrap
+msgid ""
+"do spawn {\n"
+"    chan.send(some_expensive_computation());\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:232
+#, no-wrap
+msgid ""
+"// ERROR! The previous spawn statement already owns the channel,\n"
+"// so the compiler will not allow it to be captured again\n"
+"do spawn {\n"
+"    chan.send(some_expensive_computation());\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:235
+msgid ""
+"Instead we can use a `SharedChan`, a type that allows a single `Chan` to be "
+"shared by multiple senders."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:239
+msgid "~~~ # use std::task::spawn; # use std::comm::{stream, SharedChan};"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:242
+msgid "let (port, chan) = stream(); let chan = SharedChan::new(chan);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:250
+#, no-wrap
+msgid ""
+"for init_val in range(0u, 3) {\n"
+"    // Create a new channel handle to distribute to the child task\n"
+"    let child_chan = chan.clone();\n"
+"    do spawn {\n"
+"        child_chan.send(some_expensive_computation(init_val));\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:254
+msgid ""
+"let result = port.recv() + port.recv() + port.recv(); # fn "
+"some_expensive_computation(_i: uint) -> int { 42 } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:263
+msgid ""
+"Here we transfer ownership of the channel into a new `SharedChan` value.  "
+"Like `Chan`, `SharedChan` is a non-copyable, owned type (sometimes also "
+"referred to as an *affine* or *linear* type). Unlike with `Chan`, though, "
+"the programmer may duplicate a `SharedChan`, with the `clone()` method.  A "
+"cloned `SharedChan` produces a new handle to the same channel, allowing "
+"multiple tasks to send data to a single port.  Between `spawn`, `stream` and "
+"`SharedChan`, we have enough tools to implement many useful concurrency "
+"patterns."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:268
+msgid ""
+"Note that the above `SharedChan` example is somewhat contrived since you "
+"could also simply use three `stream` pairs, but it serves to illustrate the "
+"point. For reference, written with multiple streams, it might look like the "
+"example below."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:273
+msgid "~~~ # use std::task::spawn; # use std::comm::stream; # use std::vec;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:282
+#, no-wrap
+msgid ""
+"// Create a vector of ports, one for each child task\n"
+"let ports = do vec::from_fn(3) |init_val| {\n"
+"    let (port, chan) = stream();\n"
+"    do spawn {\n"
+"        chan.send(some_expensive_computation(init_val));\n"
+"    }\n"
+"    port\n"
+"};\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:287
+msgid ""
+"// Wait on each port, accumulating the results let result = ports.iter()."
+"fold(0, |accum, port| accum + port.recv() ); # fn "
+"some_expensive_computation(_i: uint) -> int { 42 } ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:291
+msgid ""
+"## Backgrounding computations: Futures With `extra::future`, rust has a "
+"mechanism for requesting a computation and getting the result later."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:299
+#, no-wrap
+msgid ""
+"The basic example below illustrates this.\n"
+"~~~\n"
+"# fn make_a_sandwich() {};\n"
+"fn fib(n: uint) -> uint {\n"
+"    // lengthy computation returning an uint\n"
+"    12586269025\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:304
+msgid ""
+"let mut delayed_fib = extra::future::spawn (|| fib(50) ); make_a_sandwich(); "
+"println(fmt!(\"fib(50) = %?\", delayed_fib.get()))  ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:310
+msgid ""
+"The call to `future::spawn` returns immediately a `future` object regardless "
+"of how long it takes to run `fib(50)`. You can then make yourself a sandwich "
+"while the computation of `fib` is running. The result of the execution of "
+"the method is obtained by calling `get` on the future.  This call will block "
+"until the value is available (*i.e.* the computation is complete). Note that "
+"the future needs to be mutable so that it can save the result for next time "
+"`get` is called."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:322
+#, no-wrap
+msgid ""
+"Here is another example showing how futures allow you to background computations. The workload will\n"
+"be distributed on the available cores.\n"
+"~~~\n"
+"# use std::vec;\n"
+"fn partial_sum(start: uint) -> f64 {\n"
+"    let mut local_sum = 0f64;\n"
+"    for num in range(start*100000, (start+1)*100000) {\n"
+"        local_sum += (num as f64 + 1.0).pow(&-2.0);\n"
+"    }\n"
+"    local_sum\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:325
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    let mut futures = vec::from_fn(1000, |ind| do extra::future::spawn { partial_sum(ind) });\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:333
+#, no-wrap
+msgid ""
+"    let mut final_res = 0f64;\n"
+"    for ft in futures.mut_iter()  {\n"
+"        final_res += ft.get();\n"
+"    }\n"
+"    println(fmt!(\"π^2/6 is not far from : %?\", final_res));\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:335
+msgid "## Sharing immutable data without copy: Arc"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:340
+msgid ""
+"To share immutable data between tasks, a first approach would be to only use "
+"pipes as we have seen previously. A copy of the data to share would then be "
+"made for each task. In some cases, this would add up to a significant amount "
+"of wasted memory and would require copying the same data more than necessary."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:344
+msgid ""
+"To tackle this issue, one can use an Atomically Reference Counted wrapper "
+"(`Arc`) as implemented in the `extra` library of Rust. With an Arc, the data "
+"will no longer be copied for each task. The Arc acts as a reference to the "
+"shared data and only this reference is shared and cloned."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:351
+msgid ""
+"Here is a small example showing how to use Arcs. We wish to run concurrently "
+"several computations on a single large vector of floats. Each task needs the "
+"full vector to perform its duty.  ~~~ # use std::vec; # use std::rand; use "
+"extra::arc::Arc;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:355
+#, no-wrap
+msgid ""
+"fn pnorm(nums: &~[float], p: uint) -> float {\n"
+"    nums.iter().fold(0.0, |a,b| a+(*b).pow(&(p as float)) ).pow(&(1f / (p as float)))\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:359
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    let numbers = vec::from_fn(1000000, |_| rand::random::<float>());\n"
+"    println(fmt!(\"Inf-norm = %?\",  *numbers.iter().max().unwrap()));\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:361
+#, no-wrap
+msgid "    let numbers_arc = Arc::new(numbers);\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:365
+#, no-wrap
+msgid ""
+"    for num in range(1u, 10) {\n"
+"        let (port, chan)  = stream();\n"
+"        chan.send(numbers_arc.clone());\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:374
+#, no-wrap
+msgid ""
+"        do spawn {\n"
+"            let local_arc : Arc<~[float]> = port.recv();\n"
+"            let task_numbers = local_arc.get();\n"
+"            println(fmt!(\"%u-norm = %?\", num, pnorm(task_numbers, num)));\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:396
+msgid ""
+"The function `pnorm` performs a simple computation on the vector (it "
+"computes the sum of its items at the power given as argument and takes the "
+"inverse power of this value). The Arc on the vector is created by the line "
+"~~~ # use extra::arc::Arc; # use std::vec; # use std::rand; # let numbers = "
+"vec::from_fn(1000000, |_| rand::random::<float>()); let numbers_arc=Arc::"
+"new(numbers); ~~~ and a clone of it is sent to each task ~~~ # use extra::"
+"arc::Arc; # use std::vec; # use std::rand; # let numbers=vec::"
+"from_fn(1000000, |_| rand::random::<float>()); # let numbers_arc = Arc::"
+"new(numbers); # let (port, chan)  = stream(); chan.send(numbers_arc."
+"clone()); ~~~ copying only the wrapper and not its contents."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:410
+msgid ""
+"Each task recovers the underlying data by ~~~ # use extra::arc::Arc; # use "
+"std::vec; # use std::rand; # let numbers=vec::from_fn(1000000, |_| rand::"
+"random::<float>()); # let numbers_arc=Arc::new(numbers); # let (port, chan)  "
+"= stream(); # chan.send(numbers_arc.clone()); # let local_arc : "
+"Arc<~[float]> = port.recv(); let task_numbers = local_arc.get(); ~~~ and can "
+"use it as if it were local."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:412
+msgid ""
+"The `arc` module also implements Arcs around mutable data that are not "
+"covered here."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:414
+msgid "# Handling task failure"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:423
+msgid ""
+"Rust has a built-in mechanism for raising exceptions. The `fail!()` macro "
+"(which can also be written with an error string as an argument: `fail!"
+"( ~reason)`) and the `assert!` construct (which effectively calls `fail!()` "
+"if a boolean expression is false) are both ways to raise exceptions. When a "
+"task raises an exception the task unwinds its stack---running destructors "
+"and freeing memory along the way---and then exits. Unlike exceptions in C++, "
+"exceptions in Rust are unrecoverable within a single task: once a task "
+"fails, there is no way to \"catch\" the exception."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:426
+msgid ""
+"All tasks are, by default, _linked_ to each other. That means that the fates "
+"of all tasks are intertwined: if one fails, so do all the others."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:434
+msgid ""
+"~~~{.xfail-test .linked-failure} # use std::task::spawn; # use std::task; # "
+"fn do_some_work() { loop { task::yield() } } # do task::try { // Create a "
+"child task that fails do spawn { fail!() }"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:439
+msgid ""
+"// This will also fail because the task we spawned failed do_some_work(); "
+"# }; ~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:449
+msgid ""
+"While it isn't possible for a task to recover from failure, tasks may notify "
+"each other of failure. The simplest way of handling task failure is with the "
+"`try` function, which is similar to `spawn`, but immediately blocks waiting "
+"for the child task to finish. `try` returns a value of type `Result<int, "
+"()>`. `Result` is an `enum` type with two variants: `Ok` and `Err`. In this "
+"case, because the type arguments to `Result` are `int` and `()`, callers can "
+"pattern-match on a result to check whether it's an `Ok` result with an `int` "
+"field (representing a successful result) or an `Err` result (representing "
+"termination with an error)."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:463
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::task;\n"
+"# fn some_condition() -> bool { false }\n"
+"# fn calculate_result() -> int { 0 }\n"
+"let result: Result<int, ()> = do task::try {\n"
+"    if some_condition() {\n"
+"        calculate_result()\n"
+"    } else {\n"
+"        fail!(\"oops!\");\n"
+"    }\n"
+"};\n"
+"assert!(result.is_err());\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:469
+msgid ""
+"Unlike `spawn`, the function spawned using `try` may return a value, which "
+"`try` will dutifully propagate back to the caller in a [`Result`] enum. If "
+"the child task terminates successfully, `try` will return an `Ok` result; if "
+"the child task fails, `try` will return an `Error` result."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:471
+msgid "[`Result`]: std/result.html"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:476
+msgid ""
+"> ***Note:*** A failed task does not currently produce a useful error > "
+"value (`try` always returns `Err(())`). In the > future, it may be possible "
+"for tasks to intercept the value passed to > `fail!()`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:479
+msgid ""
+"TODO: Need discussion of `future_result` in order to make failure modes "
+"useful."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:487
+msgid ""
+"But not all failures are created equal. In some cases you might need to "
+"abort the entire program (perhaps you're writing an assert which, if it "
+"trips, indicates an unrecoverable logic error); in other cases you might "
+"want to contain the failure at a certain boundary (perhaps a small piece of "
+"input from the outside world, which you happen to be processing in parallel, "
+"is malformed and its processing task can't proceed). Hence, you will need "
+"different _linked failure modes_."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:489
+msgid "## Failure modes"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:492
+msgid ""
+"By default, task failure is _bidirectionally linked_, which means that if "
+"either task fails, it kills the other one."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:507
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::task;\n"
+"# use std::comm::oneshot;\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
+"# do task::try {\n"
+"do spawn {\n"
+"    do spawn {\n"
+"        fail!();  // All three tasks will fail.\n"
+"    }\n"
+"    sleep_forever();  // Will get woken up by force, then fail\n"
+"}\n"
+"sleep_forever();  // Will get woken up by force, then fail\n"
+"# };\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:514
+msgid ""
+"If you want parent tasks to be able to kill their children, but do not want "
+"a parent to fail automatically if one of its child task fails, you can call "
+"`task::spawn_supervised` for _unidirectionally linked_ failure. The function "
+"`task::try`, which we saw previously, uses `spawn_supervised` internally, "
+"with additional logic to wait for the child task to finish before returning. "
+"Hence:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:536
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::comm::{stream, Chan, Port};\n"
+"# use std::comm::oneshot;\n"
+"# use std::task::{spawn, try};\n"
+"# use std::task;\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
+"# do task::try {\n"
+"let (receiver, sender): (Port<int>, Chan<int>) = stream();\n"
+"do spawn {  // Bidirectionally linked\n"
+"    // Wait for the supervised child task to exist.\n"
+"    let message = receiver.recv();\n"
+"    // Kill both it and the parent task.\n"
+"    assert!(message != 42);\n"
+"}\n"
+"do try {  // Unidirectionally linked\n"
+"    sender.send(42);\n"
+"    sleep_forever();  // Will get woken up by force\n"
+"}\n"
+"// Flow never reaches here -- parent task was killed too.\n"
+"# };\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:542
+msgid ""
+"Supervised failure is useful in any situation where one task manages "
+"multiple fallible child tasks, and the parent task can recover if any child "
+"fails. On the other hand, if the _parent_ (supervisor) fails, then there is "
+"nothing the children can do to recover, so they should also fail."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:545
+msgid ""
+"Supervised task failure propagates across multiple generations even if an "
+"intermediate generation has already exited:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:562
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::task;\n"
+"# use std::comm::oneshot;\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
+"# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }\n"
+"# do task::try::<int> {\n"
+"do task::spawn_supervised {\n"
+"    do task::spawn_supervised {\n"
+"        sleep_forever();  // Will get woken up by force, then fail\n"
+"    }\n"
+"    // Intermediate task immediately exits\n"
+"}\n"
+"wait_for_a_while();\n"
+"fail!();  // Will kill grandchild even if child has already exited\n"
+"# };\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:565
+msgid ""
+"Finally, tasks can be configured to not propagate failure to each other at "
+"all, using `task::spawn_unlinked` for _isolated failure_."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:581
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::task;\n"
+"# fn random() -> uint { 100 }\n"
+"# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }\n"
+"# do task::try::<()> {\n"
+"let (time1, time2) = (random(), random());\n"
+"do task::spawn_unlinked {\n"
+"    sleep_for(time2);  // Won't get forced awake\n"
+"    fail!();\n"
+"}\n"
+"sleep_for(time1);  // Won't get forced awake\n"
+"fail!();\n"
+"// It will take MAX(time1,time2) for the program to finish.\n"
+"# };\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:583
+msgid "## Creating a task with a bi-directional communication path"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:588
+msgid ""
+"A very common thing to do is to spawn a child task where the parent and "
+"child both need to exchange messages with each other. The function `extra::"
+"comm::DuplexStream()` supports this pattern.  We'll look briefly at how to "
+"use it."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:593
+msgid ""
+"To see how `DuplexStream()` works, we will create a child task that "
+"repeatedly receives a `uint` message, converts it to a string, and sends the "
+"string in response.  The child terminates when it receives `0`.  Here is the "
+"function that implements the child task:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:606
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use extra::comm::DuplexStream;\n"
+"# use std::uint;\n"
+"fn stringifier(channel: &DuplexStream<~str, uint>) {\n"
+"    let mut value: uint;\n"
+"    loop {\n"
+"        value = channel.recv();\n"
+"        channel.send(uint::to_str(value));\n"
+"        if value == 0 { break; }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:614
+msgid ""
+"The implementation of `DuplexStream` supports both sending and receiving. "
+"The `stringifier` function takes a `DuplexStream` that can send strings (the "
+"first type parameter) and receive `uint` messages (the second type "
+"parameter). The body itself simply loops, reading from the channel and then "
+"sending its response back.  The actual response itself is simply the "
+"stringified version of the received value, `uint::to_str(value)`."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:616
+msgid "Here is the code for the parent task:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:630
+#, no-wrap
+msgid ""
+"~~~{.xfail-test .linked-failure}\n"
+"# use std::task::spawn;\n"
+"# use std::uint;\n"
+"# use extra::comm::DuplexStream;\n"
+"# fn stringifier(channel: &DuplexStream<~str, uint>) {\n"
+"#     let mut value: uint;\n"
+"#     loop {\n"
+"#         value = channel.recv();\n"
+"#         channel.send(uint::to_str(value));\n"
+"#         if value == 0u { break; }\n"
+"#     }\n"
+"# }\n"
+"# fn main() {\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:632
+msgid "let (from_child, to_child) = DuplexStream();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:636
+#, no-wrap
+msgid ""
+"do spawn {\n"
+"    stringifier(&to_child);\n"
+"};\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:639
+msgid "from_child.send(22); assert!(from_child.recv() == ~\"22\");"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:642
+msgid "from_child.send(23); from_child.send(0);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:645
+msgid ""
+"assert!(from_child.recv() == ~\"23\"); assert!(from_child.recv() == ~\"0\");"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-tasks.md:652
+msgid ""
+"The parent task first calls `DuplexStream` to create a pair of bidirectional "
+"endpoints. It then uses `task::spawn` to create the child task, which "
+"captures one end of the communication channel.  As a result, both parent and "
+"child can send and receive data to and from the other."
+msgstr ""
diff --git a/doc/po/ja/tutorial.md.po b/doc/po/ja/tutorial.md.po
new file mode 100644 (file)
index 0000000..3c523e2
--- /dev/null
@@ -0,0 +1,5702 @@
+# Japanese translations for Rust package
+# Copyright (C) 2013 The Rust Project Developers
+# This file is distributed under the same license as the Rust package.
+# Automatically generated, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Rust 0.8-pre\n"
+"POT-Creation-Date: 2013-08-12 02:06+0900\n"
+"PO-Revision-Date: 2013-08-08 22:27+0900\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: UTF-8\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#. 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
+msgid "# Introduction"
+msgstr "# イントロダクション"
+
+#. type: Plain text
+#: doc/rust.md:1277 doc/tutorial.md:2176
+msgid ""
+"In type-parameterized functions, methods of the supertrait may be called on "
+"values of subtrait-bound type parameters.  Refering to the previous example "
+"of `trait Circle : Shape`:"
+msgstr ""
+"型パラメータを持つ関数では、サブトレイトの境界型パラメータの値によりスーパー"
+"トレイトのメソッドを呼び出すことになります。前の例の `trait Circle : Shape` "
+"を参照してください。"
+
+#. type: Plain text
+#: doc/rust.md:1286 doc/tutorial.md:2185
+#, no-wrap
+msgid ""
+"~~~\n"
+"# trait Shape { fn area(&self) -> float; }\n"
+"# trait Circle : Shape { fn radius(&self) -> float; }\n"
+"fn radius_times_area<T: Circle>(c: T) -> float {\n"
+"    // `c` is both a Circle and a Shape\n"
+"    c.radius() * c.area()\n"
+"}\n"
+"~~~\n"
+msgstr ""
+"~~~\n"
+"# trait Shape { fn area(&self) -> float; }\n"
+"# trait Circle : Shape { fn radius(&self) -> float; }\n"
+"fn radius_times_area<T: Circle>(c: T) -> float {\n"
+"    // `c` は Circle でもあり、Shape でもある\n"
+"    c.radius() * c.area()\n"
+"}\n"
+"~~~\n"
+
+#. type: Plain text
+#: doc/rust.md:1288 doc/tutorial.md:2187
+msgid "Likewise, supertrait methods may also be called on trait objects."
+msgstr ""
+"同様に、スーパートレイトのメソッドは、トレイトオブジェクトについても呼び出す"
+"ことが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:2
+msgid "% The Rust Language Tutorial"
+msgstr "% Rust 言語チュートリアル"
+
+#. type: Plain text
+#: doc/tutorial.md:13
+msgid ""
+"Rust is a programming language with a focus on type safety, memory safety, "
+"concurrency and performance. It is intended for writing large-scale, high-"
+"performance software that is free from several classes of common errors. "
+"Rust has a sophisticated memory model that encourages efficient data "
+"structures and safe concurrency patterns, forbidding invalid memory accesses "
+"that would otherwise cause segmentation faults. It is statically typed and "
+"compiled ahead of time."
+msgstr ""
+"Rust は、型安全性、メモリ安全性、並列性、パフォーマンスを重視したプログラミン"
+"グ言語です。大規模でハイパフォーマンスなソフトウェア作成向きの、C++ 等の言語"
+"でよくある誤りを犯しにくい言語仕様になっています。Rust の洗練されたメモリモデ"
+"ルでは、効率的なデータ構造や安全な並行計算を実現することが可能であり、セグメ"
+"ンテーション違反を引き起こす不正なメモリアクセスは起こりえません。Rust は、静"
+"的型付けされた、コンパイル型の言語です。"
+
+#. type: Plain text
+#: doc/tutorial.md:17
+msgid ""
+"As a multi-paradigm language, Rust supports writing code in procedural, "
+"functional and object-oriented styles. Some of its pleasant high-level "
+"features include:"
+msgstr ""
+"Rust はマルチパラダイム言語であり、手続き型、関数型、オブジェクト指向型のプロ"
+"グラミングをサポートします。Rust には、次のような素敵で高レベルな特徴がありま"
+"す。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:30
+msgid ""
+"**Type inference.** Type annotations on local variable declarations are "
+"optional."
+msgstr ""
+"**型推論:** ローカル変数の宣言では型注釈 (type annotation) を省略できます。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:30
+msgid ""
+"**Safe task-based concurrency.** Rust's lightweight tasks do not share "
+"memory, instead communicating through messages."
+msgstr ""
+"**タスクベースの安全な並行計算:** Rust の軽量タスクはタスク間でメモリを共有す"
+"るのではなく、メッセージを介して通信します。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:30
+msgid ""
+"**Higher-order functions.** Efficient and flexible closures provide "
+"iteration and other control structures"
+msgstr ""
+"**高階関数:** 効率的で柔軟なクロージャにより、イテレーションやその他の制御構"
+"造を実現できます。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:30
+msgid ""
+"**Pattern matching and algebraic data types.** Pattern matching on Rust's "
+"enumeration types (a more powerful version of C's enums, similar to "
+"algebraic data types in functional languages) is a compact and expressive "
+"way to encode program logic."
+msgstr ""
+"**パターンマッチと代数的データ型:** Rust の列挙型 (C の列挙型の強化バージョ"
+"ン。関数型言語における代数的データ型のようなもの) のパターンマッチにより、プ"
+"ログラムの論理を、コンパクトで表現力豊かに記述することができます。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:30
+msgid ""
+"**Polymorphism.** Rust has type-parametric functions and types, type classes "
+"and OO-style interfaces."
+msgstr ""
+"**ポリモーフィズム:** Rust には、型パラメータをもつ関数や型、型クラスとオブ"
+"ジェクト指向風のインターフェースがあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:32
+msgid "## Scope"
+msgstr "## 本文書の位置づけ"
+
+#. type: Plain text
+#: doc/tutorial.md:38
+msgid ""
+"This is an introductory tutorial for the Rust programming language. It "
+"covers the fundamentals of the language, including the syntax, the type "
+"system and memory model, generics, and modules. [Additional tutorials](#what-"
+"next) cover specific language features in greater depth."
+msgstr ""
+"この文章は、Rust プログラミング言語のチュートリアルです。構文、型システムとメ"
+"モリモデル、ジェネリクス、モジュールなどの言語の基礎となる部分をカバーしてい"
+"ます。 いくつかの言語機能の詳細については、 [その他のチュートリアル](#次のス"
+"テップは) を参照してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:42
+msgid ""
+"This tutorial assumes that the reader is already familiar with one or more "
+"languages in the C family. Understanding of pointers and general memory "
+"management techniques will help."
+msgstr ""
+"本チュートリアルは、読者がすでに 1 つ以上の C 系統言語 に精通していることを前"
+"提としています。本書を理解する上で、ポインタやメモリ管理のテクニックに関する"
+"知識が役に立つでしょう。"
+
+#. type: Plain text
+#: doc/tutorial.md:44
+msgid "## Conventions"
+msgstr "## 本書の表記について"
+
+#. type: Plain text
+#: doc/tutorial.md:47
+msgid ""
+"Throughout the tutorial, language keywords and identifiers defined in "
+"example code are displayed in `code font`."
+msgstr ""
+"本チュートリアルでは、言語のキーワードや、サンプルコード中で定義される識別子"
+"を `code font` のように示します。"
+
+#. type: Plain text
+#: doc/tutorial.md:53
+msgid ""
+"Code snippets are indented, and also shown in a monospaced font. Not all "
+"snippets constitute whole programs. For brevity, we'll often show fragments "
+"of programs that don't compile on their own. To try them out, you might have "
+"to wrap them in `fn main() { ... }`, and make sure they don't contain "
+"references to names that aren't actually defined."
+msgstr ""
+"コードスニペットは、インデントされ、固定幅フォントで表示されます。いくつかの"
+"コードスニペットは、プログラムの一部を抜き出したものになっています。説明を簡"
+"潔にするため、それだけではコンパイル不可能なプログラムの断片を掲載することが"
+"あります。プログラムの動作を試す際には、全体を `fn main() { ... }` で囲んでく"
+"ださい。また、プログラム中で未定義の名前を参照している箇所がないか確認してく"
+"ださい。"
+
+#. type: Plain text
+#: doc/tutorial.md:57
+msgid ""
+"> ***Warning:*** Rust is a language under ongoing development. Notes > about "
+"potential changes to the language, implementation > deficiencies, and other "
+"caveats appear offset in blockquotes."
+msgstr ""
+"> ***警告:*** Rust は開発途上の言語です。将来予定されている言語への変更や、実"
+"装上の不備、その他の注意事項など、 blockquote の段落 (この段落もそうです) に"
+"注意してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:59
+msgid "# Getting started"
+msgstr "# はじめに"
+
+#. type: Plain text
+#: doc/tutorial.md:63
+msgid ""
+"The Rust compiler currently must be built from a [tarball], unless you are "
+"on Windows, in which case using the [installer][win-exe] is recommended."
+msgstr ""
+"Windows 以外の環境では、今のところ、Rust のコンパイラは [ソースコード]"
+"[tarball] からビルドする必要があります。Windows をお使いの場合は、 [インス"
+"トーラー][win-exe] の使用をおすすめします。"
+
+#. type: Plain text
+#: doc/tutorial.md:69
+msgid ""
+"Since the Rust compiler is written in Rust, it must be built by a "
+"precompiled \"snapshot\" version of itself (made in an earlier state of "
+"development). As such, source builds require a connection to the Internet, "
+"to fetch snapshots, and an OS that can execute the available snapshot "
+"binaries."
+msgstr ""
+"Rust のコンパイラは Rust で書かれているため、最新版の少し前のソースからコンパ"
+"イルされた「スナップショット」版コンパイラでビルドする必要があります。スナッ"
+"プショットを利用してビルドするためには、スナップショットをダウンロードするた"
+"めのインターネット接続と、スナップショットバイナリを実行できる OS が必要で"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:71
+msgid "Snapshot binaries are currently built and tested on several platforms:"
+msgstr ""
+"スナップショットバイナリは、現時点では以下のプラットフォーム向けのものがあり"
+"ます。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:75
+msgid "Windows (7, Server 2008 R2), x86 only"
+msgstr "Windows (7, Server 2008 R2), x86 のみ"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:75
+msgid "Linux (various distributions), x86 and x86-64"
+msgstr "Linux (各種ディストリビューション), x86 または x86-64"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:75
+msgid "OSX 10.6 (\"Snow Leopard\") or greater, x86 and x86-64"
+msgstr "OSX 10.6 (\"Snow Leopard\") 以降, x86 または x86-64"
+
+#. type: Plain text
+#: doc/tutorial.md:78
+msgid ""
+"You may find that other platforms work, but these are our \"tier 1\" "
+"supported build environments that are most likely to work."
+msgstr ""
+"スナップショットは他のプラットフォームでも動作するかもしれませんが、\"tier "
+"1\" プラットフォームとしてサポートされているのは上記のみです。"
+
+#. type: Plain text
+#: doc/tutorial.md:85
+msgid ""
+"> ***Note:*** Windows users should read the detailed > \"[getting started]"
+"[wiki-start]\" notes on the wiki. Even when using > the binary installer, "
+"the Windows build requires a MinGW installation, > the precise details of "
+"which are not discussed here. Finally, `rustc` may > need to be [referred to "
+"as `rustc.exe`][bug-3319]. It's a bummer, we > know."
+msgstr ""
+"> ***注意:*** Windows ユーザーは wiki の [getting started][wiki-start] の記事"
+"を読んでください。 本書では詳細を説明しませんが、インストーラを利用する場合で"
+"も、MinGW のインストールなど、追加の手順が必要です。また、コンパイラは "
+"`rustc` ではなく、 [`rustc.exe` として呼び出す必要がある][bug-3319] かもしれ"
+"ません。このような制限があることはは、本当に残念です。"
+
+#. type: Plain text
+#: doc/tutorial.md:88
+msgid ""
+"[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
+"https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
+msgstr ""
+"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n"
+"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
+"developing-Rust"
+
+#. type: Plain text
+#: doc/tutorial.md:91
+msgid ""
+"To build from source you will also need the following prerequisite packages:"
+msgstr "ソースからビルドするためには、以下のパッケージが必要です。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:97
+msgid "g++ 4.4 or clang++ 3.x"
+msgstr "g++ 4.4 または clang++ 3.x"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:97
+msgid "python 2.6 or later (but not 3.x)"
+msgstr "python 2.6 以降 (ただし、 3.x は除く)"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:97
+msgid "perl 5.0 or later"
+msgstr "perl 5.0 以降"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:97
+msgid "gnu make 3.81 or later"
+msgstr "gnu make 3.81 以降"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:97
+msgid "curl"
+msgstr "curl"
+
+#. type: Plain text
+#: doc/tutorial.md:100
+msgid ""
+"If you've fulfilled those prerequisites, something along these lines should "
+"work."
+msgstr "上記条件を満たしていれば、以下のような手順でビルド可能なはずです。"
+
+#. type: Plain text
+#: doc/tutorial.md:108
+msgid ""
+"~~~~ {.notrust} $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz $ "
+"tar -xzf rust-0.7.tar.gz $ cd rust-0.7 $ ./configure $ make && make install "
+"~~~~"
+msgstr ""
+"~~~~ {.notrust}\n"
+"$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz\n"
+"$ tar -xzf rust-0.7.tar.gz $ cd rust-0.7 $ ./configure\n"
+"$ make && make install\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:114
+msgid ""
+"You may need to use `sudo make install` if you do not normally have "
+"permission to modify the destination directory. The install locations can be "
+"adjusted by passing a `--prefix` argument to `configure`. Various other "
+"options are also supported: pass `--help` for more information on them."
+msgstr ""
+"インストール先のディレクトリを変更する権限がない場合、 `sudo make install` を"
+"実行する必要があるかもしれません。インストール先は `configure` に `--prefix` "
+"引数を渡すことで変更できます。`configure` はその他いろいろなオプションをサ"
+"ポートしています。詳細については、 `--help` 引数を指定して実行してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:120
+msgid ""
+"When complete, `make install` will place several programs into `/usr/local/"
+"bin`: `rustc`, the Rust compiler; `rustdoc`, the API-documentation tool; "
+"`rustpkg`, the Rust package manager; `rusti`, the Rust REPL; and `rust`, a "
+"tool which acts both as a unified interface for them, and for a few common "
+"command line scenarios."
+msgstr ""
+"ビルド完了後、`make install` を実行すると、以下のプログラムが `/usr/local/"
+"bin` にインストールされます。\n"
+"\n"
+"* `rustc`: Rust のコンパイラ\n"
+"* `rustdoc`: API ドキュメント作成ツール\n"
+"* `rustpkg`: Rust のパッケージマネージャ\n"
+"* `rust`: Rust の REPL\n"
+"* `rust`: Rust のツール群への共通のインターフェースと、いくつかのコマンドライ"
+"ンシナリオを提供するツール"
+
+#. type: Plain text
+#: doc/tutorial.md:123
+msgid ""
+"[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz [win-exe]: "
+"http://static.rust-lang.org/dist/rust-0.7-install.exe"
+msgstr ""
+"[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz\n"
+"[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe"
+
+#. type: Plain text
+#: doc/tutorial.md:125
+msgid "## Compiling your first program"
+msgstr "## 最初のプログラム"
+
+#. type: Plain text
+#: doc/tutorial.md:128
+msgid ""
+"Rust program files are, by convention, given the extension `.rs`. Say we "
+"have a file `hello.rs` containing this program:"
+msgstr ""
+"Rust プログラムのファイルの拡張子は、慣例的に `.rs` とされています。以下の内"
+"容を持つファイル、`hello.rs` が存在するとします。"
+
+#. type: Plain text
+#: doc/tutorial.md:134
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn main() {\n"
+"    println(\"hello?\");\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:138
+msgid ""
+"If the Rust compiler was installed successfully, running `rustc hello.rs` "
+"will produce an executable called `hello` (or `hello.exe` on Windows) which, "
+"upon running, will likely do exactly what you expect."
+msgstr ""
+"Rust のコンパイラが正しくインストールされている場合、 `rustc hello.rs` を実行"
+"することで、実行ファイル `hello` (Windows の場合 `hello.exe`) を生成すること"
+"が可能です。このファイルを実行すれば、予想通りの出力が得られるでしょう。"
+
+#. type: Plain text
+#: doc/tutorial.md:143
+msgid ""
+"The Rust compiler tries to provide useful information when it encounters an "
+"error. If you introduce an error into the program (for example, by changing "
+"`println` to some nonexistent function), and then compile it, you'll see an "
+"error message like this:"
+msgstr ""
+"コンパイルエラーが発生した場合、Rust コンパイラはエラー解決のための情報を出力"
+"します。プログラム中にエラーが含まれる場合 (上記プログラムの `println` を存在"
+"しない別の名前に変更した場合など)、コンパイル時に以下のようなエラーメッセージ"
+"が出力されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:149
+#, no-wrap
+msgid ""
+"~~~~ {.notrust}\n"
+"hello.rs:2:4: 2:16 error: unresolved name: print_with_unicorns\n"
+"hello.rs:2     print_with_unicorns(\"hello?\");\n"
+"               ^~~~~~~~~~~~~~~~~~~~~~~\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:156
+msgid ""
+"In its simplest form, a Rust program is a `.rs` file with some types and "
+"functions defined in it. If it has a `main` function, it can be compiled to "
+"an executable. Rust does not allow code that's not a declaration to appear "
+"at the top level of the file: all statements must live inside a function.  "
+"Rust programs can also be compiled as libraries, and included in other "
+"programs."
+msgstr ""
+"最も単純な Rust プログラムは、いくつかの型や関数が定義された `.rs` ファイルの"
+"みからなります。`.rs` ファイルをコンパイルして実行可能ファイルを作成する場"
+"合、ファイル中に `main` 関数が含まれている必要があります。Rust プログラムで"
+"ファイルのトップレベルに記述可能なのは宣言 (declaration) のみです。ステートメ"
+"ント (statement) は、すべて関数内部に記述されます。Rust のプログラムは、他の"
+"プログラムから利用するライブラリとしてコンパイルすることも可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:158
+msgid "## Using the rust tool"
+msgstr "## `rust` コマンドを利用する"
+
+#. type: Plain text
+#: doc/tutorial.md:163
+msgid ""
+"While using `rustc` directly to generate your executables, and then running "
+"them manually is a perfectly valid way to test your code, for smaller "
+"projects, prototypes, or if you're a beginner, it might be more convenient "
+"to use the `rust` tool."
+msgstr ""
+"作成したプログラムのテストを行うには、`rustc` でコンパイル後、生成されたファ"
+"イルを手動で実行する方法だけではなく、 `rust` ツールを利用する方法もありま"
+"す。小さなプロジェクトやプロトタイプを作成する場合、もしくはあなたが初心者の"
+"場合は、 `rust` ツールによりコンパイルから実行までの一連の流れを簡単に行うこ"
+"とができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:169
+msgid ""
+"The `rust` tool provides central access to the other rust tools, as well as "
+"handy shortcuts for directly running source files.  For example, if you have "
+"a file `foo.rs` in your current directory, `rust run foo.rs` would attempt "
+"to compile it and, if successful, directly run the resulting binary."
+msgstr ""
+"`rust` ツールには、rust ツール群を統一的なインターフェースで呼び出す機能だけ"
+"でなく、ソースファイルを直接実行する便利なショートカット機能もあります。例え"
+"ば、カレントディレクトリにある `foo.rs` を実行しようとする場合、 `rust run "
+"foo.rs` を実行することで、コンパイルから、コンパイル成功後に生成されるバイナ"
+"リの実行までを自動的に行なってくれます。"
+
+#. type: Plain text
+#: doc/tutorial.md:172
+msgid ""
+"To get a list of all available commands, simply call `rust` without any "
+"argument."
+msgstr ""
+"実行可能なコマンドを調べるためには、引数を与えず `rust` コマンドを実行してく"
+"ださい。"
+
+#. type: Plain text
+#: doc/tutorial.md:174
+msgid "## Editing Rust code"
+msgstr "## Rust のコードを編集する"
+
+#. type: Plain text
+#: doc/tutorial.md:184
+msgid ""
+"There are vim highlighting and indentation scripts in the Rust source "
+"distribution under `src/etc/vim/`. There is an emacs mode under `src/etc/"
+"emacs/` called `rust-mode`, but do read the instructions included in that "
+"directory. In particular, if you are running emacs 24, then using emacs's "
+"internal package manager to install `rust-mode` is the easiest way to keep "
+"it up to date. There is also a package for Sublime Text 2, available both "
+"[standalone][sublime] and through [Sublime Package Control][sublime-pkg], "
+"and support for Kate under `src/etc/kate`."
+msgstr ""
+"vim のハイライトとインデント用スクリプトは、Rust のソースツリーの `src/etc/"
+"vim` 以下にあります。emacs の Rust 編集用モードの `rust-mode` は、 `src/etc/"
+"emacs/` 以下にありますが、当該ディレクトリに配置されているインストール手順に"
+"従って操作する必要があります。 emacs 24 以降をご利用の場合、 emacs 組み込みの"
+"パッケージマネージャで `rust-mode` をインストールするのが最もお手軽です。"
+"Sublime Text 2 用のパッケージは、[スタンドアロン版][sublime] と、[Sublime "
+"Package Control][sublime-pkg] 版の2つがあります。Kate 向けパッケージは `src/"
+"etc/kate` 以下です。"
+
+#. type: Plain text
+#: doc/tutorial.md:188
+msgid ""
+"There is ctags support via `src/etc/ctags.rust`, but many other tools and "
+"editors are not yet supported. If you end up writing a Rust mode for your "
+"favorite editor, let us know so that we can link to it."
+msgstr ""
+"ctags は `src/etc/ctags.rust` を利用することで rust をサポートします。多くの"
+"ツールやエディタは rust をサポートしていません。もしあなたがお気に入りのエ"
+"ディタ向けのRust モードを作成した場合、リンクを貼りたいのでお知らせください。"
+
+#. type: Plain text
+#: doc/tutorial.md:191
+msgid ""
+"[sublime]: http://github.com/dbp/sublime-rust [sublime-pkg]: http://wbond."
+"net/sublime_packages/package_control"
+msgstr ""
+"[sublime]: http://github.com/dbp/sublime-rust\n"
+"[sublime-pkg]: http://wbond.net/sublime_packages/package_control"
+
+#. type: Plain text
+#: doc/tutorial.md:193
+msgid "# Syntax basics"
+msgstr "# 基本的な構文"
+
+#. type: Plain text
+#: doc/tutorial.md:201
+msgid ""
+"Assuming you've programmed in any C-family language (C++, Java, JavaScript, "
+"C#, or PHP), Rust will feel familiar. Code is arranged in blocks delineated "
+"by curly braces; there are control structures for branching and looping, "
+"like the familiar `if` and `while`; function calls are written `myfunc(arg1, "
+"arg2)`; operators are written the same and mostly have the same precedence "
+"as in C; comments are again like C; module names are separated with double-"
+"colon (`::`) as with C++."
+msgstr ""
+"あなたが C 系統の言語 (C++, Java, JavaScript, C# または PHP) でプログラミング"
+"したことがあれば、Rust の構文には馴染みがあるでしょう。コードは波括弧で区切ら"
+"れたブロックの中に配置され、分岐やループのための制御構文はお馴染みの `if` と "
+"`while` で、関数呼び出しは `myfunc(arg1, arg2)` と書け、演算子は C のものと同"
+"じで、優先順位もほとんど同じで、コメントもまた C と同じで、モジュール名のセパ"
+"レータは C++ と同様 2つのコロン (`::`) です。"
+
+#. type: Plain text
+#: doc/tutorial.md:206
+msgid ""
+"The main surface difference to be aware of is that the condition at the head "
+"of control structures like `if` and `while` does not require parentheses, "
+"while their bodies *must* be wrapped in braces. Single-statement, unbraced "
+"bodies are not allowed."
+msgstr ""
+"表記上の違いで注目すべき点は、`if` や `while` などの制御構造の先頭にある条件"
+"句を丸括弧で囲う必要がない点と、ボディ部をで波括弧で **囲わなければならない"
+"** という点です。ボディ部が単一のステートメントであっても、波括弧を省略するこ"
+"とはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:219
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# mod universe { pub fn recalibrate() -> bool { true } }\n"
+"fn main() {\n"
+"    /* A simple loop */\n"
+"    loop {\n"
+"        // A tricky calculation\n"
+"        if universe::recalibrate() {\n"
+"            return;\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"# mod universe { pub fn recalibrate() -> bool { true } }\n"
+"fn main() {\n"
+"    /* シンプルなループ */\n"
+"    loop {\n"
+"        // 複雑な計算\n"
+"        if universe::recalibrate() {\n"
+"            return;\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:223
+msgid ""
+"The `let` keyword introduces a local variable. Variables are immutable by "
+"default. To introduce a local variable that you can re-assign later, use "
+"`let mut` instead."
+msgstr ""
+"`let` キーワードにより、ローカル変数を定義します。変数はデフォルトでは "
+"immutable (変更不可) です。再代入可能なローカル変数を定義するためには、`let "
+"mut` を用います。"
+
+#. type: Plain text
+#: doc/tutorial.md:227
+msgid "~~~~ let hi = \"hi\"; let mut count = 0;"
+msgstr ""
+"~~~~\n"
+" let hi = \"hi\";\n"
+" let mut count = 0;"
+
+#. type: Plain text
+#: doc/tutorial.md:233
+#, no-wrap
+msgid ""
+"while count < 10 {\n"
+"    println(fmt!(\"count: %?\", count));\n"
+"    count += 1;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:237
+msgid ""
+"Although Rust can almost always infer the types of local variables, you can "
+"specify a variable's type by following it with a colon, then the type name. "
+"Static items, on the other hand, always require a type annotation."
+msgstr ""
+"Rust は、ほぼすべてのローカル変数の型を推論してくれますが、コロンの後に続けて"
+"型名を書くことで、明示的に変数の型を指定することもできます。一方、静的な項目 "
+"(static item) には、常に型注釈を指定しなければなりません。"
+
+#. type: Plain text
+#: doc/tutorial.md:243
+msgid ""
+"~~~~ static MONSTER_FACTOR: float = 57.8; let monster_size = MONSTER_FACTOR "
+"* 10.0; let monster_size: int = 50; ~~~~"
+msgstr ""
+"~~~~\n"
+"static MONSTER_FACTOR: float = 57.8;\n"
+"let monster_size = MONSTER_FACTOR * 10.0;\n"
+"let monster_size: int = 50;\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:252
+msgid ""
+"Local variables may shadow earlier declarations, as in the previous example: "
+"`monster_size` was first declared as a `float`, and then a second "
+"`monster_size` was declared as an `int`. If you were to actually compile "
+"this example, though, the compiler would determine that the first "
+"`monster_size` is unused and issue a warning (because this situation is "
+"likely to indicate a programmer error). For occasions where unused variables "
+"are intentional, their names may be prefixed with an underscore to silence "
+"the warning, like `let _monster_size = 50;`."
+msgstr ""
+"ローカル変数は、先行する宣言を隠すことがあります。先の例では、1つ目の "
+"`monster_size` は `float` として宣言され、2つ目の `monster_size` は `int` と"
+"して宣言されています。このプログラムをコンパイルした場合、「1つ目の "
+"`monster_size` は未使用である」という警告メッセージが出力されます (プログラマ"
+"が何らかの誤りを犯している可能性があるため)。未使用変数の存在が意図的なもので"
+"あった場合、未使用変数名の先頭にアンダースコアをつけることで、警告を抑制でき"
+"ます (`let _monster_size = 50;`)。"
+
+#. type: Plain text
+#: doc/tutorial.md:258
+msgid ""
+"Rust identifiers start with an alphabetic character or an underscore, and "
+"after that may contain any sequence of alphabetic characters, numbers, or "
+"underscores. The preferred style is to write function, variable, and module "
+"names with lowercase letters, using underscores where they help readability, "
+"while writing types in camel case."
+msgstr ""
+"Rust の識別子 (identifier) は、アルファベット、数字、またはアンダースコア "
+"(`_`) から構成されますが、先頭の文字は数字以外でなければなりません。関数名、"
+"変数名、モジュール名はスネークケース (アルファベットは小文字にし、単語間をア"
+"ンダースコアで区切る) にし、型の名前はアッパーキャメルケースにすることが推奨"
+"されています。"
+
+#. type: Plain text
+#: doc/tutorial.md:263
+#, no-wrap
+msgid ""
+"~~~\n"
+"let my_variable = 100;\n"
+"type MyType = int;     // primitive types are _not_ camel case\n"
+"~~~\n"
+msgstr ""
+"~~~\n"
+"let my_variable = 100;\n"
+"type MyType = int;     // プリミティブ型はキャメルケース __ではない__\n"
+"~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:265
+msgid "## Expressions and semicolons"
+msgstr "## 式とセミコロン"
+
+#. type: Plain text
+#: doc/tutorial.md:271
+msgid ""
+"Though it isn't apparent in all code, there is a fundamental difference "
+"between Rust's syntax and predecessors like C.  Many constructs that are "
+"statements in C are expressions in Rust, allowing code to be more concise. "
+"For example, you might write a piece of code like this:"
+msgstr ""
+"コードの見た目から明らかではないのですが、Rust の構文と、C 等の先行言語の構文"
+"との間の根本的な違いがとして、C ではステートメントとして扱われる多くの構文要"
+"素が、Rust では式として扱われるという点があります。Rust のこの特徴により、"
+"コードをより簡潔に書くことができるようになります。例えば、C 系言語では以下の"
+"ようにコードを書きますが、"
+
+#. type: Plain text
+#: doc/tutorial.md:283
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# let item = \"salad\";\n"
+"let price;\n"
+"if item == \"salad\" {\n"
+"    price = 3.50;\n"
+"} else if item == \"muffin\" {\n"
+"    price = 2.25;\n"
+"} else {\n"
+"    price = 2.00;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:285
+msgid "But, in Rust, you don't have to repeat the name `price`:"
+msgstr "Rust では、変数名 `price` を繰り返し書く必要はありません。"
+
+#. type: Plain text
+#: doc/tutorial.md:297
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# let item = \"salad\";\n"
+"let price =\n"
+"    if item == \"salad\" {\n"
+"        3.50\n"
+"    } else if item == \"muffin\" {\n"
+"        2.25\n"
+"    } else {\n"
+"        2.00\n"
+"    };\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:303
+msgid ""
+"Both pieces of code are exactly equivalent: they assign a value to `price` "
+"depending on the condition that holds. Note that there are no semicolons in "
+"the blocks of the second snippet. This is important: the lack of a semicolon "
+"after the last statement in a braced block gives the whole block the value "
+"of that last expression."
+msgstr ""
+"どちらのコードも、全く等価です。`price` には、条件 (この場合は `item` の値) "
+"に対応した値が代入されます。2つ目のコード例では、ブロックの中にセミコロンが書"
+"かれていないことに注意してください。ブロック内の最後のステートメントの後にセ"
+"ミコロンがない場合、**ブロック全体の値 (ブロックを式として評価した際の値) は"
+"最後の式の値になります**。"
+
+#. type: Plain text
+#: doc/tutorial.md:309
+msgid ""
+"Put another way, the semicolon in Rust *ignores the value of an "
+"expression*.  Thus, if the branches of the `if` had looked like `{ 4; }`, "
+"the above example would simply assign `()` (nil or void) to `price`. But "
+"without the semicolon, each branch has a different value, and `price` gets "
+"the value of the branch that was taken."
+msgstr ""
+"言い換えると、Rust では、セミコロンにより **式の値が無視されます。** したがっ"
+"て、上記の例で `if` のすべての節 (branch) が `{ 4; }` のように書かれていたと"
+"したら、`price` には単に `()` (nil または void の意) が代入されます。しかし、"
+"式にセミコロンが付けられていない場合、各節はそれぞれ異なる値を持ち、 `price` "
+"には節のうち実行されたものの値が代入されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:314
+msgid ""
+"In short, everything that's not a declaration (declarations are `let` for "
+"variables; `fn` for functions; and any top-level named items such as [traits]"
+"(#traits), [enum types](#enums), and static items) is an expression, "
+"including function bodies."
+msgstr ""
+"まとめると、宣言 (変数の `let`, 関数の `fn`, [トレイト](#トレイト) や [列挙"
+"型](#列挙型)、静的な項目などの、トップレベルで名前を持つ項目) でないものは、"
+"すべてが式となります。関数のボディ部も式です。"
+
+#. type: Plain text
+#: doc/tutorial.md:322
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn is_four(x: int) -> bool {\n"
+"   // No need for a return statement. The result of the expression\n"
+"   // is used as the return value.\n"
+"   x == 4\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"fn is_four(x: int) -> bool {\n"
+"   // return ステートメントは省略可能。最後の式の値が戻り値となる。\n"
+"   x == 4\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:324
+msgid "## Primitive types and literals"
+msgstr "## プリミティブ型とリテラル"
+
+#. type: Plain text
+#: doc/tutorial.md:331
+msgid ""
+"There are general signed and unsigned integer types, `int` and `uint`, as "
+"well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc.  Integers can "
+"be written in decimal (`144`), hexadecimal (`0x90`), or binary "
+"(`0b10010000`) base. Each integral type has a corresponding literal suffix "
+"that can be used to indicate the type of a literal: `i` for `int`, `u` for "
+"`uint`, `i8` for the `i8` type."
+msgstr ""
+"Rust には、他の言語と同様、符号付き整数の `int` と、符号なし整数の `uint` が"
+"あります。同様に、8 または 16, 32, 64 ビット幅の `i8`, `u16` などもあります。"
+"整数リテラルは、10進数 (`144`)、16進数 (`0x90`)、または2進数 (`0b10010000`) "
+"の表記が可能です。整数リテラルの型を表すための、各整数型に対応したサフィック"
+"スがあります。例えば、`i` は `int` 型、`u` は `uint` 型、`i8` は `i8` 型に対"
+"応します。"
+
+#. type: Plain text
+#: doc/tutorial.md:337
+msgid ""
+"In the absence of an integer literal suffix, Rust will infer the integer "
+"type based on type annotations and function signatures in the surrounding "
+"program. In the absence of any type information at all, Rust will assume "
+"that an unsuffixed integer literal has type `int`."
+msgstr ""
+"サフィックスが省略されている整数リテラルの型は、周囲にある型アノテーションや"
+"関数のシグネチャから推論されます。型について一切情報が得られない場合、サ"
+"フィックスなしの整数リテラルは `int` 型だとみなされます。"
+
+#. type: Plain text
+#: doc/tutorial.md:344
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let a = 1;       // a is an int\n"
+"let b = 10i;     // b is an int, due to the 'i' suffix\n"
+"let c = 100u;    // c is a uint\n"
+"let d = 1000i32; // d is an i32\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"let a = 1;       // a は int\n"
+"let b = 10i;     // b は int (サフィックス 'i' がある)\n"
+"let c = 100u;    // c は uint\n"
+"let d = 1000i32; // d は i32\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:349
+msgid ""
+"There are three floating-point types: `float`, `f32`, and `f64`.  Floating-"
+"point numbers are written `0.0`, `1e6`, or `2.1e-4`.  Like integers, "
+"floating-point literals are inferred to the correct type.  Suffixes `f`, "
+"`f32`, and `f64` can be used to create literals of a specific type."
+msgstr ""
+"浮動小数型は、 `float`, `f32`, `f64` の3種類があります。浮動小数リテラルは "
+"`0.0` や、 `1e6`、 `2.1e-4` といった表記が可能です。整数と同じく、サフィック"
+"スが省略された浮動小数リテラルは型推論されます。浮動小数のサフィックスは "
+"`f`、`f32`、`f64` の3種類で、リテラルの末尾につけることで、対応する型の値を作"
+"り出すことができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:351
+msgid "The keywords `true` and `false` produce literals of type `bool`."
+msgstr "`true` キーワードと `false` キーワードは、`bool` 型のリテラルです。"
+
+#. type: Plain text
+#: doc/tutorial.md:358
+msgid ""
+"Characters, the `char` type, are four-byte Unicode codepoints, whose "
+"literals are written between single quotes, as in `'x'`.  Just like C, Rust "
+"understands a number of character escapes, using the backslash character, "
+"such as `\\n`, `\\r`, and `\\t`. String literals, written between double "
+"quotes, allow the same escape sequences.  More on strings [later](#vectors-"
+"and-strings)."
+msgstr ""
+"文字は `char` 型で表され、4バイトの Unicode コードポイントに対応しています。"
+"`'x'` のように、文字をシングルクオートで囲んだものが文字リテラルです。C と同"
+"様、 Rust もバックスラッシュを使ったエスケープシーケンス (`\\n`, `\\r`, `"
+"\\t`) に対応しています。文字列リテラル (複数の文字をダブルクオートで囲ったも"
+"の) も同じエスケープシーケンスに対応しています。詳細は [ベクタと文字列](#ベク"
+"タと文字列) の章で述べます。"
+
+#. type: Plain text
+#: doc/tutorial.md:360
+msgid "The nil type, written `()`, has a single value, also written `()`."
+msgstr ""
+"nil 型は `()` と表記されます。 nil 型の唯一の値も `()` と表記されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:362
+msgid "## Operators"
+msgstr "## 演算子"
+
+#. type: Plain text
+#: doc/tutorial.md:367
+msgid ""
+"Rust's set of operators contains very few surprises. Arithmetic is done with "
+"`*`, `/`, `%`, `+`, and `-` (multiply, quotient, remainder, add, and "
+"subtract). `-` is also a unary prefix operator that negates numbers. As in "
+"C, the bitwise operators `>>`, `<<`, `&`, `|`, and `^` are also supported."
+msgstr ""
+"Rust の演算子には、あまり変わったものはありません。算術演算子は `*` (乗算)、 "
+"`/` (除算), `%` (剰余), `+` (加算), `-` (減算) です。`-` は数の符号を反転する"
+"単行演算子でもあります。C と同様、ビット演算子 `>>`, `<<`, `&`, `|`, `^` もサ"
+"ポートされています。"
+
+#. type: Plain text
+#: doc/tutorial.md:370
+msgid ""
+"Note that, if applied to an integer value, `!` flips all the bits (like `~` "
+"in C)."
+msgstr ""
+"整数型に対して `!` 演算子を適用すると、ビット単位での反転操作 (C の `~` と同"
+"じ動作) が行われることに注意してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:374
+msgid ""
+"The comparison operators are the traditional `==`, `!=`, `<`, `>`, `<=`, and "
+"`>=`. Short-circuiting (lazy) boolean operators are written `&&` (and) and "
+"`||` (or)."
+msgstr ""
+"比較演算子は、従来の言語と同じく、`==`, `!=`, `<`, `>`, `<=`, `>=` です。短絡"
+"評価 (遅延評価) されるブール演算子は、 `&&` (and 演算) と `||` (or 演算) があ"
+"ります。"
+
+#. type: Plain text
+#: doc/tutorial.md:379
+msgid ""
+"For type casting, Rust uses the binary `as` operator.  It takes an "
+"expression on the left side and a type on the right side and will, if a "
+"meaningful conversion exists, convert the result of the expression to the "
+"given type."
+msgstr ""
+"Rust では、型のキャストには二項演算子 `as` を使います。`as` 演算子は、左辺に"
+"式、右辺に型を取り、意味のある変換が可能な場合に限り、式の評価結果を指定され"
+"た型に変換します。"
+
+#. type: Plain text
+#: doc/tutorial.md:385
+msgid ""
+"~~~~ let x: float = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
+msgstr ""
+"~~~~\n"
+"let x: float = 4.0;\n"
+"let y: uint = x as uint;\n"
+"assert!(y == 4u);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:387
+msgid "## Syntax extensions"
+msgstr "## 構文拡張"
+
+#. type: Plain text
+#: doc/tutorial.md:394
+#, no-wrap
+msgid ""
+"*Syntax extensions* are special forms that are not built into the language,\n"
+"but are instead provided by the libraries. To make it clear to the reader when\n"
+"a name refers to a syntax extension, the names of all syntax extensions end\n"
+"with `!`. The standard library defines a few syntax extensions, the most\n"
+"useful of which is `fmt!`, a `sprintf`-style text formatter that you will\n"
+"often see in examples.\n"
+msgstr "**構文拡張** *(Syntax extensions)* は言語組み込みではなく、ライブラリにより提供される特殊形式 (スペシャルフォーム) です。プログラム中に構文拡張が登場したことを外見上明確にするため、構文拡張の名前には末尾に `!` をつけますなければなりません。標準ライブラリではいくつかの構文拡張が定義されていますが、その中でも最も有用なのは `fmt!` です。`fmt!` は `sprintf`スタイルの書式整形を行うもので、後のコード例の中でも何度か見かけることになるでしょう。\n"
+
+#. type: Plain text
+#: doc/tutorial.md:398
+msgid ""
+"`fmt!` supports most of the directives that [printf][pf] supports, but "
+"unlike printf, will give you a compile-time error when the types of the "
+"directives don't match the types of the arguments."
+msgstr ""
+"`fmt!` は、[`printf`][pf] がサポートするほとんどのディレクティブ (フォーマッ"
+"ト指定子) をサポートしますが、`printf` とは異なり、ディレクティブと引数の型が"
+"一致しない場合はコンパイルエラーとなります。"
+
+#. type: Plain text
+#: doc/tutorial.md:401
+msgid "~~~~ # let mystery_object = ();"
+msgstr ""
+"~~~~\n"
+"# let mystery_object = ();"
+
+#. type: Plain text
+#: doc/tutorial.md:403
+msgid "println(fmt!(\"%s is %d\", \"the answer\", 43));"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:407
+msgid ""
+"// %? will conveniently print any type println(fmt!(\"what is this thing: %?"
+"\", mystery_object)); ~~~~"
+msgstr ""
+"// %? は任意の型を表示できる便利なディレクティブです\n"
+"println(fmt!(\"what is this thing: %?\", mystery_object));\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:409
+msgid "[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:411
+msgid ""
+"You can define your own syntax extensions with the macro system. For "
+"details, see the [macro tutorial][macros]."
+msgstr ""
+"マクロシステムを利用すれば、独自に構文拡張を定義することも可能です。詳細は "
+"[マクロチュートリアル][macros] を参照してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:413
+msgid "# Control structures"
+msgstr "# 制御構造"
+
+#. type: Plain text
+#: doc/tutorial.md:415
+msgid "## Conditionals"
+msgstr "## 条件式"
+
+#. type: Plain text
+#: doc/tutorial.md:419
+msgid ""
+"We've seen `if` expressions a few times already. To recap, braces are "
+"compulsory, an `if` can have an optional `else` clause, and multiple `if`/"
+"`else` constructs can be chained together:"
+msgstr ""
+"`if` 式は既に何度か登場しています。これまでの説明の要点をまとめると、波括弧は"
+"省略不可であり、`if` 式には省略可能な `else` 句があり、複数個の `if`/`else` "
+"構文は互いに連鎖できる、ということでした。"
+
+#. type: Plain text
+#: doc/tutorial.md:429
+#, no-wrap
+msgid ""
+"~~~~\n"
+"if false {\n"
+"    println(\"that's odd\");\n"
+"} else if true {\n"
+"    println(\"right\");\n"
+"} else {\n"
+"    println(\"neither true nor false\");\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:434
+msgid ""
+"The condition given to an `if` construct *must* be of type `bool` (no "
+"implicit conversion happens). If the arms are blocks that have a value, this "
+"value must be of the same type for every arm in which control reaches the "
+"end of the block:"
+msgstr ""
+"`if` 構文の条件式は `bool` 型ででなければなりません (暗黙的な型変換は行われま"
+"せん)。同一の `if` 構文に属する arm のうち、制御がブロックの末尾まで到達し得"
+"るものは、すべて同じ型の値でなければなりません。"
+
+#. type: Plain text
+#: doc/tutorial.md:442
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn signum(x: int) -> int {\n"
+"    if x < 0 { -1 }\n"
+"    else if x > 0 { 1 }\n"
+"    else { return 0 }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:444
+msgid "## Pattern matching"
+msgstr "## パターンマッチ"
+
+#. type: Plain text
+#: doc/tutorial.md:450
+msgid ""
+"Rust's `match` construct is a generalized, cleaned-up version of C's "
+"`switch` construct. You provide it with a value and a number of *arms*, each "
+"labelled with a pattern, and the code compares the value against each "
+"pattern in order until one matches. The matching pattern executes its "
+"corresponding arm."
+msgstr ""
+"Rust の `match` 構文は、C の `switch` 構文を整理・一般化したものです。"
+"`match` 構文は、パターンマッチの対象となる値と、いくつかの、 **arm**  (**訳"
+"注:** 分岐条件と、条件を満たした場合に実行される式の組のこと。`match` の場合"
+"はパターンと式の組) から構成されます。`match` 構文では、指定された値とパター"
+"ンの比較をコード内で記述された順番通りに行います。比較の結果、値とパターンが"
+"マッチした場合、対応する式が実行されます。マッチしたパターンの後に現れるパ"
+"ターンとの比較は行われません。"
+
+#. type: Plain text
+#: doc/tutorial.md:460
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# let my_number = 1;\n"
+"match my_number {\n"
+"  0     => println(\"zero\"),\n"
+"  1 | 2 => println(\"one or two\"),\n"
+"  3..10 => println(\"three to ten\"),\n"
+"  _     => println(\"something else\")\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:464
+msgid ""
+"Unlike in C, there is no \"falling through\" between arms: only one arm "
+"executes, and it doesn't have to explicitly `break` out of the construct "
+"when it is finished."
+msgstr ""
+"C とは異なり、Rust では arm 間での「フォールスルー」はないため、1つの arm の"
+"みが実行されます。 そのため、 `match` 構文から抜ける箇所を `break` により明示"
+"する必要はありません。"
+
+#. type: Plain text
+#: doc/tutorial.md:474
+msgid ""
+"A `match` arm consists of a *pattern*, then an arrow `=>`, followed by an "
+"*action* (expression). Literals are valid patterns and match only their own "
+"value. A single arm may match multiple different patterns by combining them "
+"with the pipe operator (`|`), so long as every pattern binds the same set of "
+"variables. Ranges of numeric literal patterns can be expressed with two "
+"dots, as in `M..N`. The underscore (`_`) is a wildcard pattern that matches "
+"any single value. The asterisk (`*`)  is a different wildcard that can match "
+"one or more fields in an `enum` variant."
+msgstr ""
+"`match` の arm は、 **パターン** および矢印 `=>` と、それらに続く **アクショ"
+"ン** (式) から構成されます。リテラルはパターンとして利用可能で、リテラル自身"
+"の値のみとマッチするパターンを意味します。複数のパターンをパイプ演算子 (`|`) "
+"で結合させることで、複数の異なるパターンにマッチする単一の arm を作ることがで"
+"きます。ただし、変数の束縛を行うパターンをパイプ演算子で結合する場合は、すべ"
+"てのパータンで束縛する変数の名前・数が一致している必要があります (**訳注:** "
+"変数の束縛については、本節の後半で説明します)。指定した範囲に含まれる任意の数"
+"値にマッチするパターンは、2つのドットで `M..N` のように表記します。アンダース"
+"コア (`_`) は任意の値1つにマッチするワイルドカードパターンです。アスタリスク "
+"(`*`) は任意の値をもつ、`enum` バリアントの複数のフィールドにマッチする、ワイ"
+"ルドカードです (**訳注** `enum` については、[列挙型](#列挙型) の節で説明しま"
+"す)。"
+
+#. type: Plain text
+#: doc/tutorial.md:479
+msgid ""
+"The patterns in a match arm are followed by a fat arrow, `=>`, then an "
+"expression to evaluate. Each case is separated by commas. It's often "
+"convenient to use a block expression for each case, in which case the commas "
+"are optional."
+msgstr ""
+"`match` の各 arm はカンマ (`,`) は区切ります。 arm のアクションとしてブロック"
+"を記述することも可能で、その場合は arm 末尾のカンマを省略することが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:487
+#, no-wrap
+msgid ""
+"~~~\n"
+"# let my_number = 1;\n"
+"match my_number {\n"
+"  0 => { println(\"zero\") }\n"
+"  _ => { println(\"something else\") }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:492
+msgid ""
+"`match` constructs must be *exhaustive*: they must have an arm covering "
+"every possible case. For example, the typechecker would reject the previous "
+"example if the arm with the wildcard pattern was omitted."
+msgstr ""
+"`match` 構文は **網羅的** でなければなりません。すなわち、`match` 対象の値と"
+"同じ型を持つ任意の値に対し、少なくとも 1 つ以上のパターンがマッチするだけの "
+"arm を含んでいなければなりません。例えば、上記コード例のワイルドカードパター"
+"ンの arm を削除した場合、型検査によりコンパイルエラーとされます。"
+
+#. type: Plain text
+#: doc/tutorial.md:496
+msgid ""
+"A powerful application of pattern matching is *destructuring*: matching in "
+"order to bind names to the contents of data types."
+msgstr ""
+"パターンマッチの応用として、 **destructuring** という強力な機能があります。構"
+"造化代入とは、データ型内部の値を名前に束縛 (bind) することです。"
+
+#. type: Plain text
+#: doc/tutorial.md:500
+msgid ""
+"> ***Note:*** The following code makes use of tuples (`(float, float)`) "
+"which > are explained in section 5.3. For now you can think of tuples as a "
+"list of > items."
+msgstr ""
+"> ***注意:*** 以下のコード例では5.3 節で説明されるタプル (`(float, float)`) "
+"を使っています。現時点では、タプルは項目のリストのようなものだとみなしてくだ"
+"さい。"
+
+#. type: Plain text
+#: doc/tutorial.md:513
+#, 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) => atan(y / x)\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:519
+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)` "
+"matches any tuple whose first element is zero, and binds `y` to the second "
+"element. `(x, y)` matches any two-element tuple, and binds both elements to "
+"variables."
+msgstr ""
+"パターン内に登場する変数は、任意の値にマッチ **するだけでなく**、arm のアク"
+"ション内ではマッチした値が変数の名前に束縛されます。従って、 `(0f, y)` は1つ"
+"目の要素が 0 である任意のタプルにマッチし、 `y` には2つ目の要素の値が束縛され"
+"ます。`(x, y)` は任意の2要素のタプルにマッチし、タプルの各要素がそれぞれの変"
+"数に束縛されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:526
+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, "
+"after the pattern is found to match, whether the arm is taken or not. The "
+"variables bound by the pattern are in scope in this guard expression. The "
+"first arm in the `angle` example shows an example of a pattern guard."
+msgstr ""
+"`match` の任意の arm は **パターンガード** と呼ばれる、ガード節 (`if EXPR` と"
+"書かれる) を持つことができます。パターンガードは、 `bool` 型の値をもつ式で、"
+"値にマッチするパターンが見つかった後に評価され、arm が実行されるかどうかを決"
+"定します。パターンにより束縛される変数は、ガード式からも参照可能 (ガード式の"
+"スコープに含まれる) です。`angle` 関数の例の最初の arm に、パターンガードの使"
+"用例が示されています。"
+
+#. type: Plain text
+#: doc/tutorial.md:531
+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. "
+"For example, you can write this to extract the fields from a tuple, "
+"introducing two variables at once: `a` and `b`."
+msgstr ""
+"`let` は単純な変数束縛だけではなく、パターンによる destructuring をサポートし"
+"ています。例えば、タプルからフィールドを抽出し、1度に2つの変数 `a` と `b` を"
+"定義することが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:536
+msgid ""
+"~~~~ # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) } let (a, b) = "
+"get_tuple_of_two_ints(); ~~~~"
+msgstr ""
+"~~~~\n"
+"# fn get_tuple_of_two_ints() -> (int, int) { (1, 1) }\n"
+"let (a, b) = get_tuple_of_two_ints();\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:540
+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 "
+"`enum` variants."
+msgstr ""
+"let による変数定義が可能なのは、パターンが __不可反駁__ (iefutable; 必ず値に"
+"マッチする) な場合のみです。この制限により、`let` を用いた destructuring で、"
+"リテラルやほとんどの `enum` バリアントをパターンとして用いることはできませ"
+"ん。"
+
+#. type: Plain text
+#: doc/tutorial.md:542
+msgid "## Loops"
+msgstr "## ループ"
+
+#. type: Plain text
+#: doc/tutorial.md:547
+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 "
+"`break` aborts the loop, and `loop` aborts the current iteration and "
+"continues with the next."
+msgstr ""
+"`while` は、与えられた条件 (`bool` 型の値でなければならない) が `true` と評価"
+"されている間、繰り返し実行されるループを表します。`break` キーワードは、ルー"
+"プの実行を中断させます。`loop` キーワードは、現在実行中の繰り返し (イテレー"
+"ション) を中断し、次の繰り返しを実行します。"
+
+#. type: Plain text
+#: doc/tutorial.md:554
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let mut cake_amount = 8;\n"
+"while cake_amount > 0 {\n"
+"    cake_amount -= 1;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:556
+msgid ""
+"`loop` denotes an infinite loop, and is the preferred way of writing `while "
+"true`:"
+msgstr ""
+"`loop` は無限ループを表します。 `while true` と書く代わりに `loop` と書くこと"
+"が推奨されています。"
+
+#. type: Plain text
+#: doc/tutorial.md:566
+#, no-wrap
+msgid ""
+"~~~~\n"
+"use std::int;\n"
+"let mut x = 5;\n"
+"loop {\n"
+"    x += x - 3;\n"
+"    if x % 5 == 0 { break; }\n"
+"    println(int::to_str(x));\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:569
+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 "このコードは 5 で割り切れる数値が現れるまで、数値を出力し続けます。"
+
+#. type: Plain text
+#: doc/tutorial.md:571
+msgid "# Data structures"
+msgstr "# データ構造"
+
+#. type: Plain text
+#: doc/tutorial.md:573
+msgid "## Structs"
+msgstr "## 構造体"
+
+#. type: Plain text
+#: doc/tutorial.md:578
+msgid ""
+"Rust struct types must be declared before they are used using the `struct` "
+"syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, "
+"`T2`, ... denote types. To construct a struct, use the same syntax, but "
+"leave off the `struct`: for example: `Point { x: 1.0, y: 2.0 }`."
+msgstr ""
+"Rust の構造体 (struct) 型を利用するためには、`struct Name { field1: T1, "
+"field2: T2 [, ...] }` (`T1`, `T2`, .. は型を意味する) のように、 `struct` 構"
+"文を使った型の宣言が必要です。構造体型の値は、`Point { x: 1.0, y: 2.0 }` のよ"
+"うに、構造体宣言から `struct` を取り除いたものと同じ構文で作成します。"
+
+#. type: Plain text
+#: doc/tutorial.md:582
+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 "
+"dot operator to access struct fields, as in `mypoint.x`."
+msgstr ""
+"Rust の構造体は C の構造体とよく似ており、メモリ上のレイアウトも C と同じで"
+"す (そのため、Rust と C で相互に構造体を読み込むことが可能です)。構造体の"
+"フィールドにアクセスするには、 `mypoint.x` のように、ドット演算子を用います。"
+
+#. type: Plain text
+#: doc/tutorial.md:589
+#, no-wrap
+msgid ""
+"~~~~\n"
+"struct Point {\n"
+"    x: float,\n"
+"    y: float\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:593
+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 "
+"so forth)."
+msgstr ""
+"継承ミュータビリティ (inherited mutability) とは、構造体自体がミュータブルな"
+"スロットに配置されている場合、構造体のすべてのフィールドもミュータブルになる"
+"という性質を意味する言葉です (ミュータブルなスロットに配置された構造体の"
+"フィールドに配置された構造体のフィールドもまた、ミュータブルになります) 。"
+
+#. type: Plain text
+#: doc/tutorial.md:597
+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 "
+"struct without inherited mutability would result in a type error."
+msgstr ""
+"ある構造体の値 (仮に `mypoint` とします) がミュータブルな場所に配置された場"
+"合、 `mypoint.y += 1.0` というような操作を行うことができます。しかし、構造体"
+"がイミュータブルな場所に配置された場合、ミュータビリティは継承されないため、"
+"このような代入操作は型エラーとなります。"
+
+#. type: Plain text
+#: doc/tutorial.md:602
+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 ""
+"~~~~ {.xfail-test}\n"
+"# struct Point { x: float, y: float }\n"
+"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
+"let origin = Point { x: 0.0, y: 0.0 };"
+
+#. type: Plain text
+#: doc/tutorial.md:606
+msgid ""
+"mypoint.y += 1.0; // mypoint is mutable, and its fields as well origin.y += "
+"1.0; // ERROR: assigning to immutable field ~~~~"
+msgstr ""
+"mypoint.y += 1.0;\n"
+"// mypoint はミュータブル\n"
+"origin.y += 1.0; // ERROR: assigning to immutable field\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:609
+msgid ""
+"`match` patterns destructure structs. The basic syntax is `Name { fieldname: "
+"pattern, ... }`:"
+msgstr ""
+"`match` のパターンで構造体の destructuring を行うことも可能です。パターン"
+"は、 `Name { fieldname: pattern, ... }` という構文を持ちます。"
+
+#. type: Plain text
+#: doc/tutorial.md:618
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# let mypoint = Point { x: 0.0, y: 0.0 };\n"
+"match mypoint {\n"
+"    Point { x: 0.0, y: yy } => { println(yy.to_str());                     }\n"
+"    Point { x: xx,  y: yy } => { println(xx.to_str() + \" \" + yy.to_str()); }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:625
+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 "
+"of a struct, a struct pattern may end with `, _` (as in `Name { field1, _ }"
+"`) to indicate that you're ignoring all other fields.  Additionally, struct "
+"fields have a shorthand matching form that simply reuses the field name as "
+"the binding name."
+msgstr ""
+"構造体のフィールド名の並び順は、型定義での並び順と同じにする必要はありませ"
+"ん。構造体のパターンマッチで、すべてのフィールドについて考える必要がない場合"
+"は、`Name { field1, _ }` のように、末尾に `, _` をつけることで、他のすべての"
+"フィールドを無視することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:633
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# let mypoint = Point { x: 0.0, y: 0.0 };\n"
+"match mypoint {\n"
+"    Point { x, _ } => { println(x.to_str()) }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:635
+msgid "## Enums"
+msgstr "## 列挙型"
+
+#. type: Plain text
+#: doc/tutorial.md:638
+msgid ""
+"Enums are datatypes that have several alternate representations. For "
+"example, consider the type shown earlier:"
+msgstr ""
+"列挙型 (enum) は、いくつかの代替表現を持つデータ型です。例えば、以下の型につ"
+"いて考えます。"
+
+#. type: Plain text
+#: doc/tutorial.md:646
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# struct Point { x: float, y: float }\n"
+"enum Shape {\n"
+"    Circle(Point, float),\n"
+"    Rectangle(Point, Point)\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:652
+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 "
+"`Point` structs. The run-time representation of such a value includes an "
+"identifier of the actual form that it holds, much like the \"tagged union\" "
+"pattern in C, but with better static guarantees."
+msgstr ""
+"この型の値は、`Point` 構造体と `float` を含む `Circle` か、2つの `Point` 構造"
+"体を含む `Rectangle` のどちらかになります。列挙型の値の実行時表現には、値がど"
+"の形式をとっているのか示す識別子が含まれます。この表現方法は C の \"タグ付き"
+"共用体\" と非常によく似ていますが、Rust の列挙型はコンパイラにより値の正当性"
+"が静的に保証されるという点でより良いものとなっています。"
+
+#. type: Plain text
+#: doc/tutorial.md:658
+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 "
+"construct values of the type (taking arguments of the specified types). So "
+"`Circle(Point { x: 0f, y: 0f }, 10f)` is the way to create a new circle."
+msgstr ""
+"上記の宣言は `Shape` 型と `Circle` と `Rectangle` という2つの関数も同時に定義"
+"します。これらの関数により、関数名に対応した `Shape` 型の値を構築することがで"
+"きます (引数の型も列挙型宣言時に指定されたものをとります)。例えば、"
+"`Circle(Point { x: 0f, y: 0f }, 10f)` という記述により、新しい circle を作る"
+"ことができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:661
+msgid ""
+"Enum variants need not have parameters. This `enum` declaration, for "
+"example, is equivalent to a C enum:"
+msgstr ""
+"列挙型のバリアントはパラメータを省略することもできます。以下の例の `enum` 宣"
+"言は C の列挙型と等価です。"
+
+#. type: Plain text
+#: doc/tutorial.md:670
+#, no-wrap
+msgid ""
+"~~~~\n"
+"enum Direction {\n"
+"    North,\n"
+"    East,\n"
+"    South,\n"
+"    West\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:673
+msgid ""
+"This declaration defines `North`, `East`, `South`, and `West` as constants, "
+"all of which have type `Direction`."
+msgstr ""
+"この宣言は `Direction` 型の定数 `North`, `East`, `South`, `West` を定義しま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:677
+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 "
+"value:"
+msgstr ""
+"列挙型が Cライクな (すべてのバリアントがパラメータを持たない) 場合、各定数の"
+"識別値 (discriminator value) を明示的に指定することも可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:685
+#, no-wrap
+msgid ""
+"~~~~\n"
+"enum Color {\n"
+"  Red = 0xff0000,\n"
+"  Green = 0x00ff00,\n"
+"  Blue = 0x0000ff\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:690
+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 "
+"does not have a discriminator, it defaults to 0. For example, the value of "
+"`North` is 0, `East` is 1, `South` is 2, and `West` is 3."
+msgstr ""
+"バリアントの識別値が明に指定されていない場合、1つ前のバリアントの値に1を足し"
+"たものが設定されます。また、最初のバリアントの場合は0が設定されます。上記の例"
+"で言うと、 `North` は 0、 `East` は 1、 `South` は 2、`West` は3となります。"
+
+#. type: Plain text
+#: doc/tutorial.md:693
+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 ""
+"C ライクな列挙型の値は、キャスト演算子 `as` を適用することで、`int` 型の識別"
+"値へ変換することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:697
+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 "
+"this definition of `area`:"
+msgstr ""
+"複数のバリアントを持つ列挙型で、列挙型値の内部のデータを取得するには、 "
+"destructuring を使う必要があります。以下の `area` 関数の例のように、バリアン"
+"トのコンストラクタは、パターンとして用いることもできます。"
+
+#. type: Plain text
+#: doc/tutorial.md:709
+#, no-wrap
+msgid ""
+"~~~~\n"
+"use std::float;\n"
+"# struct Point {x: float, y: float}\n"
+"# enum Shape { Circle(Point, float), Rectangle(Point, Point) }\n"
+"fn area(sh: Shape) -> float {\n"
+"    match sh {\n"
+"        Circle(_, size) => float::consts::pi * size * size,\n"
+"        Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:714
+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, "
+"nullary enum patterns are written without parentheses."
+msgstr ""
+"パターンマッチの際に、特定のフィールドに対するマッチングが不要な場合、無視し"
+"たいフィールドの場所に `_` を書くことで、個々のフィールドを無視することができ"
+"ます。また、 `Circle(*)` のように書くことで、すべてのフィールドを無視すること"
+"も可能です。引数をとらない列挙型のパターンは、定義時の形式と同様、丸括弧の無"
+"い形式で記述します。"
+
+#. type: Plain text
+#: doc/tutorial.md:727
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Direction { North, East, South, West }\n"
+"fn point_from_direction(dir: Direction) -> Point {\n"
+"    match dir {\n"
+"        North => Point { x:  0f, y:  1f },\n"
+"        East  => Point { x:  1f, y:  0f },\n"
+"        South => Point { x:  0f, y: -1f },\n"
+"        West  => Point { x: -1f, y:  0f }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:729
+msgid "Enum variants may also be structs. For example:"
+msgstr "以下の例のように、列挙型バリアントを構造体にすることも可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:747
+#, no-wrap
+msgid ""
+"~~~~\n"
+"use std::float;\n"
+"# struct Point { x: float, y: float }\n"
+"# fn square(x: float) -> float { x * x }\n"
+"enum Shape {\n"
+"    Circle { center: Point, radius: float },\n"
+"    Rectangle { top_left: Point, bottom_right: Point }\n"
+"}\n"
+"fn area(sh: Shape) -> float {\n"
+"    match sh {\n"
+"        Circle { radius: radius, _ } => float::consts::pi * square(radius),\n"
+"        Rectangle { top_left: top_left, bottom_right: bottom_right } => {\n"
+"            (bottom_right.x - top_left.x) * (bottom_right.y - top_left.y)\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:749
+msgid "## Tuples"
+msgstr "## タプル"
+
+#. type: Plain text
+#: doc/tutorial.md:754
+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 "
+"can have any arity except for 0 (though you may consider unit, `()`, as the "
+"empty tuple if you like)."
+msgstr ""
+"Rust のタプルは、フィールドが名前を持たないという点以外は、構造体と同じように"
+"振る舞います。フィールド名が存在しないため、ドット記法を使ってタプルのフィー"
+"ルドにアクセスすることはできません。タプルは 1 個以上の要素を持つことができま"
+"す (必要ならば、ユニット型 `()` を 0 要素のタプルと見なすことはできます。)"
+
+#. type: Plain text
+#: doc/tutorial.md:761
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let mytup: (int, int, float) = (10, 20, 30.0);\n"
+"match mytup {\n"
+"  (a, b, c) => info!(a + b + (c as int))\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:763
+msgid "## Tuple structs"
+msgstr "## タプル構造体"
+
+#. type: Plain text
+#: doc/tutorial.md:768
+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 "
+"different type from `Bar(1, 2)`), and tuple structs' _fields_ do not have "
+"names."
+msgstr ""
+"Rust には __タプル構造体__ と呼ばれる、構造体とタプルの両者の特徴を併せ持つも"
+"のが存在します。タプルと異なり、タプル構造体自体は名前を持ちます (従って、"
+"`Foo(1, 2)` と `Bar(1, 2)` は異なる型になります。) しかし、タプル構造体の __"
+"フィールド__ は名前を持ちません。"
+
+#. type: Plain text
+#: doc/tutorial.md:777
+#, no-wrap
+msgid ""
+"For example:\n"
+"~~~~\n"
+"struct MyTup(int, int, float);\n"
+"let mytup: MyTup = MyTup(10, 20, 30.0);\n"
+"match mytup {\n"
+"  MyTup(a, b, c) => info!(a + b + (c as int))\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"struct MyTup(int, int, float);\n"
+"let mytup: MyTup = MyTup(10, 20, 30.0);\n"
+"match mytup {\n"
+"  MyTup(a, b, c) => info!(a + b + (c as int))\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:779
+msgid "<a name=\"newtype\"></a>"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:784
+msgid ""
+"There is a special case for tuple structs with a single field, which are "
+"sometimes called \"newtypes\" (after Haskell's \"newtype\" feature). These "
+"are used to define new types in such a way that the new name is not just a "
+"synonym for an existing type but is rather its own distinct type."
+msgstr ""
+"タプル構造体がフィールドを 1 つしか持たない場合、 \"newtype\" と呼ばれること"
+"があります (Haskell の \"newtype\" 機能に由来しています)。 このようなタプル構"
+"造体を使うことで、既存の型の別名 (シノニム) となる新しい型を定義することがで"
+"きます。この新しい型は、元にした型とは異なった型として扱われます。"
+
+#. type: Plain text
+#: doc/tutorial.md:788
+msgid "~~~~ struct GizmoId(int); ~~~~"
+msgstr ""
+"~~~~\n"
+"struct GizmoId(int);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:791
+msgid ""
+"For convenience, you can extract the contents of such a struct with the "
+"dereference (`*`) unary operator:"
+msgstr ""
+"便宜上、デリファレンス単項演算子 (`*`) により、タプル構造体の内容を展開するこ"
+"とが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:797
+msgid ""
+"~~~~ # struct GizmoId(int); let my_gizmo_id: GizmoId = GizmoId(10); let "
+"id_int: int = *my_gizmo_id; ~~~~"
+msgstr ""
+"~~~~\n"
+"# struct GizmoId(int);\n"
+"let my_gizmo_id: GizmoId = GizmoId(10);\n"
+"let id_int: int = *my_gizmo_id;\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:800
+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:805
+msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~"
+msgstr ""
+"~~~~\n"
+"struct Inches(int);\n"
+"struct Centimeters(int);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:808
+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:810
+msgid "# Functions"
+msgstr "# 関数"
+
+#. type: Plain text
+#: doc/tutorial.md:818
+msgid ""
+"We've already seen several function definitions. Like all other static "
+"declarations, such as `type`, functions can be declared both at the top "
+"level and inside other functions (or in modules, which we'll come back to "
+"[later](#modules-and-crates)). The `fn` keyword introduces a function. A "
+"function has an argument list, which is a parenthesized list of `expr: type` "
+"pairs separated by commas. An arrow `->` separates the argument list and the "
+"function's return type."
+msgstr ""
+"関数定義はこれまでに何度か登場しています。他の静的な宣言 (`type` など)と同様"
+"に、関数はトップレベルまたは、他の関数の内部、モジュールの内部で定義すること"
+"ができます (モジュールについては、[後述](#モジュールとクレート)します) 。"
+
+#. type: Plain text
+#: doc/tutorial.md:824
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn line(a: int, b: int, x: int) -> int {\n"
+"    return a * x + b;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:829
+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 "
+"value by having its top-level block produce an expression."
+msgstr ""
+"`return` キーワードにより、呼び出し中の関数を即座に復帰させることができます。"
+"`return` の後に式を書くことで、呼び出し元へ戻り値として返すことも可能です。ま"
+"た、関数トップレベルのブロックを式と解釈した場合の値 (ブロック内最後の式の"
+"値) も関数の戻り値になります。"
+
+#. type: Plain text
+#: doc/tutorial.md:835
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn line(a: int, b: int, x: int) -> int {\n"
+"    a * x + b\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:842
+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 "
+"from a function. Functions that do not return a value are said to return "
+"nil, `()`, and both the return type and the return value may be omitted from "
+"the definition. The following two functions are equivalent."
+msgstr ""
+"Rust では、明示的に `return` を書くのではなく、上記のような方法で戻り値を返す"
+"スタイルが推奨されています。 `return` は、関数を途中で復帰させたい場合に使い"
+"ます。値を返さない関数は、 nil `()` を返す関数として取り扱われ、関数の戻り値"
+"の型や、戻り値を返す処理を省略することが可能です。以下の2つの関数は等価です。"
+
+#. type: Plain text
+#: doc/tutorial.md:845
+msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }"
+msgstr ""
+"~~~~\n"
+"fn do_nothing_the_hard_way() -> () { return (); }"
+
+#. type: Plain text
+#: doc/tutorial.md:848
+msgid "fn do_nothing_the_easy_way() { } ~~~~"
+msgstr ""
+"fn do_nothing_the_easy_way() { }\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:850
+msgid ""
+"Ending the function with a semicolon like so is equivalent to returning `()`."
+msgstr "以下のように、セミコロンで終わる関数は `()` を返す関数と等価です。"
+
+#. type: Plain text
+#: doc/tutorial.md:854
+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 ""
+"~~~~\n"
+"fn line(a: int, b: int, x: int) -> int { a * x + b }\n"
+"fn oops(a: int, b: int, x: int) -> ()  { a * x + b; }"
+
+#. type: Plain text
+#: doc/tutorial.md:858
+msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~"
+msgstr ""
+"assert!(8 == line(5, 3, 1));\n"
+"assert!(() == oops(5, 3, 1));\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:862
+msgid ""
+"As with `match` expressions and `let` bindings, function arguments support "
+"pattern destructuring. Like `let`, argument patterns must be irrefutable, as "
+"in this example that unpacks the first value from a tuple and returns it."
+msgstr ""
+"`match` 式や `let` による変数定義のように、関数の引数もパターンによる "
+"destructuring をサポートしています。`let` と同様、引数のパターンは 不可反駁 "
+"(irrefutable) でなければなりません。以下の例では、タプルの最初の要素を取得"
+"し、呼び出し元へ返します。"
+
+#. type: Plain text
+#: doc/tutorial.md:866
+msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~"
+msgstr ""
+"~~~\n"
+"fn first((value, _): (int, float)) -> int { value }\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:868 doc/tutorial-ffi.md:143
+msgid "# Destructors"
+msgstr "# デストラクタ"
+
+#. type: Plain text
+#: doc/tutorial.md:872
+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 "
+"handle the release of resources like files, sockets and heap memory."
+msgstr ""
+"**デストラクタ** はアクセスできなくなったオブジェクトから利用されていたリソー"
+"スを解放する役割を持つ関数です。デストラクタはファイルやソケット、ヒープメモ"
+"リのようなリソースの解放を処理するために定義することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:876
+msgid ""
+"Objects are never accessible after their destructor has been called, so "
+"there are no dynamic failures from accessing freed resources. When a task "
+"fails, the destructors of all objects in the task are called."
+msgstr ""
+"オブジェクトは、デストラクタが呼び出された後にアクセス不能になります。そのた"
+"め、解放済みリソースへアクセスしたことによる動的なエラーは発生しません。タス"
+"クの実行に失敗した場合、タスクに属するすべてのオブジェクトのデストラクタが呼"
+"び出されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:878
+msgid ""
+"The `~` sigil represents a unique handle for a memory allocation on the heap:"
+msgstr ""
+"シジル `~` はヒープに獲得されたメモリへのユニークな (唯一の) ハンドルを表しま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:886
+#, no-wrap
+msgid ""
+"~~~~\n"
+"{\n"
+"    // an integer allocated on the heap\n"
+"    let y = ~10;\n"
+"}\n"
+"// the destructor frees the heap memory as soon as `y` goes out of scope\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:890
+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 "
+"custom destructor."
+msgstr ""
+"Rust はヒープメモリ獲得のための構文を持っています。これは、ヒープメモリ獲得が"
+"よく利用されるというのが理由ですが、同じ動作は独自のデストラクタを持つ型によ"
+"り実装することが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:892
+msgid "# Ownership"
+msgstr "# 所有権"
+
+#. type: Plain text
+#: doc/tutorial.md:897
+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 "
+"object's owner is responsible for managing the lifetime of the object by "
+"calling the destructor, and the owner determines whether the object is "
+"mutable."
+msgstr ""
+"Rust は、オブジェクトの寿命の管理を変数またはタスクローカルのガベージコレクタ"
+"に委譲するために、オブジェクトの所有権という考え方を取り入れています。オブ"
+"ジェクトの所有者はデストラクタを呼び出すことにより、オブジェクトの寿命を管理"
+"する責任を負っています。また、所有者はオブジェクトがミュータブルかどうかも判"
+"断します。"
+
+#. type: Plain text
+#: doc/tutorial.md:903
+msgid ""
+"Ownership is recursive, so mutability is inherited recursively and a "
+"destructor destroys the contained tree of owned objects. Variables are top-"
+"level owners and destroy the contained object when they go out of scope. A "
+"box managed by the garbage collector starts a new ownership tree, and the "
+"destructor is called when it is collected."
+msgstr ""
+"所有権は再帰的であるため、ミュータビリティは再帰的に継承され、デストラクタは"
+"所有しているオブジェクトの含まれているツリーを破壊します。変数はトップレベル"
+"の所有者です。変数の存在しているスコープを抜けるタイミングで、変数は所有して"
+"いるオブジェクトを破棄します。ガベージコレクタによって管理されるボックスは、"
+"新しい所有権ツリーを生成し、ガベージコレクタによりオブジェクトが回収されると"
+"きにデストラクタが呼び出されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:907
+msgid ""
+"~~~~ // the struct owns the objects contained in the `x` and `y` fields "
+"struct Foo { x: int, y: ~int }"
+msgstr ""
+"~~~~\n"
+"// この構造体はフィールド `x` と `y` に含まれるオブジェクトを所有している\n"
+"struct Foo { x: int, y: ~int }"
+
+#. type: Plain text
+#: doc/tutorial.md:914
+#, no-wrap
+msgid ""
+"{\n"
+"    // `a` is the owner of the struct, and thus the owner of the struct's fields\n"
+"    let a = Foo { x: 5, y: ~10 };\n"
+"}\n"
+"// when `a` goes out of scope, the destructor for the `~int` in the struct's\n"
+"// field is called\n"
+msgstr ""
+"{\n"
+"    // `a` は構造体の所有者であり、構造体のフィールドの所有者でもある\n"
+"    let a = Foo { x: 5, y: ~10 };\n"
+"}\n"
+"// `a` の含まれているスコープから抜けるとき、 構造体のフィールドの `~int` のデストラクタが呼ばれる\n"
+
+#. type: Plain text
+#: doc/tutorial.md:919
+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 ""
+"// `b` はミュータブルなので、所有しているオブジェクトにもミュターブル性が継承"
+"される\n"
+"let mut b = Foo { x: 5, y: ~10 };\n"
+"b.x = 10;\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:925
+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 "
+"sent between tasks. Custom destructors can only be implemented directly on "
+"types that are `Owned`, but garbage-collected boxes can still *contain* "
+"types with custom destructors."
+msgstr ""
+"オブジェクトにガベージコレクトされるボックスが含まれていない場合、オブジェク"
+"トは単一の継承ツリーからの構成され、`Owned` トレイトが付与されます。`Owned` "
+"トレイトが付与されたデータは、タスク間を跨いで受け渡すことが可能です。独自の"
+"デストラクタは、`Owned` トレイトを満たす型に対して直接実装されなければなりま"
+"せんが、ガベージコレクトされるボックスが独自のデストラクタをもつ型を **含む"
+"** ことは依然可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:927
+msgid "# Boxes"
+msgstr "# ボックス"
+
+#. type: Plain text
+#: doc/tutorial.md:934
+msgid ""
+"Many modern languages represent values as pointers to heap memory by "
+"default. In contrast, Rust, like C and C++, represents such types directly.  "
+"Another way to say this is that aggregate data in Rust are *unboxed*. This "
+"means that if you `let x = Point { x: 1f, y: 1f };`, you are creating a "
+"struct on the stack. If you then copy it into a data structure, you copy the "
+"entire struct, not just a pointer."
+msgstr ""
+"多くのモダンな言語では、デフォルトで、値はヒープメモリへのポインタとして表さ"
+"れます。一方、Rust は C や C++ のように、これらの型を直接取り扱うことができま"
+"す。言い換えると、集積データは **ボックス化されていない** ということです。つ"
+"まり、`let x = Point { x: 1f, y: 1f };` というコードは、スタック上に構造体を"
+"作成することを意味します。この構造体を別のデータ構造の中へコピーする場合、ポ"
+"インタのコピーではなく構造体全体をコピーすることになります。"
+
+#. type: Plain text
+#: doc/tutorial.md:939
+msgid ""
+"For small structs like `Point`, this is usually more efficient than "
+"allocating memory and indirecting through a pointer. But for big structs, or "
+"mutable state, it can be useful to have a single copy on the stack or on the "
+"heap, and refer to that through a pointer."
+msgstr ""
+"`Point` のような小さな構造体の場合、このような動作は、メモリを獲得しポインタ"
+"経由でアクセスするよりも一般的には効率的です。しかし、大きな構造体の場合や"
+"ミュータブルな状態を持つようなものの場合、スタックまたはヒープ上に単一ののコ"
+"ピーをもち、ポインタ経由で参照する方が便利な場合もあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:941
+msgid "## Owned boxes"
+msgstr "## 所有ボックス"
+
+#. type: Plain text
+#: doc/tutorial.md:944
+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 ""
+"所有ボックス (Owned box, `~`) は、単一の所有者のみを持つ、ヒープ上に獲得され"
+"た領域です。所有ボックスは、ボックスが存在しない場合と同じように、所有者の"
+"ミュータビリティと寿命を継承します。"
+
+#. type: Plain text
+#: doc/tutorial.md:949
+msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;"
+msgstr ""
+"~~~~\n"
+"let x = 5; // イミュータブル\n"
+"let mut y = 5; // ミュータブル\n"
+"y += 2;"
+
+#. type: Plain text
+#: doc/tutorial.md:954
+msgid ""
+"let x = ~5; // immutable let mut y = ~5; // mutable *y += 2; // the * "
+"operator is needed to access the contained value ~~~~"
+msgstr ""
+"let x = ~5; // イミュータブル\n"
+"let mut y = ~5; // ミュータブル\n"
+"*y += 2; // ボックスの中身にアクセスするには、 * 演算子が必要\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:959
+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 "
+"than a pointer. Since an owned box has a unique owner, it can only be used "
+"to represent a tree data structure."
+msgstr ""
+"所有ボックスの目的は、再帰的なデータ型の作成や、ポインターのサイズより大きい"
+"オブジェクトを安価な方法で渡したりするための、関節参照のレイヤを追加すること"
+"です。所有ボックスは複数の所有者を持てないため、ツリー構造を持ったデータのみ"
+"を表すことが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:962
+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:968
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"struct Foo {\n"
+"    child: Option<Foo>\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:972
+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 "
+"stores the > contained value unboxed."
+msgstr ""
+"> ***注意*** `Option` 型は **オプショナルな** (値の有無を選択可能な) 値を表す"
+"列挙型です。`Option` 型は他の言語の null 値をとりうるポインタ型に相当します"
+"が、格納される値はボックス化されていません。"
+
+#. type: Plain text
+#: doc/tutorial.md:976
+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 "
+"compile-time error:"
+msgstr ""
+"所有ポインタによる関節参照を導入することで、`child` を構造体の外のヒープ上に"
+"獲得することができ、構造体のデータサイズは有限となるため、コンパイルエラーと"
+"はなりません。"
+
+#. type: Plain text
+#: doc/tutorial.md:982
+#, no-wrap
+msgid ""
+"~~~~\n"
+"struct Foo {\n"
+"    child: Option<~Foo>\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:984
+msgid "## Managed boxes"
+msgstr "## マネージドボックス"
+
+#. type: Plain text
+#: doc/tutorial.md:992
+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 "
+"no references left to the box, no later than the end of the task. Managed "
+"boxes lack an owner, so they start a new ownership tree and don't inherit "
+"mutability. They do own the contained object, and mutability is defined by "
+"the type of the managed box (`@` or `@mut`). An object containing a managed "
+"box is not `Owned`, and can't be sent between tasks."
+msgstr ""
+"マネージドボックス (`@`) は、タスクローカルなガベージコレクタにより寿命管理さ"
+"れる、ヒープ上に獲得された領域です。マネージドボックスは、ボックスへの参照が"
+"無くなった後、いずれかの時点で破棄されます。破棄のタイミングがタスク終了後に"
+"なることはありません。マネージドボックスは所有者を持たないので、新たな所有権"
+"ツリーを開始し、ミュータビリティを継承しません。マネージドボックスは、ボック"
+"スに含まれているオブジェクトを所有し、ミュータビリティはマネージドボックスの"
+"種別 (`@` または `@mut`) によって決定されます。マネージドボックスに含まれるオ"
+"ブジェクトは `Owned` を付与されず、タスク間で受け渡すことはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:995
+msgid "~~~~ let a = @5; // immutable"
+msgstr ""
+"~~~~\n"
+"let a = @5; // イミュータブル"
+
+#. type: Plain text
+#: doc/tutorial.md:998
+msgid "let mut b = @5; // mutable variable, immutable box b = @10;"
+msgstr ""
+"let mut b = @5; // ミュータブルな変数、イミュータブルなボックス\n"
+"b = @10;"
+
+#. type: Plain text
+#: doc/tutorial.md:1001
+msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;"
+msgstr ""
+"let c = @mut 5; // イミュータブルな変数、ミュータブルなボックス\n"
+"*c = 10;"
+
+#. type: Plain text
+#: doc/tutorial.md:1006
+msgid ""
+"let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; "
+"~~~~"
+msgstr ""
+"let mut d = @mut 5; // ミュータブルな変数、ミュータブルなボックス\n"
+"*d += 5;\n"
+"d = @mut 15;\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1011
+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 "
+"its type, however, so for example a mutable handle to an immutable box "
+"cannot be assigned a reference to a mutable box."
+msgstr ""
+"ミュータブルな変数とイミュータブルな変数は、それぞれの変数の型が同じであれ"
+"ば、同じボックスを参照することが可能です。ただし、ボックスのミュータビリティ"
+"は、型自体が持つ属性なので、ミュータブルなボックスの参照を、イミュータブルな"
+"ボックスを参照するミュータブルな変数 (handle) へ代入することはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1015
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let a = @1;     // immutable box\n"
+"let b = @mut 2; // mutable box\n"
+msgstr ""
+"~~~~\n"
+"let a = @1;     // イミュータブルなボックス\n"
+"let b = @mut 2; // ミュータブルなボックス\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1018
+#, no-wrap
+msgid ""
+"let mut c : @int;       // declare a variable with type managed immutable int\n"
+"let mut d : @mut int;   // and one of type managed mutable int\n"
+msgstr ""
+"let mut c : @int;       // イミュータブルなマネージド int 型の変数と、\n"
+"let mut d : @mut int;   // ミュータブルなマネージド int 型の変数の宣言\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1022
+#, no-wrap
+msgid ""
+"c = a;          // box type is the same, okay\n"
+"d = b;          // box type is the same, okay\n"
+"~~~~\n"
+msgstr ""
+"c = a;          // ボックスの型は変数の型と同じなので、OK\n"
+"d = b;          // ボックスの型は変数の型と同じなので、OK\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1027
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"// but b cannot be assigned to c, or a to d\n"
+"c = b;          // error\n"
+"~~~~\n"
+msgstr ""
+"~~~~ {.xfail-test}\n"
+"// しかし、 b は c に代入できないし、a は d に代入できない\n"
+"c = b;          // エラー\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1029
+msgid "# Move semantics"
+msgstr "# ムーブセマンティクス"
+
+#. type: Plain text
+#: doc/tutorial.md:1035
+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 "
+"the ownership tree of the copied value includes an owned box or a type with "
+"a custom destructor. After a value has been moved, it can no longer be used "
+"from the source location and will not be destroyed there."
+msgstr ""
+"Rust は関数パラメータの受け渡しや、変数への代入、関数からの戻り値を設定する際"
+"に、シャローコピーを使用しています。コピーされる値の所有権ツリーが所有ボック"
+"スや独自のデストラクタを持つ型を含んでいる場合、シャローコピーは所有権の移動"
+"とみなされます。値の移動が行われた後、元々その値を参照していた箇所からは値を"
+"利用することはできなくなり、もとの所有者から値が破壊されることもありません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1041
+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 ""
+"~~~~\n"
+"let x = ~5;\n"
+"let y = x.clone();\n"
+"// y は新しく獲得されるボックス\n"
+"let z = x; // 新たなメモリの獲得は行われない。x を使うことはできなくなる\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1044
+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:1051
+msgid ""
+"~~~~ let r = ~13; let mut s = r; // box becomes mutable *s += 1; let t = "
+"s; // box becomes immutable ~~~~"
+msgstr ""
+"~~~~\n"
+"let r = ~13;\n"
+"let mut s = r; // ボックスはミュータブルになる\n"
+"*s += 1;\n"
+"let t = s; // ボックスはイミュータブルになる\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1053
+msgid "# Borrowed pointers"
+msgstr "# 借用ポインタ"
+
+#. type: Plain text
+#: doc/tutorial.md:1059
+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 "
+"pointed-to memory, borrowed pointers never imply ownership. A pointer can be "
+"borrowed to any object, and the compiler verifies that it cannot outlive the "
+"lifetime of the object."
+msgstr ""
+"Rust の借用ポインタ (borrowed pointer) は汎用的な参照型です。所有ボックスの場"
+"合、ボックスの所有者が参照されているメモリの所有者となるのに対して、借用ポイ"
+"ンタを所有することがメモリを所有を意味することはありません。ポインタは任意の"
+"オブジェクトから借用することが可能で、参照先のオブジェクトよりもポインタが長"
+"生きしないことがコンパイラにより保証されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1061
+msgid "As an example, consider a simple struct type, `Point`:"
+msgstr "例として、シンプルな構造体型の `Point` について考えます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1068
+#, no-wrap
+msgid ""
+"~~~\n"
+"struct Point {\n"
+"    x: float,\n"
+"    y: float\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1072
+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 "
+"point, but allocated in a different location:"
+msgstr ""
+"シンプルな定義ですが、この定義を使って `Point` 型のオブジェクトを様々な方法で"
+"割り当てることができます。例えば、このコードの3つのローカル変数は、それぞれ異"
+"なった場所に `Point` 型のオブジェクトを割り当てています。"
+
+#. type: Plain text
+#: doc/tutorial.md:1079
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"let on_the_stack : Point  =  Point { x: 3.0, y: 4.0 };\n"
+"let managed_box  : @Point = @Point { x: 5.0, y: 1.0 };\n"
+"let owned_box    : ~Point = ~Point { x: 7.0, y: 9.0 };\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1089
+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 "
+"compute the distance between `on_the_stack` and `managed_box`, or between "
+"`managed_box` and `owned_box`. One option is to define a function that takes "
+"two arguments of type point—that is, it takes the points by value. But this "
+"will cause the points to be copied when we call the function. For points, "
+"this is probably not so bad, but often copies are expensive. So we’d like to "
+"define a function that takes the points by pointer. We can use borrowed "
+"pointers to do this:"
+msgstr ""
+"`Point` 型のオブジェクトの割り当て先がどこであったとしても利用可能な、任意の "
+"2 点間の距離を計算する処理を書きたいとします。例えば、 `on_the_stack`, "
+"`managed_box` 間や `managed_box`, `owned_box` 間の距離を計算する処理です。 1"
+"つ目の実装方法として、2つの `Point` 型オブジェクトを引数にとる関数を定義する"
+"方法、すなわち、オブジェクトを値で受け渡す方法があります。しかし、この方法で"
+"は関数呼び出し時に `Point` オブジェクトのコピーが行われます。`Point` オブジェ"
+"クトの場合、このような実装はそれほど悪いものではないでしょうが、コピー処理の"
+"コストは高い場合もあります。したがって、`Point` オブジェクトをポインタ渡しす"
+"る関数を定義する必要があります。そのために、借用ポインタを利用することが可能"
+"です。"
+
+#. type: Plain text
+#: doc/tutorial.md:1099
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# fn sqrt(f: float) -> float { 0f }\n"
+"fn compute_distance(p1: &Point, p2: &Point) -> float {\n"
+"    let x_d = p1.x - p2.x;\n"
+"    let y_d = p1.y - p2.y;\n"
+"    sqrt(x_d * x_d + y_d * y_d)\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1101 doc/tutorial-borrowed-ptr.md:72
+msgid "Now we can call `compute_distance()` in various ways:"
+msgstr ""
+"上記の `compute_distance()` 関数は、様々な方法で呼び出すことができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1111
+#, no-wrap
+msgid ""
+"~~~\n"
+"# struct Point{ x: float, y: float };\n"
+"# let on_the_stack : Point  =  Point { x: 3.0, y: 4.0 };\n"
+"# let managed_box  : @Point = @Point { x: 5.0, y: 1.0 };\n"
+"# let owned_box    : ~Point = ~Point { x: 7.0, y: 9.0 };\n"
+"# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }\n"
+"compute_distance(&on_the_stack, managed_box);\n"
+"compute_distance(managed_box, owned_box);\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1118
+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 "
+"is, a struct value) and we have to take its address to get a value. We also "
+"call this _borrowing_ the local variable `on_the_stack`, because we are "
+"creating an alias: that is, another route to the same data."
+msgstr ""
+"ここで `&` 演算子は `on_the_stack` 変数のアドレスを取得するために使われていま"
+"す。これは、 `on_the_stack` の型は `Point` (つまり、構造体の値) であり、呼び"
+"出した関数から値を取得させるため、構造体のアドレスを渡す必要があるからです。"
+"値の別名 (エイリアス)、すなわち、同じデータへアクセスするための別の方法を提供"
+"するので、このような操作のことをローカル変数 `on_the_stack` の __借用__ "
+"(_borrowing_) と呼びます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1124
+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 "
+"`@point` or `~point` to a borrowed pointer like `&point`. This is another "
+"form of borrowing; in this case, the contents of the managed/owned box are "
+"being lent out."
+msgstr ""
+"ボックスである `managed_box` と `owned_box` の場合は、特に明示的な操作を行う"
+"必要はありません。コンパイラは `@point` や `~point` のようなボックスを自動的"
+"に `&point` のような借用ポインタへと変換します。これは、別の形態の借用 "
+"(borrowing) です。この場合、マネージド/所有ボックスの内容が貸し出されていま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:1133
+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 "
+"out, you cannot send that variable to another task, nor will you be "
+"permitted to take actions that might cause the borrowed value to be freed or "
+"to change its type. This rule should make intuitive sense: you must wait for "
+"a borrowed value to be returned (that is, for the borrowed pointer to go out "
+"of scope) before you can make full use of it again."
+msgstr ""
+"値が借用されている間、借用元の値に対して行える操作がいくらか制限されます。例"
+"えば、変数の内容が貸し出された場合、その変数を他のタスクに送信することはでき"
+"ませんし、借用された値を解放したり、型が変化させるような操作も行うことができ"
+"ません。このルールは理にかなったものでしょう。貸し出した値を最大限に活用する "
+"(make full use of it) ためには、貸し出した値の返却 (借用ポインタが存在するス"
+"コープを抜ける) を待たなければなりません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1136
+msgid ""
+"For a more in-depth explanation of borrowed pointers, read the [borrowed "
+"pointer tutorial][borrowtut]."
+msgstr ""
+"借用ポインタの詳細については、[借用ポインタのチュートリアル][borrowtut]を参照"
+"してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:1138
+msgid "[borrowtut]: tutorial-borrowed-ptr.html"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1140
+msgid "## Freezing"
+msgstr "## 凍結"
+
+#. type: Plain text
+#: doc/tutorial.md:1143
+msgid ""
+"Borrowing an immutable pointer to an object freezes it and prevents "
+"mutation.  `Owned` objects have freezing enforced statically at compile-time."
+msgstr ""
+"オブジェクトへのイミュータブルな (借用) ポインタを借用した場合、借用されたオ"
+"ブジェクトは凍結 (freezing) され、変更することができなくなります。`Owned` ト"
+"レイトが付与されたオブジェクトは、コンパイル時の静的解析により、強制的に凍結"
+"されます (凍結された値を変更しようとすると、コンパイルエラーとなります)。"
+
+#. type: Plain text
+#: doc/tutorial.md:1152
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let mut x = 5;\n"
+"{\n"
+"    let y = &x; // x is now frozen, it cannot be modified\n"
+"}\n"
+"// x is now unfrozen again\n"
+"# x = 3;\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"let mut x = 5;\n"
+"{\n"
+"    let y = &x; // x は凍結されたので、変更することができない\n"
+"}\n"
+"// x の凍結状態は解除される\n"
+"# x = 3;\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1156
+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 "
+"while they are frozen:"
+msgstr ""
+"ミュータブルなマネージドボックスは、その内容のいずれかが借用される際に動的に"
+"凍結され、凍結状態の間に内容を変更しようとすると、タスクが失敗します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1166
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let x = @mut 5;\n"
+"let y = x;\n"
+"{\n"
+"    let z = &*y; // the managed box is now frozen\n"
+"    // modifying it through x or y will cause a task failure\n"
+"}\n"
+"// the box is now unfrozen again\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"let x = @mut 5;\n"
+"let y = x;\n"
+"{\n"
+"    let z = &*y; // マネージドボックスが凍結される\n"
+"    // x か y を経由して内容を変更すると、タスクが異常終了する\n"
+"}\n"
+"// ボックスの凍結状態は解除される\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1168
+msgid "# Dereferencing pointers"
+msgstr "# ポインタのデリファレンス"
+
+#. type: Plain text
+#: doc/tutorial.md:1171
+msgid ""
+"Rust uses the unary star operator (`*`) to access the contents of a box or "
+"pointer, similarly to C."
+msgstr ""
+"Rust では、C と同様、ボックスの内容やポインタの参照先にアクセスするためには単"
+"項スター演算子 (`*`) を使います。"
+
+#. type: Plain text
+#: doc/tutorial.md:1176
+msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;"
+msgstr ""
+"~~~\n"
+"let managed = @10;\n"
+"let owned = ~20;\n"
+"let borrowed = &30;"
+
+#. type: Plain text
+#: doc/tutorial.md:1179
+msgid "let sum = *managed + *owned + *borrowed; ~~~"
+msgstr ""
+"let sum = *managed + *owned + *borrowed;\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1183
+msgid ""
+"Dereferenced mutable pointers may appear on the left hand side of "
+"assignments. Such an assignment modifies the value that the pointer points "
+"to."
+msgstr ""
+"ミュータブルなポインタをデリファレンスしたものは、代入文の左辺に置くことがで"
+"きます。このような代入文は、ポインタが指す値を変更します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1187
+msgid "~~~ let managed = @mut 10; let mut owned = ~20;"
+msgstr ""
+"~~~\n"
+"let managed = @mut 10;\n"
+"let mut owned = ~20;"
+
+#. type: Plain text
+#: doc/tutorial.md:1190
+msgid "let mut value = 30; let borrowed = &mut value;"
+msgstr ""
+"let mut value = 30;\n"
+"let borrowed = &mut value;"
+
+#. type: Plain text
+#: doc/tutorial.md:1195
+#, no-wrap
+msgid ""
+"*managed = *owned + 10;\n"
+"*owned = *borrowed + 100;\n"
+"*borrowed = *managed + 1000;\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1199
+msgid ""
+"Pointers have high operator precedence, but lower precedence than the dot "
+"operator used for field and method access. This precedence order can "
+"sometimes make code awkward and parenthesis-filled."
+msgstr ""
+"ポインタ演算子の優先順位は高いですが、フィールドやメソッドのアクセスに用いる"
+"ドット演算子よりは優先順位は低いです。この優先順位により、コードが不格好で括"
+"弧だらけなものになることがあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1209
+msgid ""
+"~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, "
+"Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point "
+"{ x: 10f, y: 20f }; let end = ~Point { x: (*start).x + 100f, y: (*start).y + "
+"100f }; let rect = &Rectangle(*start, *end); let area = (*rect).area(); ~~~"
+msgstr ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape { Rectangle(Point, Point) }\n"
+"# impl Shape { fn area(&self) -> int { 0 } }\n"
+"let start = @Point { x: 10f, y: 20f };\n"
+"let end = ~Point { x: (*start).x + 100f, y: (*start).y + 100f };\n"
+"let rect = &Rectangle(*start, *end);\n"
+"let area = (*rect).area();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1213
+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), "
+"so in most cases, explicitly dereferencing the receiver is not necessary."
+msgstr ""
+"コードが醜くなるのを防ぐため、ドット演算子はレシーバ (ドットの左にある値) の "
+"__ポインタを自動的にデリファレンス__ します。これにより、ほとんどのケースでは"
+"レシーバを明示的にデリファレンスする必要がなくなります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1223
+msgid ""
+"~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, "
+"Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point "
+"{ x: 10f, y: 20f }; let end = ~Point { x: start.x + 100f, y: start.y + "
+"100f }; let rect = &Rectangle(*start, *end); let area = rect.area(); ~~~"
+msgstr ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape { Rectangle(Point, Point) }\n"
+"# impl Shape { fn area(&self) -> int { 0 } }\n"
+"let start = @Point { x: 10f, y: 20f };\n"
+"let end = ~Point { x: start.x + 100f, y: start.y + 100f };\n"
+"let rect = &Rectangle(*start, *end);\n"
+"let area = rect.area();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1227
+msgid ""
+"You can write an expression that dereferences any number of pointers "
+"automatically. For example, if you feel inclined, you could write something "
+"silly like"
+msgstr ""
+"1つのドット演算子で何度も自動デリファレンスが行うことができます。例えば、やろ"
+"うと思えば以下のような馬鹿げたものを書くこともできます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1233
+msgid ""
+"~~~ # struct Point { x: float, y: float } let point = &@~Point { x: 10f, y: "
+"20f }; println(fmt!(\"%f\", point.x)); ~~~"
+msgstr ""
+"~~~\n"
+"# struct Point { x: float, y: float }\n"
+"let point = &@~Point { x: 10f, y: 20f };\n"
+"println(fmt!(\"%f\", point.x));\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1235
+msgid "The indexing operator (`[]`) also auto-dereferences."
+msgstr "添字演算子 (`[]`) も自動でリファレンスを行います。"
+
+#. type: Plain text
+#: doc/tutorial.md:1237
+msgid "# Vectors and strings"
+msgstr "# ベクタと文字列"
+
+#. type: Plain text
+#: doc/tutorial.md:1242
+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, "
+"the local heap, or the exchange heap. Borrowed pointers to vectors are also "
+"called 'slices'."
+msgstr ""
+"ベクタは同じ型の値が0個以上含まれる、メモリ上の連続した部分のことです。Rust "
+"の他の型と同様、ベクタもスタック、ローカルヒープ、交換ヒープ (exchange heap) "
+"上に格納することができます。ベクトルの借用ポインタは、「スライス」と呼ばれる"
+"場合もあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1252
+#, no-wrap
+msgid ""
+"~~~\n"
+"# enum Crayon {\n"
+"#     Almond, AntiqueBrass, Apricot,\n"
+"#     Aquamarine, Asparagus, AtomicTangerine,\n"
+"#     BananaMania, Beaver, Bittersweet,\n"
+"#     Black, BlizzardBlue, Blue\n"
+"# }\n"
+"// A fixed-size stack vector\n"
+"let stack_crayons: [Crayon, ..3] = [Almond, AntiqueBrass, Apricot];\n"
+msgstr ""
+"~~~\n"
+"# enum Crayon {\n"
+"#     Almond, AntiqueBrass, Apricot,\n"
+"#     Aquamarine, Asparagus, AtomicTangerine,\n"
+"#     BananaMania, Beaver, Bittersweet,\n"
+"#     Black, BlizzardBlue, Blue\n"
+"# }\n"
+"// スタック上の固定長ベクタ\n"
+"let stack_crayons: [Crayon, ..3] = [Almond, AntiqueBrass, Apricot];\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1255
+msgid ""
+"// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] "
+"= &[Aquamarine, Asparagus, AtomicTangerine];"
+msgstr ""
+"// スタックに獲得されたベクタへの借用ポインタ\n"
+"let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];"
+
+#. type: Plain text
+#: doc/tutorial.md:1258
+msgid ""
+"// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = "
+"@[BananaMania, Beaver, Bittersweet];"
+msgstr ""
+"// ローカルヒープ上に獲得された、クレヨンの (マネージド) ベクタ\n"
+"let local_crayons: @[Crayon] = @[BananaMania, Beaver, Bittersweet];"
+
+#. type: Plain text
+#: doc/tutorial.md:1262
+msgid ""
+"// An exchange heap (owned) vector of crayons let exchange_crayons: "
+"~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~"
+msgstr ""
+"// 交換ヒープに獲得された、クレヨンの (所有) ベクタ\n"
+"let exchange_crayons: ~[Crayon] = ~[Black, BlizzardBlue, Blue];\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1264
+msgid "The `+` operator means concatenation when applied to vector types."
+msgstr "`+` 演算子がベクタ型に適用された場合、ベクタの結合を意味します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1274
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum Crayon { Almond, AntiqueBrass, Apricot,\n"
+"#               Aquamarine, Asparagus, AtomicTangerine,\n"
+"#               BananaMania, Beaver, Bittersweet };\n"
+"# impl Clone for Crayon {\n"
+"#     fn clone(&self) -> Crayon {\n"
+"#         *self\n"
+"#     }\n"
+"# }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1277
+msgid ""
+"let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = "
+"~[BananaMania, Beaver, Bittersweet];"
+msgstr ""
+"let my_crayons = ~[Almond, AntiqueBrass, Apricot];\n"
+"let your_crayons = ~[BananaMania, Beaver, Bittersweet];"
+
+#. type: Plain text
+#: doc/tutorial.md:1280
+msgid ""
+"// Add two vectors to create a new one let our_crayons = my_crayons + "
+"your_crayons;"
+msgstr ""
+"// 2 つのベクタを結合して、新しいベクタを作る\n"
+"let our_crayons = my_crayons + your_crayons;"
+
+#. type: Plain text
+#: doc/tutorial.md:1285
+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 ""
+"// .push_all() はベクタに要素を追加します。ミュータブルなスロットのベクタに対"
+"してのみ有効です\n"
+"let mut my_crayons = my_crayons;\n"
+"my_crayons.push_all(your_crayons);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1290
+msgid ""
+"> ***Note:*** The above examples of vector addition use owned > vectors. "
+"Some operations on slices and stack vectors are > not yet well-supported. "
+"Owned vectors are often the most > usable."
+msgstr ""
+"> ***注意:*** 上記のベクタに要素を追加する例では、所有ベクタを利用していま"
+"す。いくつかの操作はスライスやスタックベクタを十分にサポートしていません。所"
+"有ベクタが最も便利な場合がしばしばあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1292
+msgid "Square brackets denote indexing into a vector:"
+msgstr "角括弧はベクタの添字を表します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1304
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# enum Crayon { Almond, AntiqueBrass, Apricot,\n"
+"#               Aquamarine, Asparagus, AtomicTangerine,\n"
+"#               BananaMania, Beaver, Bittersweet };\n"
+"# fn draw_scene(c: Crayon) { }\n"
+"let crayons: [Crayon, ..3] = [BananaMania, Beaver, Bittersweet];\n"
+"match crayons[0] {\n"
+"    Bittersweet => draw_scene(crayons[0]),\n"
+"    _ => ()\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1306
+msgid "A vector can be destructured using pattern matching:"
+msgstr "ベクタはパターンマッチにより destructuring することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1316
+#, no-wrap
+msgid ""
+"~~~~\n"
+"let numbers: &[int] = &[1, 2, 3];\n"
+"let score = match numbers {\n"
+"    [] => 0,\n"
+"    [a] => a * 10,\n"
+"    [a, b] => a * 6 + b * 4,\n"
+"    [a, b, c, ..rest] => a * 5 + b * 3 + c * 2 + rest.len() as int\n"
+"};\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1320
+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 "
+"immutable slot."
+msgstr ""
+"ベクタの要素は、 __ベクタのミュータビリティを継承するので__、ベクタがイミュー"
+"タブルなスロットに格納されている場合は個々の要素を変更する (再代入する) こと"
+"はできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1326
+#, no-wrap
+msgid ""
+"~~~ {.xfail-test}\n"
+"# enum Crayon { Almond, AntiqueBrass, Apricot,\n"
+"#               Aquamarine, Asparagus, AtomicTangerine,\n"
+"#               BananaMania, Beaver, Bittersweet };\n"
+"let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1329
+msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~"
+msgstr ""
+"crayons[0] = Apricot; // ERROR: Can't assign to immutable vector\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1331
+msgid "Moving it into a mutable slot makes the elements assignable."
+msgstr ""
+"ベクタをミュータブルなスロットに移動することで、要素への代入が可能になりま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:1337
+#, no-wrap
+msgid ""
+"~~~\n"
+"# enum Crayon { Almond, AntiqueBrass, Apricot,\n"
+"#               Aquamarine, Asparagus, AtomicTangerine,\n"
+"#               BananaMania, Beaver, Bittersweet };\n"
+"let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1340
+msgid ""
+"// Put the vector into a mutable slot let mut mutable_crayons = crayons;"
+msgstr ""
+"// ベクタをミュータブルなスロットに配置する\n"
+"let mut mutable_crayons = crayons;"
+
+#. type: Plain text
+#: doc/tutorial.md:1344
+msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~"
+msgstr ""
+"// 完全にミュータブルになった\n"
+"mutable_crayons[0] = Apricot;\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1347
+msgid ""
+"This is a simple example of Rust's _dual-mode data structures_, also "
+"referred to as _freezing and thawing_."
+msgstr ""
+"これは、__凍結および解凍__ (_freezing and thawing_) と呼ばれる、Rust の __"
+"デュアルモードのデータ構造__ についての簡単な例です。"
+
+#. type: Plain text
+#: doc/tutorial.md:1355
+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 "
+"the string literal without a storage sigil (for example, `\"foo\"`) is "
+"treated differently than a comparable vector (`[foo]`).  Whereas plain "
+"vectors are stack-allocated fixed-length vectors, plain strings are borrowed "
+"pointers to read-only (static)  memory. All strings are immutable."
+msgstr ""
+"文字列は `u8` 型のベクタとして実装されていますが、ベクタとは異なる独自の型を"
+"持ちます。文字列はベクタと同じくメモリを獲得先を選択できますが、ストレージを"
+"表すシジルが付与されていない文字列リテラル (`\"foo\"` など) は対応するベクタ "
+"(`[foo]`) と異なった扱いをされます。シジルなしのベクタはスタックに獲得される"
+"固定長のベクタですが、シジルなしの文字列は読み込み専用の (静的な) メモリ領域"
+"への借用ポインタとなります。すべての文字列はイミュータブルです。"
+
+#. type: Plain text
+#: doc/tutorial.md:1359
+msgid ""
+"~~~ // A plain string is a slice to read-only (static) memory let "
+"stack_crayons: &str = \"Almond, AntiqueBrass, Apricot\";"
+msgstr ""
+"~~~\n"
+"// シジルなしの文字列は、読み込み専用な (静的) メモリへのスライス\n"
+"let stack_crayons: &str = \"Almond, AntiqueBrass, Apricot\";"
+
+#. type: Plain text
+#: doc/tutorial.md:1362
+msgid ""
+"// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, "
+"Asparagus, AtomicTangerine\";"
+msgstr ""
+"// `&` を付与した場合も、シジルなしと同じ意味\n"
+"let stack_crayons: &str = &\"Aquamarine, Asparagus, AtomicTangerine\";"
+
+#. type: Plain text
+#: doc/tutorial.md:1365
+msgid ""
+"// A local heap (managed) string let local_crayons: @str = @\"BananaMania, "
+"Beaver, Bittersweet\";"
+msgstr ""
+"// ローカルヒープ上の (マネージドな) 文字列\n"
+"let local_crayons: @str = @\"BananaMania, Beaver, Bittersweet\";"
+
+#. type: Plain text
+#: doc/tutorial.md:1369
+msgid ""
+"// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, "
+"BlizzardBlue, Blue\"; ~~~"
+msgstr ""
+"// 交換ヒープ上の (所有) 文字列\n"
+"let exchange_crayons: ~str = ~\"Black, BlizzardBlue, Blue\";\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1373
+msgid ""
+"Both vectors and strings support a number of useful [methods](#methods), "
+"defined in [`std::vec`] and [`std::str`]. Here are some examples."
+msgstr ""
+"ベクタと文字列は、[`std::vec`] と [`std::str`] で定義された、多くの有用な [メ"
+"ソッド](#methods) を持ちます。以下にいくつか例を挙げます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1376
+msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html"
+msgstr ""
+"[`std::vec`]: std/vec.html\n"
+"[`std::str`]: std/str.html"
+
+#. type: Plain text
+#: doc/tutorial.md:1387
+#, no-wrap
+msgid ""
+"~~~\n"
+"# enum Crayon {\n"
+"#     Almond, AntiqueBrass, Apricot,\n"
+"#     Aquamarine, Asparagus, AtomicTangerine,\n"
+"#     BananaMania, Beaver, Bittersweet\n"
+"# }\n"
+"# fn unwrap_crayon(c: Crayon) -> int { 0 }\n"
+"# fn eat_crayon_wax(i: int) { }\n"
+"# fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }\n"
+"# fn crayon_to_str(c: Crayon) -> &str { \"\" }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1389
+msgid "let crayons = [Almond, AntiqueBrass, Apricot];"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1393
+msgid ""
+"// Check the length of the vector assert!(crayons.len() == 3); assert!(!"
+"crayons.is_empty());"
+msgstr ""
+"// ベクタの長さをチェックする\n"
+"assert!(crayons.len() == 3);\n"
+"assert!(!crayons.is_empty());"
+
+#. type: Plain text
+#: doc/tutorial.md:1400
+#, no-wrap
+msgid ""
+"// Iterate over a vector, obtaining a pointer to each element\n"
+"// (`for` is explained in the container/iterator tutorial)\n"
+"for crayon in crayons.iter() {\n"
+"    let delicious_crayon_wax = unwrap_crayon(*crayon);\n"
+"    eat_crayon_wax(delicious_crayon_wax);\n"
+"}\n"
+msgstr ""
+"// ベクタの要素をイテレートし、各要素へのポインタを取得する\n"
+"// (`for` については、は次の章で説明します)\n"
+"for crayon in crayons.iter() {\n"
+"    let delicious_crayon_wax = unwrap_crayon(*crayon);\n"
+"    eat_crayon_wax(delicious_crayon_wax);\n"
+"}\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1404
+msgid ""
+"// Map vector elements let crayon_names = crayons.map(|v| "
+"crayon_to_str(*v)); let favorite_crayon_name = crayon_names[0];"
+msgstr ""
+"// ベクタの要素をマッピング (変換) する\n"
+"let crayon_names = crayons.map(|v| crayon_to_str(*v));\n"
+"let favorite_crayon_name = crayon_names[0];"
+
+#. type: Plain text
+#: doc/tutorial.md:1407
+msgid ""
+"// Remove whitespace from before and after the string let "
+"new_favorite_crayon_name = favorite_crayon_name.trim();"
+msgstr ""
+"// 文字列の先頭と末尾の空白を除去する\n"
+"let new_favorite_crayon_name = favorite_crayon_name.trim();"
+
+#. type: Plain text
+#: doc/tutorial.md:1413
+#, no-wrap
+msgid ""
+"if favorite_crayon_name.len() > 5 {\n"
+"   // Create a substring\n"
+"   println(favorite_crayon_name.slice_chars(0, 5));\n"
+"}\n"
+"~~~\n"
+msgstr ""
+"if favorite_crayon_name.len() > 5 {\n"
+"   // 部分文字列を作る\n"
+"   println(favorite_crayon_name.slice_chars(0, 5));\n"
+"}\n"
+"~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1415
+msgid "# Closures"
+msgstr "# クロージャ"
+
+#. type: Plain text
+#: doc/tutorial.md:1420
+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 "
+"environment (sometimes referred to as \"capturing\" variables in their "
+"environment). For example, you couldn't write the following:"
+msgstr ""
+"これまで登場したような名前のある関数は、関数の外で定義されるローカル変数を参"
+"照することはできません。ローカル変数は環境を閉じ込める (環境中の変数を「キャ"
+"プチャする」と呼ばれることもあります) ことはありません。例えば、以下のような"
+"コードを書くことはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1423
+msgid "~~~~ {.ignore} let foo = 10;"
+msgstr ""
+"~~~~ {.ignore}\n"
+"let foo = 10;"
+
+#. type: Plain text
+#: doc/tutorial.md:1428
+#, no-wrap
+msgid ""
+"fn bar() -> int {\n"
+"   return foo; // `bar` cannot refer to `foo`\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"fn bar() -> int {\n"
+"   return foo; // `bar` ば `foo` を参照できない\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1431
+msgid ""
+"Rust also supports _closures_, functions that can access variables in the "
+"enclosing scope."
+msgstr ""
+"Rust は __クロージャ__ という、周囲のスコープの変数にアクセスできる関数をサ"
+"ポートしています。"
+
+#. type: Plain text
+#: doc/tutorial.md:1434
+msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }"
+msgstr ""
+"~~~~\n"
+"fn call_closure_with_ten(b: &fn(int)) { b(10); }"
+
+#. type: Plain text
+#: doc/tutorial.md:1437
+msgid ""
+"let captured_var = 20; let closure = |arg| println(fmt!(\"captured_var=%d, "
+"arg=%d\", captured_var, arg));"
+msgstr ""
+"let captured_var = 20;\n"
+"let closure = |arg| println(fmt!(\"captured_var=%d, arg=%d\", captured_var, "
+"arg));"
+
+#. type: Plain text
+#: doc/tutorial.md:1440
+msgid "call_closure_with_ten(closure); ~~~~"
+msgstr ""
+"call_closure_with_ten(closure);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1446
+msgid ""
+"Closures begin with the argument list between vertical bars and are followed "
+"by a single expression. Remember that a block, `{ <expr1>; <expr2>; ... }`, "
+"is considered a single expression: it evaluates to the result of the last "
+"expression it contains if that expression is not followed by a semicolon, "
+"otherwise the block evaluates to `()`."
+msgstr ""
+"クロージャはバーティカルバー (`|`) で囲まれた引数リストと、それに続く単一の式"
+"から構成されます。ブロック `{ <expr1>; <expr2>; ...}` は単一の式とみなされる"
+"ことを思い出してください。ブロックに含まれる最後の式に続けてセミコロンがない"
+"場合、ブロックの値は最後の式の値となり、そうでなければ `()` となります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1451
+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 "
+"the compiler needs assistance, though, the arguments and return types may be "
+"annotated."
+msgstr ""
+"引数の型や戻り値の型は、ほとんどすべての場合においてコンパイラにより推論され"
+"るため、通常省略できます。発生するのはまれですが、コンパイラが推論に失敗する"
+"場合は、引数と戻り値の型注釈を付けることがあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1455
+msgid "~~~~ let square = |x: int| -> uint { (x * x) as uint }; ~~~~"
+msgstr ""
+"~~~~\n"
+"let square = |x: int| -> uint { (x * x) as uint };\n"
+"~~~~~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1459
+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 "
+"variables in the enclosing scope."
+msgstr ""
+"クロージャにはいくつかの形態があり、それぞれに独自の役割があります。最も一般"
+"的なのはスタッククロージャと呼ばれるもので、 `&fn` という型を持ち、外側のロー"
+"カル変数に直接アクセスすることができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1464
+msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~"
+msgstr ""
+"~~~~\n"
+"let mut max = 0;\n"
+"[1, 2, 3].map(|x| if *x > max { max = *x });\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1473
+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 "
+"stack closures never outlive the local variables to which they refer, stack "
+"closures are not first-class. That is, they can only be used in argument "
+"position; they cannot be stored in data structures or returned from "
+"functions. Despite these limitations, stack closures are used pervasively in "
+"Rust code."
+msgstr ""
+"スタッククロージャは、閉じ込める環境はコールスタック上に獲得され、ローカル変"
+"数をポインタで参照するため、非常に効率的です。スタッククロージャが参照してい"
+"るローカル変数よりも長生きしないことを保証するため、スタッククロージャは第一"
+"級の値ではありません。すなわち、スタッククロージャは引数としてしか使うことが"
+"できず、データ構造や関数の戻り値となることはありません。この制限にも関わら"
+"ず、スタッククロージャは Rust のコードのあちこちに登場します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1475
+msgid "## Managed closures"
+msgstr "## マネージドクロージャ"
+
+#. type: Plain text
+#: doc/tutorial.md:1481
+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 "
+"purpose, Rust provides a type of closure that has an arbitrary lifetime, "
+"written `@fn` (boxed closure, analogous to the `@` pointer type described "
+"earlier). This type of closure *is* first-class."
+msgstr ""
+"クロージャをデータ構造に格納する必要がある場合、スタッククロージャを利用する"
+"ことは言語仕様上、許可されていませんRust は、このような目的のために任意の寿命"
+"を持つクロージャ型、`@fn` (ボックスクロージャ、 前述の `@` ポインタ型と似たよ"
+"うなもの) を提供しています。この種のクロージャ **は** 第一級の値です。"
+
+#. type: Plain text
+#: doc/tutorial.md:1486
+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. "
+"This means that it can not assign to these variables, and cannot observe "
+"updates to them."
+msgstr ""
+"マネージドクロージャは環境に直接アクセスすることはできませんが、単に値をコ"
+"ピーしてプライベートなデータ構造に閉じ込めます。これは、クロージャは変数に値"
+"を代入することや、値の変更を監視することもできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1489
+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:1495
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn mk_appender(suffix: ~str) -> @fn(~str) -> ~str {\n"
+"    // The compiler knows that we intend this closure to be of type @fn\n"
+"    return |s| s + suffix;\n"
+"}\n"
+msgstr ""
+"~~~~\n"
+"fn mk_appender(suffix: ~str) -> @fn(~str) -> ~str {\n"
+"    // コンパイラはこのクロージャが @fn 型であることを推論します\n"
+"    return |s| s + suffix;\n"
+"}\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1501
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    let shout = mk_appender(~\"!\");\n"
+"    println(shout(~\"hey ho, let's go\"));\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1503
+msgid "## Owned closures"
+msgstr "## 所有クロージャ"
+
+#. type: Plain text
+#: doc/tutorial.md:1510
+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 "
+"close over, much like managed closures, but they also own them: that is, no "
+"other code can access them. Owned closures are used in concurrent code, "
+"particularly for spawning [tasks][tasks]."
+msgstr ""
+"`~` ポインタ型と同様に `~fn` 型  で書き表される所有クロージャは安全にプロセス"
+"間で送信することができます。所有クローじゃはマネージドクロージャと全く同じよ"
+"うに閉じ込める値をコピーしますが、値を所有します。つまり、他のコードは閉じ込"
+"められた値にアクセスできなくなります。所有クロージャは並列プログラム、特に "
+"[タスク][tasks] 生成で利用されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1512
+msgid "## Closure compatibility"
+msgstr "## クロージャの互換性"
+
+#. type: Plain text
+#: doc/tutorial.md:1519
+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 "
+"expect a `&fn()`. Thus, when writing a higher-order function that only calls "
+"its function argument, and does nothing else with it, you should almost "
+"always declare the type of that argument as `&fn()`. That way, callers may "
+"pass any kind of closure."
+msgstr ""
+"Rust のクロージャは型の派生 (subtyping) という便利な性質を持っています。この"
+"性質により、`&fn()` 型を期待する関数には (引数と戻り値の型が一致する限り) 任"
+"意の種類のクロージャを渡すことができます。したがって、引数で渡された関数につ"
+"いては呼び出すだけで他に何もしない高階関数を書くときには、ほぼすべてのケース"
+"で引数の型を `&fn` と宣言するべきです。そうすることで、呼び出し元は任意の種類"
+"のクロージャを渡すことができるよになります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1527
+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 "
+"normal function\"; } call_twice(closure); call_twice(function); ~~~~"
+msgstr ""
+"~~~~\n"
+"fn call_twice(f: &fn()) { f(); f(); }\n"
+"let closure = || { \"I'm a closure, and it doesn't matter what type I am"
+"\"; };\n"
+"fn function() { \"I'm a normal function\"; }\n"
+"call_twice(closure);\n"
+"call_twice(function);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1531
+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 "
+"with non-copyable types."
+msgstr ""
+"> ***注意*** コードの文法と意味は将来的に変更されるかもしれません。現時点では"
+"いくつかの状況、特にコピーできない型が関連するケースにおいて望ましくない振る"
+"舞いが起こされる場合があります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1533
+msgid "## Do syntax"
+msgstr "## do 構文"
+
+#. type: Plain text
+#: doc/tutorial.md:1536
+msgid ""
+"The `do` expression provides a way to treat higher-order functions "
+"(functions that take closures as arguments) as control structures."
+msgstr ""
+"`do` 式は高階関数 (クロージャを引数にとる関数) を制御構造のように取り扱う方法"
+"を提供します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1539
+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:1549
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn each(v: &[int], op: &fn(v: &int)) {\n"
+"   let mut n = 0;\n"
+"   while n < v.len() {\n"
+"       op(&v[n]);\n"
+"       n += 1;\n"
+"   }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1553
+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:1561
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# fn each(v: &[int], op: &fn(v: &int)) { }\n"
+"# fn do_some_work(i: &int) { }\n"
+"each([1, 2, 3], |n| {\n"
+"    do_some_work(n);\n"
+"});\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1564
+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 ""
+"このような便利なパターンに対応するため、Rust には、言語組み込みの制御構造のよ"
+"うな記述が可能な、特別な関数呼び出し形式があります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1572
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# fn each(v: &[int], op: &fn(v: &int)) { }\n"
+"# fn do_some_work(i: &int) { }\n"
+"do each([1, 2, 3]) |n| {\n"
+"    do_some_work(n);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1577
+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, "
+"where it looks more like a typical block of code."
+msgstr ""
+"関数呼び出しの前には `do` キーワードをつけ、引数リストの中に最後のクロージャ"
+"引数を書くのではなく、普通のコードブロックのように、丸括弧の外に記述します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1582
+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 "
+"function that takes an owned closure that takes no arguments."
+msgstr ""
+"`task::spawn` 関数を用いてタスクを生成する場合、 `do` を用いると便利です。"
+"`spawn` は、 `spawn(fn: ~fn())` という方を持っています。言い換えると、"
+"`spawn` は「引数をとらない所有クロージャ」を引数としてとる関数ということで"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:1585 doc/tutorial.md:1597
+msgid "~~~~ use std::task::spawn;"
+msgstr ""
+"~~~~\n"
+"use std::task::spawn;"
+
+#. type: Plain text
+#: doc/tutorial.md:1590
+#, no-wrap
+msgid ""
+"do spawn() || {\n"
+"    debug!(\"I'm a task, whatever\");\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1594
+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 "
+"omitted from `do` expressions."
+msgstr ""
+"このコードの丸括弧と縦棒に注目してください。立て続けに2の空の引数リストが現れ"
+"ているます。これは非常に見苦しいので、`do` 式では空の引数リストを省略すること"
+"が可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:1602
+#, no-wrap
+msgid ""
+"do spawn {\n"
+"   debug!(\"Kablam!\");\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1605
+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 "
+"environment variable to the name of your crate, which, for a file named `foo."
+"rs`, will be `foo` (e.g., with bash, `export RUST_LOG=foo`)."
+msgstr ""
+"`debug!` ステートメントの出力を見たい場合、`debug!` によるロギングを有効にす"
+"る必要があるでしょう。`debug!` によるロギングを有効にするためには、 RUST_LOG "
+"環境変数をクレートの名前に設定する必要があります (例えば、bash の場合、 "
+"`export RUST_LOG=foo` を実行する)。 `foo.rs` というファイルの場合、クレート名"
+"は `foo` になります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1607
+msgid "# Methods"
+msgstr "# メソッド"
+
+#. type: Plain text
+#: doc/tutorial.md:1613
+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 "
+"`self` argument is like `this` in C++ and many other languages.  Methods are "
+"called with dot notation, as in `my_vec.len()`."
+msgstr ""
+"メソッドは、`self` という、メソッドのレシーバと同じ型の特別な引数を第一引数と"
+"してとる関数のようなものです。`self` は、 C++ や他の言語の `this` のようなも"
+"のです。メソッドはドット記法を浸かって `my_vec.len()` のように呼び出します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1617
+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 "
+"`draw` method on our `Shape` enum."
+msgstr ""
+"`impl` キーワードを使って記述される __実装__ (_implementation_) により、構造"
+"体や列挙型を含むほとんどの Rust の型に対してメソッドを定義することができま"
+"す。例のように、 `draw` メソッドを `Shape` 列挙型に定義してみましょう。"
+
+#. type: Plain text
+#: doc/tutorial.md:1625
+#, no-wrap
+msgid ""
+"~~~\n"
+"# fn draw_circle(p: Point, f: float) { }\n"
+"# fn draw_rectangle(p: Point, p: Point) { }\n"
+"struct Point {\n"
+"    x: float,\n"
+"    y: float\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1630
+#, no-wrap
+msgid ""
+"enum Shape {\n"
+"    Circle(Point, float),\n"
+"    Rectangle(Point, Point)\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1639
+#, no-wrap
+msgid ""
+"impl Shape {\n"
+"    fn draw(&self) {\n"
+"        match *self {\n"
+"            Circle(p, f) => draw_circle(p, f),\n"
+"            Rectangle(p1, p2) => draw_rectangle(p1, p2)\n"
+"        }\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1643
+msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~"
+msgstr ""
+"let s = Circle(Point { x: 1f, y: 2f }, 3f);\n"
+"s.draw();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1647
+msgid ""
+"This defines an _implementation_ for `Shape` containing a single method, "
+"`draw`. In most respects the `draw` method is defined like any other "
+"function, except for the name `self`."
+msgstr ""
+"この例では、 `Shape` に1つのメソッド `draw` をもつ __実装__ を定義していま"
+"す。`draw` メソッドは、`self` という名前を除くほとんどの面で他の関数と同じよ"
+"うに定義されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1652
+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`, "
+"`@self`, or `~self`.  A caller must in turn have a compatible pointer type "
+"to call the method."
+msgstr ""
+"`self` の型は、メソッドが実装されている型か、それらのポインタである。引数とし"
+"ては、 `self`, `&self`, `@self` または `~self` と記述されます。呼び出し側も同"
+"様、メソッドを呼び出すための互換性のあるポインタ型をもつ必要があります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1667
+#, no-wrap
+msgid ""
+"~~~\n"
+"# fn draw_circle(p: Point, f: float) { }\n"
+"# fn draw_rectangle(p: Point, p: Point) { }\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),\n"
+"#     Rectangle(Point, Point)\n"
+"# }\n"
+"impl Shape {\n"
+"    fn draw_borrowed(&self) { ... }\n"
+"    fn draw_managed(@self) { ... }\n"
+"    fn draw_owned(~self) { ... }\n"
+"    fn draw_value(self) { ... }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1669
+msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1675
+msgid ""
+"(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s."
+"draw_value(); ~~~"
+msgstr ""
+"(@s).draw_managed();\n"
+"(~s).draw_owned();\n"
+"(&s).draw_borrowed();\n"
+"s.draw_value();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1679
+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 ""
+"多くのメソッドは、借用ポインタの self 型を持つので、コンパイラは呼び出し先を"
+"借用ポインタに変換するためあらゆる手段を講じます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1697
+#, no-wrap
+msgid ""
+"~~~\n"
+"# fn draw_circle(p: Point, f: float) { }\n"
+"# fn draw_rectangle(p: Point, p: Point) { }\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),\n"
+"#     Rectangle(Point, Point)\n"
+"# }\n"
+"# impl Shape {\n"
+"#    fn draw_borrowed(&self) { ... }\n"
+"#    fn draw_managed(@self) { ... }\n"
+"#    fn draw_owned(~self) { ... }\n"
+"#    fn draw_value(self) { ... }\n"
+"# }\n"
+"# let s = Circle(Point { x: 1f, y: 2f }, 3f);\n"
+"// As with typical function arguments, managed and owned pointers\n"
+"// are automatically converted to borrowed pointers\n"
+msgstr ""
+"~~~\n"
+"# fn draw_circle(p: Point, f: float) { }\n"
+"# fn draw_rectangle(p: Point, p: Point) { }\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape {\n"
+"#     Circle(Point, float),\n"
+"#     Rectangle(Point, Point)\n"
+"# }\n"
+"# impl Shape {\n"
+"#    fn draw_borrowed(&self) { ... }\n"
+"#    fn draw_managed(@self) { ... }\n"
+"#    fn draw_owned(~self) { ... }\n"
+"#    fn draw_value(self) { ... }\n"
+"# }\n"
+"# let s = Circle(Point { x: 1f, y: 2f }, 3f);\n"
+"// 関数の引数と同様、マネージドポインタと所有ポインタは、\n"
+"// 自動的に借用ポインタに変換される\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1700
+msgid "(@s).draw_borrowed(); (~s).draw_borrowed();"
+msgstr ""
+"(@s).draw_borrowed();\n"
+"(~s).draw_borrowed();"
+
+#. type: Plain text
+#: doc/tutorial.md:1704
+msgid ""
+"// Unlike typical function arguments, the self value will // automatically "
+"be referenced ...  s.draw_borrowed();"
+msgstr ""
+"// 関数の引数とは異なり、 self の値は自動的にリファレンスされたり、 ...\n"
+"s.draw_borrowed();"
+
+#. type: Plain text
+#: doc/tutorial.md:1707
+msgid "// ... and dereferenced (& &s).draw_borrowed();"
+msgstr ""
+"// ... デリファレンスされたり、\n"
+"(& &s).draw_borrowed();"
+
+#. type: Plain text
+#: doc/tutorial.md:1711
+msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~"
+msgstr ""
+"// ... デリファレンス後借用されたりします\n"
+"(&@~s).draw_borrowed();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1715
+msgid ""
+"Implementations may also define standalone (sometimes called \"static\")  "
+"methods. The absence of a `self` parameter distinguishes such methods.  "
+"These methods are the preferred way to define constructor functions."
+msgstr ""
+"実装では、スタンドアロンなメソッド (「静的 (static)」メソッドと呼ばれる場合も"
+"あります)を定義することも可能です。引数に `self` をつけない場合、スタンドアロ"
+"ンなメソッドとなります。コンストラクタ関数は、スタンドアロンなメソッドとして"
+"定義することが推奨されています。"
+
+#. type: Plain text
+#: doc/tutorial.md:1722
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"impl Circle {\n"
+"    fn area(&self) -> float { ... }\n"
+"    fn new(area: float) -> Circle { ... }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1724
+msgid ""
+"To call such a method, just prefix it with the type name and a double colon:"
+msgstr ""
+"メソッド名の前に型名と2つのコロンを付けることで、スタンドアロンメソッドは呼び"
+"出せます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1733
+#, no-wrap
+msgid ""
+"~~~~\n"
+"use std::float::consts::pi;\n"
+"struct Circle { radius: float }\n"
+"impl Circle {\n"
+"    fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n"
+"}\n"
+"let c = Circle::new(42.5);\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1735
+msgid "# Generics"
+msgstr "# ジェネリクス"
+
+#. type: Plain text
+#: doc/tutorial.md:1743
+msgid ""
+"Throughout this tutorial, we've been defining functions that act only on "
+"specific data types. With type parameters we can also define functions whose "
+"arguments have generic types, and which can be invoked with a variety of "
+"types. Consider a generic `map` function, which takes a function `function` "
+"and a vector `vector` and returns a new vector consisting of the result of "
+"applying `function` to each element of `vector`:"
+msgstr ""
+"このチュートリアルでは、特定のデータ型のみに対して動作する関数を定義してきま"
+"した。型パラメータを用いるとジェネリックな型を引数にとり、様々な型で呼び出す"
+"ことの可能な関数を定義できます。関数 `function` とベクタ `vector` を引数にと"
+"り、`function` を`vector` の各要素に適用した結果からなる新たなベクタを返す、"
+"`map` というジェネリック関数について考えます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1753
+#, no-wrap
+msgid ""
+"~~~~\n"
+"fn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {\n"
+"    let mut accumulator = ~[];\n"
+"    for element in vector.iter() {\n"
+"        accumulator.push(function(element));\n"
+"    }\n"
+"    return accumulator;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1758
+msgid ""
+"When defined with type parameters, as denoted by `<T, U>`, this function can "
+"be applied to any type of vector, as long as the type of `function`'s "
+"argument and the type of the vector's contents agree with each other."
+msgstr ""
+"上記例で `<T, U>` と示されているように、型パラメータとともに関数を定義するこ"
+"とで、`function` の引数の型と`vectror` の要素の型が一致する場合に限りますが、"
+"任意の型のベクタを引数として渡すことが可能になります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1768
+msgid ""
+"Inside a generic function, the names of the type parameters (capitalized by "
+"convention) stand for opaque types. All you can do with instances of these "
+"types is pass them around: you can't apply any operations to them or pattern-"
+"match on them. Note that instances of generic types are often passed by "
+"pointer. For example, the parameter `function()` is supplied with a pointer "
+"to a value of type `T` and not a value of type `T` itself. This ensures that "
+"the function works with the broadest set of types possible, since some types "
+"are expensive or illegal to copy and pass by value."
+msgstr ""
+"ジェネリック関数の内部では、型パラメータの名前 (慣例的に大文字で表されます) "
+"は不透明型 (opaque type) を意味します。これらの型のインスタンスに対しては、他"
+"の関数に渡すことだけが可能で、演算子を適用したり、パターンマッチすることはで"
+"きません。ジェネリック型のインスタンスは、ポインタにより渡されることもあるこ"
+"とに注意してください。例えば、 `function()` パラメータが `T` 型自身の値ではな"
+"く `T` 型の値へのポインタとして渡されるということです。いくつかの型は、値をコ"
+"ピーするコストが高かったり、コピーが禁じられていたりするので、ポインタ渡しに"
+"することで、関数の引数としてとることのできる型の範囲が広がります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1770
+msgid ""
+"Generic `type`, `struct`, and `enum` declarations follow the same pattern:"
+msgstr ""
+"ジェネリックな型、構造体、および列挙型の宣言は、同じパターンに従います。"
+
+#. type: Plain text
+#: doc/tutorial.md:1774
+msgid "~~~~ use std::hashmap::HashMap; type Set<T> = HashMap<T, ()>;"
+msgstr ""
+"~~~~\n"
+"use std::hashmap::HashMap;\n"
+"type Set<T> = HashMap<T, ()>;"
+
+#. type: Plain text
+#: doc/tutorial.md:1778
+#, no-wrap
+msgid ""
+"struct Stack<T> {\n"
+"    elements: ~[T]\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1784
+#, no-wrap
+msgid ""
+"enum Option<T> {\n"
+"    Some(T),\n"
+"    None\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1787
+msgid ""
+"These declarations can be instantiated to valid types like `Set<int>`, "
+"`Stack<int>`, and `Option<int>`."
+msgstr ""
+"これらの宣言により、 `Set<int>` や `Stack<int>`、 `Option<int>` のような正当"
+"な型を生成することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1793
+msgid ""
+"The last type in that example, `Option`, appears frequently in Rust code.  "
+"Because Rust does not have null pointers (except in unsafe code), we need "
+"another way to write a function whose result isn't defined on every possible "
+"combination of arguments of the appropriate types. The usual way is to write "
+"a function that returns `Option<T>` instead of `T`."
+msgstr ""
+"最後の例の `Option` 型は、Rust のコード中に頻繁に現れます。Rust には null ポ"
+"インタが存在しない (unsafe なコードを除く) ため、引数の組み合わせがとりうるす"
+"べての値に対し結果が定義されないような関数を記述するための別の方法が必要で"
+"す。このような場合には、 `T` 型ではなく `Option<T>` 型を返すよう関数を定義す"
+"ることが一般的です。"
+
+#. type: Plain text
+#: doc/tutorial.md:1804
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# struct Point { x: float, y: float }\n"
+"# enum Shape { Circle(Point, float), Rectangle(Point, Point) }\n"
+"fn radius(shape: Shape) -> Option<float> {\n"
+"    match shape {\n"
+"        Circle(_, radius) => Some(radius),\n"
+"        Rectangle(*)      => None\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1812
+msgid ""
+"The Rust compiler compiles generic functions very efficiently by "
+"*monomorphizing* them. *Monomorphization* is a fancy name for a simple idea: "
+"generate a separate copy of each generic function at each call site, a copy "
+"that is specialized to the argument types and can thus be optimized "
+"specifically for them. In this respect, Rust's generics have similar "
+"performance characteristics to C++ templates."
+msgstr ""
+"Rust のコンパイラは、ジェネリック関数を *monomorphizing* することで効率的にコ"
+"ンパイルします。*monomorphization* という名前は大げさに聞こえますが、考え方は"
+"単純です。ジェネリック関数のコピーを関数の呼び出し箇所に別々に生成し、引数の"
+"型により特殊化された各コピーは、それぞれの特性に応じて最適化が施されます。こ"
+"の点において、Rust のジェネリクスは C++ のテンプレートと似たパフォーマンス上"
+"の特性を持ちます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1814
+msgid "## Traits"
+msgstr "## トレイト"
+
+#. type: Plain text
+#: doc/tutorial.md:1824
+msgid ""
+"Within a generic function the operations available on generic types are very "
+"limited. After all, since the function doesn't know what types it is "
+"operating on, it can't safely modify or query their values. This is where "
+"_traits_ come into play. Traits are Rust's most powerful tool for writing "
+"polymorphic code. Java developers will see them as similar to Java "
+"interfaces, and Haskellers will notice their similarities to type classes. "
+"Rust's traits are a form of *bounded polymorphism*: a trait is a way of "
+"limiting the set of possible types that a type parameter could refer to."
+msgstr ""
+"ジェネリック関数の内部では、ジェネリック型に対して非常に限られた操作しか行え"
+"ません。つまるところ、ジェネリック関数は操作の対象とする型が何なのか知らない"
+"ため、対象の値を安全に変更・参照することができません。__トレイト__ (_trait_) "
+"の出番です。トレイトは Rust でポリモーフィックなコードを書くための最も強力な"
+"ツールです。Java 開発者にとってトレイトは Java のインターフェースのように見え"
+"ますし、Haskeller は型クラスとの類似点に気づくでしょう。Rust のトレイトは **"
+"有界ポリモーフィズム** (*bounded polymorphism*) の形式をとります。トレイトに"
+"より、型パラメータが示す得る型の集合を限定することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1832
+msgid ""
+"As motivation, let us consider copying in Rust.  The `clone` method is not "
+"defined for all Rust types.  One reason is user-defined destructors: copying "
+"a type that has a destructor could result in the destructor running multiple "
+"times.  Therefore, types with destructors cannot be copied unless you "
+"explicitly implement `Clone` for them."
+msgstr ""
+"トレイト導入の動機となる例として、Rust でのコピーについて考えます。`clone` メ"
+"ソッドはすべての Rust の型に対して定義されていません。定義されていない理由の"
+"一つとして、ユーザ定義のデストラクタの存在が挙げられます。デストラクタを持つ"
+"型をコピーすることで、デストラクタが複数回実行されるという事態を招いてしまう"
+"かもしれません。そのため、明示的に `Clone` を実装していない型を除き、デストラ"
+"クタをもつ型をコピーすることはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1837
+msgid ""
+"This complicates handling of generic functions.  If you have a type "
+"parameter `T`, can you copy values of that type? In Rust, you can't, and if "
+"you try to run the following code the compiler will complain."
+msgstr ""
+"このことはジェネリック関数の扱い方を複雑にします。型パラメータ `T` が存在した"
+"として、この型の値をコピーすることができるでしょうか?Rust では、コピーするこ"
+"とはできません。以下のコードを実行しようとしてもコンパイラが文句を言うでしょ"
+"う。"
+
+#. type: Plain text
+#: doc/tutorial.md:1844
+#, no-wrap
+msgid ""
+"~~~~ {.xfail-test}\n"
+"// This does not compile\n"
+"fn head_bad<T>(v: &[T]) -> T {\n"
+"    v[0] // error: copying a non-copyable value\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"~~~~ {.xfail-test}\n"
+"// このコードはコンパイルできない\n"
+"fn head_bad<T>(v: &[T]) -> T {\n"
+"    v[0] // error: copying a non-copyable value\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1851
+msgid ""
+"However, we can tell the compiler that the `head` function is only for "
+"copyable types: that is, those that implement the `Clone` trait.  In that "
+"case, we can explicitly create a second copy of the value we are returning "
+"using the `clone` keyword:"
+msgstr ""
+"`head` 関数はコピー可能な型、つまり `Clone` トレイトを実装している型だけを対"
+"象にしていることをコンパイラに教えることはできます。この場合、`clone` メソッ"
+"ドを使うことで、値のコピーを明示的に作成し、戻り値として返すことができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1858
+#, no-wrap
+msgid ""
+"~~~~\n"
+"// This does\n"
+"fn head<T: Clone>(v: &[T]) -> T {\n"
+"    v[0].clone()\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"~~~~\n"
+"// このコードはコンパイルできる\n"
+"fn head<T: Clone>(v: &[T]) -> T {\n"
+"    v[0].clone()\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1866
+msgid ""
+"This says that we can call `head` on any type `T` as long as that type "
+"implements the `Clone` trait.  When instantiating a generic function, you "
+"can only instantiate it with types that implement the correct trait, so you "
+"could not apply `head` to a type that does not implement `Clone`."
+msgstr ""
+"このことは、`Clone` トレイトを実装している任意の型 `T` について、 `head` 関数"
+"を呼び出すことができることを示しています。ジェネリック関数を実体化する場合、"
+"正しいトレイトを実装した型を用いた場合のみ実体化できます。つまり、`Clone` ト"
+"レイトを実装していない型に対して `head` を呼び出すことはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1871
+msgid ""
+"While most traits can be defined and implemented by user code, two traits "
+"are automatically derived and implemented for all applicable types by the "
+"compiler, and may not be overridden:"
+msgstr ""
+"ほとんどのトレイトはユーザコードにより定義・実装できますが、2つのトレイトはコ"
+"ンパイラにより自動的に導出され、適用可能なすべての型に対し自動的に実装され、"
+"上書きすることはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:1875
+#, no-wrap
+msgid ""
+"* `Send` - Sendable types.\n"
+"Types are sendable\n"
+"unless they contain managed boxes, managed closures, or borrowed pointers.\n"
+msgstr ""
+"* `Send` - 送信可能な型。\n"
+"マネージドボックスやマネージドクロージャ、借用ポインタを含まない場合、型は送信可能である。"
+
+#. type: Plain text
+#: doc/tutorial.md:1880
+#, no-wrap
+msgid ""
+"* `Freeze` - Constant (immutable) types.\n"
+"These are types that do not contain anything intrinsically mutable.\n"
+"Intrinsically mutable values include `@mut`\n"
+"and `Cell` in the standard library.\n"
+msgstr ""
+"* `Freeze` - 定数 (イミュータブル) 型。\n"
+"本質的に変更可能な値を含まない型のことです。本質的に変更可能な値には、`@mut` や標準ライブラリで定義されている `Cell` が含まれます。\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1883
+msgid ""
+"> ***Note:*** These two traits were referred to as 'kinds' in earlier > "
+"iterations of the language, and often still are."
+msgstr ""
+"> ***注意*** これら2つのトレイトは、以前は 「種」 (kind) と呼ばれており、現在"
+"でもそう呼ばれる場合があります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1889
+msgid ""
+"Additionally, the `Drop` trait is used to define destructors. This trait "
+"defines one method called `drop`, which is automatically called when a value "
+"of the type that implements this trait is destroyed, either because the "
+"value went out of scope or because the garbage collector reclaimed it."
+msgstr ""
+"上記に加え、 `Drop` トレイトはデストラクタを定義するために使われます。このト"
+"レイトは `drop` というこのトレイトを実装した型が破壊されるタイミング(値がス"
+"コープの外に出たタイミングか、ガベージコレクタが回収するタイミング) で呼び出"
+"されるメソッドを1つ定義しています。"
+
+#. type: Plain text
+#: doc/tutorial.md:1894
+#, no-wrap
+msgid ""
+"~~~\n"
+"struct TimeBomb {\n"
+"    explosivity: uint\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1903
+#, no-wrap
+msgid ""
+"impl Drop for TimeBomb {\n"
+"    fn drop(&self) {\n"
+"        for _ in range(0, self.explosivity) {\n"
+"            println(\"blam!\");\n"
+"        }\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1906
+msgid ""
+"It is illegal to call `drop` directly. Only code inserted by the compiler "
+"may call it."
+msgstr ""
+"`drop` を直接呼び出すことはできません。コンパイラにより挿入されたコードのみ"
+"が `drop` を呼び出すことができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1908
+msgid "## Declaring and implementing traits"
+msgstr "## トレイトの宣言と実装"
+
+#. type: Plain text
+#: doc/tutorial.md:1914
+msgid ""
+"A trait consists of a set of methods without bodies, or may be empty, as is "
+"the case with `Send` and `Freeze`.  For example, we could declare the trait "
+"`Printable` for things that can be printed to the console, with a single "
+"method:"
+msgstr ""
+"トレイトはボディを持たないメソッドの集合から構成されるか、 `Send` や "
+"`Freeze` トレイトのように空の場合があります。例えば、コンソールに出力可能なも"
+"のを表しメソッドを1つもつ `Printable` トレイトは以下のように宣言できます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1920
+#, no-wrap
+msgid ""
+"~~~~\n"
+"trait Printable {\n"
+"    fn print(&self);\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1925
+msgid ""
+"Traits may be implemented for specific types with [impls]. An impl that "
+"implements a trait includes the name of the trait at the start of the "
+"definition, as in the following impls of `Printable` for `int` and `~str`."
+msgstr ""
+"[impl][impls] により特定の型にトレイトを実装することができます。トレイトを実"
+"装する impl は、以下の `Printable` の `int` と `~str` に対する実装のように、"
+"定義の先頭にトレイトの名前を含みます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1927
+msgid "[impls]: #methods"
+msgstr "[impls]: #メソッド"
+
+#. type: Plain text
+#: doc/tutorial.md:1933
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# trait Printable { fn print(&self); }\n"
+"impl Printable for int {\n"
+"    fn print(&self) { println(fmt!(\"%d\", *self)) }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1937
+#, no-wrap
+msgid ""
+"impl Printable for ~str {\n"
+"    fn print(&self) { println(*self) }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1941
+msgid "# 1.print(); # (~\"foo\").print(); ~~~~"
+msgstr ""
+"# 1.print();\n"
+"# (~\"foo\").print();\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:1946
+msgid ""
+"Methods defined in an implementation of a trait may be called just like any "
+"other method, using dot notation, as in `1.print()`. Traits may themselves "
+"contain type parameters. A trait for generalized sequence types might look "
+"like the following:"
+msgstr ""
+"トレイトの実装により定義されたメソッドは他のメソッドと全く同じように、ドット"
+"記法を用いて `1.print()` のように呼び出せます。トレイト自体に型パラメータを持"
+"たせることもできます。一般化されたシーケンスを表すトレイトは以下のように定義"
+"されるでしょう。"
+
+#. type: Plain text
+#: doc/tutorial.md:1951
+#, no-wrap
+msgid ""
+"~~~~\n"
+"trait Seq<T> {\n"
+"    fn length(&self) -> uint;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1956
+#, no-wrap
+msgid ""
+"impl<T> Seq<T> for ~[T] {\n"
+"    fn length(&self) -> uint { self.len() }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:1963
+msgid ""
+"The implementation has to explicitly declare the type parameter that it "
+"binds, `T`, before using it to specify its trait type. Rust requires this "
+"declaration because the `impl` could also, for example, specify an "
+"implementation of `Seq<int>`. The trait type (appearing between `impl` and "
+"`for`) *refers* to a type, rather than defining one."
+msgstr ""
+"実装が束縛する型パラメータ `T` は、トレイトの型を指定する前に明示的に宣言しな"
+"ければなりません。Rust でこの宣言が必要なのは、 `impl` では例えば `Seq<int>` "
+"の実装を指定することも可能だからです。トレイトの型 (`impl` と `for` の間に現"
+"れるもの) は、型を定義するのではなく、型を **参照** します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1968
+msgid ""
+"The type parameters bound by a trait are in scope in each of the method "
+"declarations. So, re-declaring the type parameter `T` as an explicit type "
+"parameter for `len`, in either the trait or the impl, would be a compile-"
+"time error."
+msgstr ""
+"トレイトにより束縛される型パラメータは、各メソッドの宣言のスコープに属しま"
+"す。したがって、trait と impl のいずれかで、型パラメータ `T` を `len` で用い"
+"る明示的な型パラメータとして再宣言すると、コンパイル時エラーとなります。"
+
+#. type: Plain text
+#: doc/tutorial.md:1973
+msgid ""
+"Within a trait definition, `Self` is a special type that you can think of as "
+"a type parameter. An implementation of the trait for any given type `T` "
+"replaces the `Self` type parameter with `T`. The following trait describes "
+"types that support an equality operation:"
+msgstr ""
+"トレイトの定義内部では、`Self` は型パラメータとみなすことのできる特別な型とな"
+"ります。型 `T` に対するトレイトの実装では `Self` は型パラメータ `T` で置き換"
+"えられます。以下のトレイトは等価性演算をサポートする型を意味します。"
+
+#. type: Plain text
+#: doc/tutorial.md:1980
+#, no-wrap
+msgid ""
+"~~~~\n"
+"// In a trait, `self` refers to the self argument.\n"
+"// `Self` refers to the type implementing the trait.\n"
+"trait Eq {\n"
+"    fn equals(&self, other: &Self) -> bool;\n"
+"}\n"
+msgstr ""
+"~~~~\n"
+"// trait の内側では, `self` は self 引数を指します。\n"
+"// `Self` はトレイトを実装する型を指します。\n"
+"trait Eq {\n"
+"    fn equals(&self, other: &Self) -> bool;\n"
+"}\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1986
+#, no-wrap
+msgid ""
+"// In an impl, `self` refers just to the value of the receiver\n"
+"impl Eq for int {\n"
+"    fn equals(&self, other: &int) -> bool { *other == *self }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+"// impl の内側では `self` はレシーバの値を指します\n"
+"impl Eq for int {\n"
+"    fn equals(&self, other: &int) -> bool { *other == *self }\n"
+"}\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:1991
+msgid ""
+"Notice that in the trait definition, `equals` takes a second parameter of "
+"type `Self`.  In contrast, in the `impl`, `equals` takes a second parameter "
+"of type `int`, only using `self` as the name of the receiver."
+msgstr ""
+"トレイトの定義では、`equals` の第二引数の型は `Self` であることに注意してくだ"
+"さい。対照的に `impl` では、 `equals` の第二引数の型は `int` で、 `self` はレ"
+"シーバの名前としてのみ使用されます。"
+
+#. type: Plain text
+#: doc/tutorial.md:1996
+msgid ""
+"Just as in type implementations, traits can define standalone (static)  "
+"methods.  These methods are called by prefixing the method name with the "
+"trait name and a double colon.  The compiler uses type inference to decide "
+"which implementation to use."
+msgstr ""
+"型への実装の場合と同様、トレイトもスタンドアロン (静的) メソッドを定義するこ"
+"とができます。メソッド名の前にトレイト名とコロン2つをつけることで、これらのメ"
+"ソッドを呼び出すことができます。コンパイラはどの実装を利用するか決定するた"
+"め、型推論を行います。"
+
+#. type: Plain text
+#: doc/tutorial.md:2002
+msgid ""
+"~~~~ use std::float::consts::pi; trait Shape { fn new(area: float) -> "
+"Self; } struct Circle { radius: float } struct Square { length: float }"
+msgstr ""
+"~~~~\n"
+"use std::float::consts::pi;\n"
+"trait Shape { fn new(area: float) -> Self; }\n"
+"struct Circle { radius: float }\n"
+"struct Square { length: float }"
+
+#. type: Plain text
+#: doc/tutorial.md:2009
+#, no-wrap
+msgid ""
+"impl Shape for Circle {\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: (area).sqrt() } }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2014
+msgid ""
+"let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::"
+"new(area); ~~~~"
+msgstr ""
+"let area = 42.5;\n"
+"let c: Circle = Shape::new(area);\n"
+"let s: Square = Shape::new(area);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2016
+msgid "## Bounded type parameters and static method dispatch"
+msgstr "## 境界型パラメータと静的メソッドディスパッチ"
+
+#. type: Plain text
+#: doc/tutorial.md:2021
+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_ "
+"on type parameters, so that we can then operate on generic types."
+msgstr ""
+"トレイトは型の述語 (predicate) や型がもつことのできる抽象的な属性を定義するた"
+"めの言語として利用することができます。この言語を使うこととで型パラメータの __"
+"境界__ (_bound_) を定義することができ、ジェネリックな型を操作することが可能に"
+"なります。"
+
+#. type: Plain text
+#: doc/tutorial.md:2030
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# trait Printable { fn print(&self); }\n"
+"fn print_all<T: Printable>(printable_things: ~[T]) {\n"
+"    for thing in printable_things.iter() {\n"
+"        thing.print();\n"
+"    }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2036
+msgid ""
+"Declaring `T` as conforming to the `Printable` trait (as we earlier did with "
+"`Clone`) makes it possible to call methods from that trait on values of type "
+"`T` inside the function. It will also cause a compile-time error when anyone "
+"tries to call `print_all` on an array whose element type does not have a "
+"`Printable` implementation."
+msgstr ""
+"(先に登場した `Clone` の例のように) `T` が `Printable` トレイトに従うことを宣"
+"言することで、関数内部で `T` 型の値に対して `Printable` トレイトのメソッドを"
+"呼び出すことが可能になります。また、この宣言により、`Printable` を実装してい"
+"ない型を要素とする配列に対して `print_all` 関数を呼びだそうとすると、コンパイ"
+"ル時エラーとなります。"
+
+#. type: Plain text
+#: doc/tutorial.md:2039
+msgid ""
+"Type parameters can have multiple bounds by separating them with `+`, as in "
+"this version of `print_all` that copies elements."
+msgstr ""
+"型パラメータは `+` で区切ることで複数の境界を持つことができます。以下の "
+"`print_all` は、ベクタの要素をコピーするバージョンです。"
+
+#. type: Plain text
+#: doc/tutorial.md:2051
+#, no-wrap
+msgid ""
+"~~~\n"
+"# trait Printable { fn print(&self); }\n"
+"fn print_all<T: Printable + Clone>(printable_things: ~[T]) {\n"
+"    let mut i = 0;\n"
+"    while i < printable_things.len() {\n"
+"        let copy_of_thing = printable_things[i].clone();\n"
+"        copy_of_thing.print();\n"
+"        i += 1;\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2055
+msgid ""
+"Method calls to bounded type parameters are _statically dispatched_, "
+"imposing no more overhead than normal function invocation, so are the "
+"preferred way to use traits polymorphically."
+msgstr ""
+"境界型パラメータに対するメソッドの呼び出しは __静的にディスパッチ__ "
+"(_statically dispatched_) されるため、通常の関数呼び出し以上のオーバーヘッド"
+"は発生しません。そのため、ポリモーフィックにトレイトを使う方法としては、境界"
+"型パラメータが推奨されます。 "
+
+#. type: Plain text
+#: doc/tutorial.md:2057
+msgid "This usage of traits is similar to Haskell type classes."
+msgstr "トレイトのこのような使い方は、Haskell の型クラスと似ています。"
+
+#. type: Plain text
+#: doc/tutorial.md:2059
+msgid "## Trait objects and dynamic method dispatch"
+msgstr "## トレイトオブジェクトと動的メソッドディスパッチ"
+
+#. type: Plain text
+#: doc/tutorial.md:2063
+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 "
+"this function:"
+msgstr ""
+"上述の例では、指定されたトレイトに従う、単一の未知の型の値についてポリモー"
+"フィックにふるまう関数を定義しました。ここでは、以下の関数について考えます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2069
+msgid ""
+"~~~~ # type Circle = int; type Rectangle = int; # impl Drawable for int { fn "
+"draw(&self) {} } # fn new_circle() -> int { 1 } trait Drawable { fn "
+"draw(&self); }"
+msgstr ""
+"~~~~\n"
+"# type Circle = int; type Rectangle = int;\n"
+"# impl Drawable for int { fn draw(&self) {} }\n"
+"# fn new_circle() -> int { 1 }\n"
+"trait Drawable { fn draw(&self); }"
+
+#. type: Plain text
+#: doc/tutorial.md:2076
+#, no-wrap
+msgid ""
+"fn draw_all<T: Drawable>(shapes: ~[T]) {\n"
+"    for shape in shapes.iter() { shape.draw(); }\n"
+"}\n"
+"# let c: Circle = new_circle();\n"
+"# draw_all(~[c]);\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2082
+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 "
+"array containing both circles and rectangles. When such behavior is needed, "
+"a trait name can alternately be used as a type, called an _object_."
+msgstr ""
+"円の配列や長方形の配列に対してこの関数を呼び出すことは (円や長方形に対し適切"
+"に `Drawable` トレイトが定義されていると仮定すれば) 可能ですが、円や長方形を"
+"両方共含む配列に対しては呼び出すことができません。そのような動作が必要な場"
+"合、__オブジェクト__  型として、トレイトの名前を代わりに利用することができま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:2089
+#, no-wrap
+msgid ""
+"~~~~\n"
+"# trait Drawable { fn draw(&self); }\n"
+"fn draw_all(shapes: &[@Drawable]) {\n"
+"    for shape in shapes.iter() { shape.draw(); }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2094
+msgid ""
+"In this example, there is no type parameter. Instead, the `@Drawable` type "
+"denotes any managed box value that implements the `Drawable` trait. To "
+"construct such a value, you use the `as` operator to cast a value to an "
+"object:"
+msgstr ""
+"この例中には、型パラメータはありません。代わりに、「`Drawable` トレイトを実装"
+"した、任意のマネージドボックス値」を表す型  `@Drawable` 型があります。このよ"
+"うな値を作成するには、 `as` 演算子を使って値をオブジェクトへキャストします。"
+
+#. type: Plain text
+#: doc/tutorial.md:2101
+msgid ""
+"~~~~ # type Circle = int; type Rectangle = bool; # trait Drawable { fn "
+"draw(&self); } # fn new_circle() -> Circle { 1 } # fn new_rectangle() -> "
+"Rectangle { true } # fn draw_all(shapes: &[@Drawable]) {}"
+msgstr ""
+"~~~~\n"
+"# type Circle = int; type Rectangle = bool;\n"
+"# trait Drawable { fn draw(&self); }\n"
+"# fn new_circle() -> Circle { 1 }\n"
+"# fn new_rectangle() -> Rectangle { true }\n"
+"# fn draw_all(shapes: &[@Drawable]) {}"
+
+#. type: Plain text
+#: doc/tutorial.md:2104
+msgid ""
+"impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for "
+"Rectangle { fn draw(&self) { ... } }"
+msgstr ""
+"impl Drawable for Circle { fn draw(&self) { ... } }\n"
+"impl Drawable for Rectangle { fn draw(&self) { ... } }"
+
+#. type: Plain text
+#: doc/tutorial.md:2109
+msgid ""
+"let c: @Circle = @new_circle(); let r: @Rectangle = @new_rectangle(); "
+"draw_all([c as @Drawable, r as @Drawable]); ~~~~"
+msgstr ""
+"let c: @Circle = @new_circle();\n"
+"let r: @Rectangle = @new_rectangle();\n"
+"draw_all([c as @Drawable, r as @Drawable]);\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2117
+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 "
+"strings and vectors, objects have dynamic size and may only be referred to "
+"via one of the pointer types.  Other pointer types work as well.  Casts to "
+"traits may only be done with compatible pointers so, for example, an "
+"`@Circle` may not be cast to an `~Drawable`."
+msgstr ""
+"`new_circle` と `new_rectangle` のコードは省略されていますが、デフォルトのサ"
+"イズをもつ `Circle` と `Rectangle` をただ返すものだと考えてください。文字列や"
+"ベクタのように、オブジェクトも動的なサイズを持ち、いずれかのポインタ型を経由"
+"してしか参照できないことに注意してください。他のポインタ型でもうまく動作しま"
+"す。トレイトへのキャストは互換性のあるポインタの場合しか行えません。例えば、"
+"`@Cicle` を `~Drawable` にキャストすることはできません。"
+
+#. type: Plain text
+#: doc/tutorial.md:2131
+msgid ""
+"~~~ # type Circle = int; type Rectangle = int; # trait Drawable { fn "
+"draw(&self); } # impl Drawable for int { fn draw(&self) {} } # fn "
+"new_circle() -> int { 1 } # fn new_rectangle() -> int { 2 } // A managed "
+"object let boxy: @Drawable = @new_circle() as @Drawable; // An owned object "
+"let owny: ~Drawable = ~new_circle() as ~Drawable; // A borrowed object let "
+"stacky: &Drawable = &new_circle() as &Drawable; ~~~"
+msgstr ""
+"~~~\n"
+"# type Circle = int; type Rectangle = int;\n"
+"# trait Drawable { fn draw(&self); }\n"
+"# impl Drawable for int { fn draw(&self) {} }\n"
+"# fn new_circle() -> int { 1 }\n"
+"# fn new_rectangle() -> int { 2 }\n"
+"// A managed object\n"
+"let boxy: @Drawable = @new_circle() as @Drawable;\n"
+"// An owned object\n"
+"let owny: ~Drawable = ~new_circle() as ~Drawable;\n"
+"// A borrowed object\n"
+"let stacky: &Drawable = &new_circle() as &Drawable;\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2136
+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 "
+"lookup table (also known as a vtable or dictionary) to select the method to "
+"call at runtime."
+msgstr ""
+"トレイト型のメソッド呼び出しは __動的にディスパッチ__ (_dynamically "
+"dispatched_) されます。どの関数を呼び出すべきかコンパイル時にはわからないた"
+"め、ルックアップテーブル (vtable や dictionary としても知られている) を用い"
+"て、呼び出すメソッドの選択を実行時に行います。"
+
+#. type: Plain text
+#: doc/tutorial.md:2138
+msgid "This usage of traits is similar to Java interfaces."
+msgstr "トレイトのこのような使い方は、Java のインターフェースと似ています。"
+
+#. type: Plain text
+#: doc/tutorial.md:2140
+msgid "## Trait inheritance"
+msgstr "## トレイトの継承"
+
+#. type: Plain text
+#: doc/tutorial.md:2145
+msgid ""
+"We can write a trait declaration that _inherits_ from other traits, called "
+"_supertraits_.  Types that implement a trait must also implement its "
+"supertraits.  For example, we can define a `Circle` trait that inherits from "
+"`Shape`."
+msgstr ""
+"__スーパートレイト__ と呼ばれる他のトレイトから __継承した__ トレイトを宣言す"
+"ることができます。継承されたトレイトを実装する型は、スーパートレイトも実装し"
+"なければなりません。例えば、 `Circle` トレイトを `Shape` トレイトを継承したも"
+"のとして定義できます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2150
+msgid ""
+"~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn "
+"radius(&self) -> float; } ~~~~"
+msgstr ""
+"~~~~\n"
+"trait Shape { fn area(&self) -> float; }\n"
+"trait Circle : Shape { fn radius(&self) -> float; }\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2152
+msgid ""
+"Now, we can implement `Circle` on a type only if we also implement `Shape`."
+msgstr "`Circle` トレイトの実装は、 `Shape` を実装した型についてのみ行えます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2167
+#, no-wrap
+msgid ""
+"~~~~\n"
+"use std::float::consts::pi;\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 { (self.area() / pi).sqrt() }\n"
+"}\n"
+"impl Shape for CircleStruct {\n"
+"    fn area(&self) -> float { pi * square(self.radius) }\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2172
+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 "
+"radius of a circle (since we could just return the `radius` field), but you "
+"get the idea."
+msgstr ""
+"`radius` の実装から `area` メソッドを呼び出せるように、`Circle` のメソッドは "
+"`Shape` のメソッドを呼び出せることに注意してください。(単純に `radius` フィー"
+"ルドの値を返すことができるにも関わらず) 円の半径を面積から計算するのは馬鹿げ"
+"ていますが、メソッド呼び出しの考え方は分かったでしょう。"
+
+#. type: Plain text
+#: doc/tutorial.md:2196
+msgid ""
+"~~~ {.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 ""
+"~~~ {.xfail-test}\n"
+"use std::float::consts::pi;\n"
+"# trait Shape { fn area(&self) -> float; }\n"
+"# trait Circle : Shape { fn radius(&self) -> float; }\n"
+"# struct Point { x: float, y: float }\n"
+"# struct CircleStruct { center: Point, radius: float }\n"
+"# impl Circle for CircleStruct { fn radius(&self) -> float { (self.area() / "
+"pi).sqrt() } }\n"
+"# impl Shape for CircleStruct { fn area(&self) -> float { pi * square(self."
+"radius) } }"
+
+#. type: Plain text
+#: doc/tutorial.md:2201
+msgid ""
+"let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; let "
+"mycircle: @Circle = concrete as @Circle; let nonsense = mycircle.radius() * "
+"mycircle.area(); ~~~"
+msgstr ""
+"let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f};\n"
+"let mycircle: @Circle = concrete as @Circle;\n"
+"let nonsense = mycircle.radius() * mycircle.area();\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2203
+msgid "> ***Note:*** Trait inheritance does not actually work with objects yet"
+msgstr ""
+"> ***注意*** トレイトの継承は、実際にはまだオブジェクトに対しては動作しませ"
+"ん。"
+
+#. type: Plain text
+#: doc/tutorial.md:2205
+msgid "## Deriving implementations for traits"
+msgstr "## トレイトの実装の導出"
+
+#. type: Plain text
+#: doc/tutorial.md:2212
+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 "
+"`deriving` attribute on a data type declaration. For example, the following "
+"will mean that `Circle` has an implementation for `Eq` and can be used with "
+"the equality operators, and that a value of type `ABC` can be randomly "
+"generated and converted to a string:"
+msgstr ""
+"`std` と `extra` で定義されているいくつかのトレイトは、自動的に実装を導出可能"
+"です。データ型の宣言時に `deriving` 属性を書くことで、これらのトレイトを実装"
+"することを指定します。例えば、以下の例では `Circle` は `Eq` を実装し等価演算"
+"子で比較することが可能であり、`ABC` 型の値はランダムに生成することや、文字列"
+"に変換することが可能です。"
+
+#. type: Plain text
+#: doc/tutorial.md:2216
+msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }"
+msgstr ""
+"~~~\n"
+"#[deriving(Eq)]\n"
+"struct Circle { radius: float }"
+
+#. type: Plain text
+#: doc/tutorial.md:2220
+msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~"
+msgstr ""
+"#[deriving(Rand, ToStr)]\n"
+"enum ABC { A, B, C }\n"
+"~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2224
+msgid ""
+"The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
+"`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, "
+"and `ToStr`."
+msgstr ""
+"実装を自動的に導出可能なトレイトは、 `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
+"`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, "
+"および `ToStr` です。."
+
+#. type: Plain text
+#: doc/tutorial.md:2226
+msgid "# Modules and crates"
+msgstr "# モジュールとクレート"
+
+#. type: Plain text
+#: doc/tutorial.md:2230
+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 ""
+"Rust の名前空間はモジュールの階層に配置されている。それぞれのソース (.rs) "
+"ファイルは単一のモジュールを表し、追加のモジュールを含んでいる場合もある。"
+
+#. type: Plain text
+#: doc/tutorial.md:2236
+#, no-wrap
+msgid ""
+"~~~~\n"
+"mod farm {\n"
+"    pub fn chicken() -> &str { \"cluck cluck\" }\n"
+"    pub fn cow() -> &str { \"mooo\" }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2241
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    println(farm::chicken());\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2246
+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 "
+"beginning of crates, `mod`s, `fn`s, and other blocks."
+msgstr ""
+"でモジュールの内容は`use` キーワードにより現在のスコープにインポートすること"
+"ができます。必要に応じて別名を付けることもできます。`use` はクレートの先頭や "
+"`mod`, `fn` などのブロックの先頭に記述することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2252
+msgid ""
+"~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` "
+"into scope use farm::chicken;"
+msgstr ""
+"~~~\n"
+"# mod farm { pub fn chicken() { } }\n"
+"# fn main() {\n"
+"// `chicken` を現在のスコープに持ち込む\n"
+"use farm::chicken;"
+
+#. type: Plain text
+#: doc/tutorial.md:2262
+#, no-wrap
+msgid ""
+"fn chicken_farmer() {\n"
+"    // The same, but name it `my_chicken`\n"
+"    use my_chicken = farm::chicken;\n"
+"    ...\n"
+"# my_chicken();\n"
+"}\n"
+"# chicken();\n"
+"# }\n"
+"~~~\n"
+msgstr ""
+"fn chicken_farmer() {\n"
+"    // 同じことをするが、名前を `my_chicken` とする\n"
+"    use my_chicken = farm::chicken;\n"
+"    ...\n"
+"# my_chicken();\n"
+"}\n"
+"# chicken();\n"
+"# }\n"
+"~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:2269
+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 "
+"containing module. An expression with `::`, like `farm::chicken`, can name "
+"an item outside of its containing module. Items, such as those declared with "
+"`fn`, `struct`, `enum`, `type`, or `static`, are module-private by default."
+msgstr ""
+"farm モジュールの動物の関数定義には、 `pub` という新しいキーワードが付けられ"
+"ています。`pub` キーワードは項目の可視性を変更し、項目を含んでいるモジュール"
+"の外側から見えるようにします。`farm::chicken` のような、 `::` を含む式は、式"
+"を含むモジュールの外側の項目を指定することができます。`fn` や `struct`, "
+"`enum`, `type`, `static` により宣言される項目の可視性は、デフォルトではモ"
+"ジュールプライベート (同一モジュール内からのみ参照可能)です。"
+
+#. type: Plain text
+#: doc/tutorial.md:2276
+msgid ""
+"Visibility restrictions in Rust exist only at module boundaries. This is "
+"quite different from most object-oriented languages that also enforce "
+"restrictions on objects themselves. That's not to say that Rust doesn't "
+"support encapsulation: both struct fields and methods can be private. But "
+"this encapsulation is at the module level, not the struct level. Note that "
+"fields and methods are _public_ by default."
+msgstr ""
+"Rust での可視性の制約はモジュールの境界にのみ存在します。これは、オブジェクト"
+"自体にも可視性の制約を課すほとんどのオブジェクト指向言語とは全く異なっていま"
+"す。しかし、Rust がカプセル化をサポートしていないというわけではありません。構"
+"造体のフィールドとメソッドはプライベートにすることができます。しかし、このカ"
+"プセル化はモジュールレベルで働くもので、構造体のレベルで働くものではありませ"
+"ん。フィールドとメソッドでは、デフォルトでは __パブリック__ であることに注意"
+"してください。"
+
+#. type: Plain text
+#: doc/tutorial.md:2289
+#, no-wrap
+msgid ""
+"~~~\n"
+"pub mod farm {\n"
+"# pub type Chicken = int;\n"
+"# type Cow = int;\n"
+"# struct Human(int);\n"
+"# impl Human { fn rest(&self) { } }\n"
+"# pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }\n"
+"    pub struct Farm {\n"
+"        priv chickens: ~[Chicken],\n"
+"        priv cows: ~[Cow],\n"
+"        farmer: Human\n"
+"    }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2295
+#, no-wrap
+msgid ""
+"    impl Farm {\n"
+"        fn feed_chickens(&self) { ... }\n"
+"        fn feed_cows(&self) { ... }\n"
+"        pub fn add_chicken(&self, c: Chicken) { ... }\n"
+"    }\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2301
+#, no-wrap
+msgid ""
+"    pub fn feed_animals(farm: &Farm) {\n"
+"        farm.feed_chickens();\n"
+"        farm.feed_cows();\n"
+"    }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2311
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"     let f = make_me_a_farm();\n"
+"     f.add_chicken(make_me_a_chicken());\n"
+"     farm::feed_animals(&f);\n"
+"     f.farmer.rest();\n"
+"}\n"
+"# fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }\n"
+"# fn make_me_a_chicken() -> farm::Chicken { 0 }\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2313
+msgid "## Crates"
+msgstr "## クレート"
+
+#. type: Plain text
+#: doc/tutorial.md:2317
+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 "
+"executable."
+msgstr ""
+"Rust の独立コンパイルの単位はクレートです。rustc は1度に1つのクレートをコンパ"
+"イルし、ライブラリか実行可能ファイルを生成します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2322
+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 "
+"shared library, or without, provided that your file contains a `fn main` "
+"somewhere, to create an executable."
+msgstr ""
+"単一の `.rs` ファイルをコンパイルする場合、1つのファイルがクレート全体として"
+"振る舞います。`--lib` コンパイラスイッチを与えてコンパイルすることで、共有ラ"
+"イブラリを生成することができます。コンパイラスイッチを与えず、 `fn main` が"
+"ファイルのどこかに含まれていれば、実行可能ファイルを生成することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2327
+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 "
+"crate file extension distinguishes source files that represent crates from "
+"those that do not, but otherwise source files and crate files are identical."
+msgstr ""
+"大きなクレートは普通複数のファイルから構成され、慣習的に、 `.rc` という拡張子"
+"をもつ、 **クレートファイル** と呼ばれるファイルからコンパイルされます。ク"
+"レートファイルの拡張子はクレートを表すソースファイルを他のものと区別するため"
+"だけのもので、それ以外の店でクレートファイルとソースファイルに違いはありませ"
+"ん。"
+
+#. type: Plain text
+#: doc/tutorial.md:2336
+msgid ""
+"A typical crate file declares attributes associated with the crate that may "
+"affect how the compiler processes the source.  Crate attributes specify "
+"metadata used for locating and linking crates, the type of crate (library or "
+"executable), and control warning and error behavior, among other things.  "
+"Crate files additionally declare the external crates they depend on as well "
+"as any modules loaded from other files."
+msgstr ""
+"典型的なクレートファイルでは、コンパイラのソースコード処理法に影響を与える、"
+"クレートに紐付けられた属性を宣言します。クレートの属性は、クレートの配置やリ"
+"ンクに使われたり、クレートの種類 (ライブラリか実行ファイルか) を指定したり、"
+"警告やエラーの挙動を制御したりするためのメタデータを指定します。クレートファ"
+"イルは、クレートが依存する外部のクレートや、他のファイルから読み込むモジュー"
+"ルについても宣言します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2340
+msgid ""
+"~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers "
+"= \"2.5\", author = \"mjh\")];"
+msgstr ""
+"~~~~ { .xfail-test }\n"
+"// クレートのリンケージに関するメタデータ\n"
+"#[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")];"
+
+#. type: Plain text
+#: doc/tutorial.md:2343
+msgid "// Make a library (\"bin\" is the default)  #[crate_type = \"lib\"];"
+msgstr ""
+"// ライブラリを作成する (\"bin\" がデフォルト値)\n"
+"#[crate_type = \"lib\"];"
+
+#. type: Plain text
+#: doc/tutorial.md:2346
+msgid "// Turn on a warning #[warn(non_camel_case_types)]"
+msgstr ""
+"// 警告を有効にする\n"
+"#[warn(non_camel_case_types)]"
+
+#. type: Plain text
+#: doc/tutorial.md:2349
+msgid "// Link to the standard library extern mod std;"
+msgstr ""
+"// 標準ライブラリをリンクする\n"
+"extern mod std;"
+
+#. type: Plain text
+#: doc/tutorial.md:2354
+msgid "// Load some modules from other files mod cow; mod chicken; mod horse;"
+msgstr ""
+"// 他のファイルからいくつかのモジュールを読み込む\n"
+"mod cow;\n"
+"mod chicken;\n"
+"mod horse;"
+
+#. type: Plain text
+#: doc/tutorial.md:2359
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    ...\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2366
+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, "
+"compile them all together, and, based on the presence of the `crate_type = "
+"\"lib\"` attribute, output a shared library or an executable. (If the line "
+"`#[crate_type = \"lib\"];` was omitted, `rustc` would create an executable.)"
+msgstr ""
+"このファイルをコンパイルすると、 `rustc` は `.rc` ファイルと同じディレクトリ"
+"の `cow.rs` と `chicken.rs`、 `horse.rs` を探し、すべてのファイルを同時にコン"
+"パイルし、`craete_type = \"lib\"` という属性の有無に応じて、共有ライブラリか"
+"実行可能ファイルを出力します。(`#[crate_type = \"lib\"];` の行が取り除かれば"
+"場合、 `rustc` は実行可能ファイルを生成します。)"
+
+#. type: Plain text
+#: doc/tutorial.md:2370
+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 ""
+"`#[link(...)]` 属性は、モジュールに関するメタ情報を提供し、この情報により他の"
+"クレートは正しいモジュールをロードすることができます。あとで詳しく述べます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2373
+msgid ""
+"To have a nested directory structure for your source files, you can nest "
+"mods:"
+msgstr ""
+"ソースファイルをネストしたディレクトリに配置する場合、`mod` をネストさせま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:2380
+#, no-wrap
+msgid ""
+"~~~~ {.ignore}\n"
+"mod poultry {\n"
+"    mod chicken;\n"
+"    mod turkey;\n"
+"}\n"
+"~~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2385
+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 "
+"can also provide a `poultry.rs` to add content to the `poultry` module "
+"itself."
+msgstr ""
+"コンパイラは `poultry/chicken.rs` と `poultry/turkey.rs` を読み込み、ファイル"
+"の内容を `poultry::chicken` と `poultry::turkey` としてエクスポートします。"
+"`poultry.rs` を作成することで、`poultry` モジュールの内容を追加することも可能"
+"です。"
+
+#. type: Plain text
+#: doc/tutorial.md:2387
+msgid "## Using other crates"
+msgstr "## 他のクレートの利用"
+
+#. type: Plain text
+#: doc/tutorial.md:2395
+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 "
+"top of a crate file or at the top of modules. It will cause the compiler to "
+"look in the library search path (which you can extend with the `-L` switch) "
+"for a compiled Rust library with the right name, then add a module with that "
+"crate's name into the local scope."
+msgstr ""
+"`extern mod` ディレクティブを使うと、あるクレートの中から、(ライブラリにコン"
+"パイルされている) 別のクレートを使用することができます。`extern mod` はク"
+"レートファイルの先頭かモジュールの先頭に記述することができます。コンパイラ"
+"は、対応する名前の Rust ライブラリをライブラリの検索パス (`-L` スイッチにより"
+"追加可能) から検索し、クレートと同じ名前のモジュールをローカルスコープに追加"
+"します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2397
+msgid "For example, `extern mod std` links the [standard library]."
+msgstr ""
+"例えば、 `extern mod std` は [標準ライブラリ][standard library] をリンクしま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:2399
+msgid "[standard library]: std/index.html"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2406
+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 "
+"in the `link` attribute of the crate file. The front-end will only select "
+"this crate for use if the actual pairs match the declared attributes. You "
+"can provide a `name` value to override the name used to search for the crate."
+msgstr ""
+"`extern mod` の後にカンマで区切られた名前と値のペアが記述された場合、コンパイ"
+"ラのフロントエンドはクレートファイルの `link` 属性によって指定された属性と比"
+"較します。フロントエンドは宣言された属性とペアが一致するクレートだけを選択"
+"し、利用します。`name` の値を設定することで、クレートの検索に使う名前を上書き"
+"することができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2408
+msgid "Our example crate declared this set of `link` attributes:"
+msgstr ""
+"先ほどのクレートの例では、 `link` 属性は以下のように宣言されていました。"
+
+#. type: Plain text
+#: doc/tutorial.md:2412
+msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~"
+msgstr ""
+"~~~~\n"
+"#[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")];\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2414
+msgid "Which you can then link with any (or all) of the following:"
+msgstr ""
+"以下のいずれか (またはすべて) の方法でクレートをリンクすることができます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2420
+msgid ""
+"~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", "
+"vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = "
+"\"mjh\"); ~~~~"
+msgstr ""
+"~~~~ {.xfail-test}\n"
+"extern mod farm;\n"
+"extern mod my_farm (name = \"farm\", vers = \"2.5\");\n"
+"extern mod my_auxiliary_farm (name = \"farm\", author = \"mjh\");\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2423
+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:2425
+msgid "## A minimal example"
+msgstr "## 最小限の例"
+
+#. type: Plain text
+#: doc/tutorial.md:2428
+msgid ""
+"Now for something that you can actually compile yourself, we have these two "
+"files:"
+msgstr ""
+"あなた自身で実際にコンパイルが行える例として、以下の2つのファイルを例示しま"
+"す。"
+
+#. type: Plain text
+#: doc/tutorial.md:2434
+msgid ""
+"~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() "
+"-> &str { \"world\" } ~~~~"
+msgstr ""
+"~~~~\n"
+"// world.rs\n"
+"#[link(name = \"world\", vers = \"1.0\")];\n"
+"pub fn explore() -> &str { \"world\" }\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2440
+msgid ""
+"~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello "
+"\" + world::explore()); } ~~~~"
+msgstr ""
+"~~~~ {.xfail-test}\n"
+"// main.rs\n"
+"extern mod world;\n"
+"fn main() { println(~\"hello \" + world::explore()); }\n"
+"~~~~"
+
+#. type: Plain text
+#: doc/tutorial.md:2442
+msgid "Now compile and run like this (adjust to your platform if necessary):"
+msgstr ""
+"以下のようにコンパイルし、実行します (必要であれば、お使いのプラットフォーム"
+"に合わせて修正してください。)"
+
+#. type: Plain text
+#: doc/tutorial.md:2449
+#, no-wrap
+msgid ""
+"~~~~ {.notrust}\n"
+"> rustc --lib world.rs  # compiles libworld-94839cbfe144198-1.0.so\n"
+"> rustc main.rs -L .    # compiles main\n"
+"> ./main\n"
+"\"hello world\"\n"
+"~~~~\n"
+msgstr ""
+"~~~~ {.notrust}\n"
+"> rustc --lib world.rs  # libworld-94839cbfe144198-1.0.so が生成される\n"
+"> rustc main.rs -L .    # main が生成される\n"
+"> ./main\n"
+"\"hello world\"\n"
+"~~~~\n"
+
+#. type: Plain text
+#: doc/tutorial.md:2454
+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 "
+"Rust's library versioning scheme. The alphanumerics are a hash representing "
+"the crate metadata."
+msgstr ""
+"生成されたライブラリのファイル名には、バージョン番号だけでなく謎めいた英数字"
+"が含まれていることに注意してください。これらは両方共 Rust のバージョン管理ス"
+"キームの一員です。英数字は、クレートのメタデータを表すハッシュ値です。"
+
+#. type: Plain text
+#: doc/tutorial.md:2456
+msgid "## The standard library"
+msgstr "## 標準ライブラリ"
+
+#. type: Plain text
+#: doc/tutorial.md:2461
+msgid ""
+"The Rust standard library provides runtime features required by the "
+"language, including the task scheduler and memory allocators, as well as "
+"library support for Rust built-in types, platform abstractions, and other "
+"commonly used features."
+msgstr ""
+"Rust の標準ライブラリは、タスクスケジューラやメモリアロケータを含む、言語自体"
+"が必要とするランタイム機能を提供するだけでなく、Rust の組み込み型や、プラット"
+"フォームの抽象化、その他一般的によく利用される機能ををサポートするライブラリ"
+"を含んでいます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2472
+msgid ""
+"[`std`] includes modules corresponding to each of the integer types, each of "
+"the floating point types, the [`bool`] type, [tuples], [characters], "
+"[strings], [vectors], [managed boxes], [owned boxes], and unsafe and "
+"borrowed [pointers].  Additionally, `std` provides some pervasive types "
+"([`option`] and [`result`]), [task] creation and [communication] primitives, "
+"platform abstractions ([`os`] and [`path`]), basic I/O abstractions "
+"([`io`]), [containers] like [`hashmap`], common traits ([`kinds`], [`ops`], "
+"[`cmp`], [`num`], [`to_str`], [`clone`]), and complete bindings to the C "
+"standard library ([`libc`])."
+msgstr ""
+"[`std`] は整数型や浮動小数点型、[`bool`] 型、[タプル][tuples]、[文字]"
+"[characters]、[文字列][strings]、[ベクタ][vectors]、[マネージドボックス]"
+"[managed boxes]、[所有ボックス][owned boxes]、unsafe または借用 [ポインタ]"
+"[pointers] に対応するモジュールを含んでいます。さらに、 `std` は、いくつかの"
+"よく使われる型 ([`option`] と [`result`])や、 [タスク][task] 生成と[通信]"
+"[communication] のためのプリミティブ、プラットフォームの抽象化 ([`os`] と "
+"[`path`])、基本的な I/O の抽象化 ([`io`]), [`hashmap`] などの [コンテナ]"
+"[containers]、共通的に使われるトレイト ([`kinds`], [`ops`], [`cmp`], "
+"[`num`], [`to_str`], [`clone`])、C 標準ライブラリ ([`libc`]) への完全なバイン"
+"ディングを提供します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2474
+msgid "### Standard Library injection and the Rust prelude"
+msgstr "### 標準ライブラリの注入と Rust の prelude"
+
+#. type: Plain text
+#: doc/tutorial.md:2477
+msgid ""
+"`std` is imported at the topmost level of every crate by default, as if the "
+"first line of each crate was"
+msgstr ""
+"`std` は、すべてのクレートの先頭以下の行か書かれているかのように、デフォルト"
+"でクレートの最上位のレベルにインポートされます。"
+
+#. type: Plain text
+#: doc/tutorial.md:2479
+#, no-wrap
+msgid "    extern mod std;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2483
+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`, "
+"etc."
+msgstr ""
+"これは、 std の内容には `std::` というパスプレフィックスを付けることで、任意"
+"のコンテキストから `use std::vec`. `use std::task::spawn` のようにアクセスで"
+"きることを意味します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2488
+msgid ""
+"Additionally, `std` contains a `prelude` module that reexports many of the "
+"most common standard modules, types and traits. The contents of the prelude "
+"are imported into every *module* by default.  Implicitly, all modules behave "
+"as if they contained the following prologue:"
+msgstr ""
+"さらに、 `std` は `prelude` という、最も共通的なモジュールや型、トレイトを再"
+"エクスポートするモジュールを含んでいます。prelude の内容は、デフォルトですべ"
+"ての **モジュール** にインポートされます。すべてのモジュールは、以下の文言を"
+"モジュール先頭に暗黙的に含んでいるように動作します。"
+
+#. type: Plain text
+#: doc/tutorial.md:2490
+#, no-wrap
+msgid "    use std::prelude::*;\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial.md:2516
+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 "
+"[managed boxes]: std/managed.html [owned boxes]: std/owned.html [pointers]: "
+"std/ptr.html [`option`]: std/option.html [`result`]: std/result.html [task]: "
+"std/task.html [communication]: std/comm.html [`os`]: std/os.html [`path`]: "
+"std/path.html [`io`]: std/io.html [containers]: std/container.html "
+"[`hashmap`]: std/hashmap.html [`kinds`]: std/kinds.html [`ops`]: std/ops."
+"html [`cmp`]: std/cmp.html [`num`]: std/num.html [`to_str`]: std/to_str.html "
+"[`clone`]: std/clone.html [`libc`]: std/libc.html"
+msgstr ""
+"[`std`]: std/index.html\n"
+"[`bool`]: std/bool.html\n"
+"[tuples]: std/tuple.html\n"
+"[characters]: std/char.html\n"
+"[strings]: std/str.html\n"
+"[vectors]: std/vec.html\n"
+"[managed boxes]: std/managed.html\n"
+"[owned boxes]: std/owned.html\n"
+"[pointers]: std/ptr.html\n"
+"[`option`]: std/option.html\n"
+"[`result`]: std/result.html\n"
+"[task]: std/task.html\n"
+"[communication]: std/comm.html\n"
+"[`os`]: std/os.html\n"
+"[`path`]: std/path.html\n"
+"[`io`]: std/io.html\n"
+"[containers]: std/container.html\n"
+"[`hashmap`]: std/hashmap.html\n"
+"[`kinds`]: std/kinds.html\n"
+"[`ops`]: std/ops.html\n"
+"[`cmp`]: std/cmp.html\n"
+"[`num`]: std/num.html\n"
+"[`to_str`]: std/to_str.html\n"
+"[`clone`]: std/clone.html\n"
+"[`libc`]: std/libc.html"
+
+#. type: Plain text
+#: doc/tutorial.md:2518
+msgid "# What next?"
+msgstr "# 次のステップは?"
+
+#. type: Plain text
+#: doc/tutorial.md:2521
+msgid ""
+"Now that you know the essentials, check out any of the additional tutorials "
+"on individual topics."
+msgstr ""
+"Rust の本質的な部分に関する説明は以上です。個々のトピックにおける追加のチュー"
+"トリアルもチェックしてみてください。"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:2527
+msgid "[Borrowed pointers][borrow]"
+msgstr "[借用ポインタ][borrow]"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:2527
+msgid "[Tasks and communication][tasks]"
+msgstr "[タスクと通信][tasks]"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:2527
+msgid "[Macros][macros]"
+msgstr "[マクロ][macros]"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:2527
+msgid "[The foreign function interface][ffi]"
+msgstr "[他言語間インターフェース (foreign function inferface)][ffi]"
+
+#. type: Bullet: '* '
+#: doc/tutorial.md:2527
+msgid "[Containers and iterators](tutorial-container.html)"
+msgstr "[コンテナとイテレータ](tutorial-container.html)"
+
+#. type: Plain text
+#: doc/tutorial.md:2529
+msgid "There is further documentation on the [wiki]."
+msgstr "[wiki] にもドキュメントがあります。"
+
+#. type: Plain text
+#: doc/tutorial.md:2534
+msgid ""
+"[borrow]: tutorial-borrowed-ptr.html [tasks]: tutorial-tasks.html [macros]: "
+"tutorial-macros.html [ffi]: tutorial-ffi.html"
+msgstr ""
+"[borrow]: tutorial-borrowed-ptr.html\n"
+"[tasks]: tutorial-tasks.html\n"
+"[macros]: tutorial-macros.html\n"
+"[ffi]: tutorial-ffi.html"
+
+#. type: Plain text
+#: doc/tutorial.md:2536
+msgid "[wiki]: https://github.com/mozilla/rust/wiki/Docs"
+msgstr ""
index 20ebb88c72434b053427a7d71d447ba995a6cc7a..9bc3fb1d16e2abd04888315bb56e21a2daa85f5f 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:47+0900\n"
+"POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -160,7 +160,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:74 doc/rust.md:417 doc/rust.md:487
+#: doc/rust.md:74 doc/rust.md:416 doc/rust.md:486
 msgid "~~~~~~~~"
 msgstr ""
 
@@ -454,27 +454,27 @@ msgid "The keywords are the following strings:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:223
+#: doc/rust.md:222
 msgid ""
-"~~~~~~~~ {.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 ~~~~~~~~"
+"~~~~~~~~ {.keyword} as break 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
-#: doc/rust.md:226
+#: doc/rust.md:225
 msgid ""
 "Each of these keywords has special meaning in its grammar, and all of them "
 "are excluded from the `ident` rule."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:228
+#: doc/rust.md:227
 msgid "### Literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:234
+#: doc/rust.md:233
 msgid ""
 "A literal is an expression consisting of a single token, rather than a "
 "sequence of tokens, that immediately and directly denotes the value it "
@@ -484,25 +484,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:238
+#: doc/rust.md:237
 msgid ""
 "~~~~~~~~ {.ebnf .gram} literal : string_lit | char_lit | num_lit ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:240
+#: doc/rust.md:239
 msgid "#### Character and string literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:244
+#: doc/rust.md:243
 msgid ""
 "~~~~~~~~ {.ebnf .gram} char_lit : '\\x27' char_body '\\x27' ; string_lit : "
 "'\"' string_body * '\"' ;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:247
+#: doc/rust.md:246
 #, no-wrap
 msgid ""
 "char_body : non_single_quote\n"
@@ -510,7 +510,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:250
+#: doc/rust.md:249
 #, no-wrap
 msgid ""
 "string_body : non_double_quote\n"
@@ -518,7 +518,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:256
+#: doc/rust.md:255
 #, no-wrap
 msgid ""
 "common_escape : '\\x5c'\n"
@@ -529,7 +529,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:264
+#: doc/rust.md:263
 #, no-wrap
 msgid ""
 "hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'\n"
@@ -542,7 +542,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:268
+#: doc/rust.md:267
 msgid ""
 "A _character literal_ is a single Unicode character enclosed within two `U"
 "+0027` (single-quote) characters, with the exception of `U+0027` itself, "
@@ -550,7 +550,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:272
+#: doc/rust.md:271
 msgid ""
 "A _string literal_ is a sequence of any Unicode characters enclosed within "
 "two `U+0022` (double-quote) characters, with the exception of `U+0022` "
@@ -558,7 +558,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:276
+#: doc/rust.md:275
 msgid ""
 "Some additional _escapes_ are available in either character or string "
 "literals. An escape starts with a `U+005C` (`\\`) and continues with one of "
@@ -566,7 +566,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:291
+#: doc/rust.md:290
 msgid ""
 "An _8-bit codepoint escape_ escape starts with `U+0078` (`x`) and is "
 "followed by exactly two _hex digits_. It denotes the Unicode codepoint equal "
@@ -574,7 +574,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:291
+#: doc/rust.md:290
 msgid ""
 "A _16-bit codepoint escape_ starts with `U+0075` (`u`) and is followed by "
 "exactly four _hex digits_. It denotes the Unicode codepoint equal to the "
@@ -582,7 +582,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:291
+#: doc/rust.md:290
 msgid ""
 "A _32-bit codepoint escape_ starts with `U+0055` (`U`) and is followed by "
 "exactly eight _hex digits_. It denotes the Unicode codepoint equal to the "
@@ -590,7 +590,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:291
+#: doc/rust.md:290
 msgid ""
 "A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072` "
 "(`r`), or `U+0074` (`t`), denoting the unicode values `U+000A` (LF), `U"
@@ -598,24 +598,24 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:291
+#: doc/rust.md:290
 msgid ""
 "The _backslash escape_ is the character U+005C (`\\`) which must be escaped "
 "in order to denote *itself*."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:293
+#: doc/rust.md:292
 msgid "#### Number literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:295 doc/rust.md:407 doc/rust.md:474
+#: doc/rust.md:294 doc/rust.md:406 doc/rust.md:473
 msgid "~~~~~~~~ {.ebnf .gram}"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:300
+#: doc/rust.md:299
 #, no-wrap
 msgid ""
 "num_lit : nonzero_dec [ dec_digit | '_' ] * num_suffix ?\n"
@@ -625,12 +625,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:302
+#: doc/rust.md:301
 msgid "num_suffix : int_suffix | float_suffix ;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:306
+#: doc/rust.md:305
 #, no-wrap
 msgid ""
 "int_suffix : 'u' int_suffix_size ?\n"
@@ -639,7 +639,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:312
+#: doc/rust.md:311
 msgid ""
 "float_suffix : [ exponent | '.' dec_lit exponent ? ] ? float_suffix_ty ? ; "
 "float_suffix_ty : 'f' [ '3' '2' | '6' '4' ] ; exponent : ['E' | 'e'] ['-' | "
@@ -647,7 +647,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:316
+#: doc/rust.md:315
 msgid ""
 "A _number literal_ is either an _integer literal_ or a _floating-point "
 "literal_. The grammar for recognizing the two kinds of literals is mixed, as "
@@ -655,38 +655,38 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:318
+#: doc/rust.md:317
 msgid "##### Integer literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:320
+#: doc/rust.md:319
 msgid "An _integer literal_ has one of three forms:"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:327
+#: doc/rust.md:326
 msgid ""
 "A _decimal literal_ starts with a *decimal digit* and continues with any "
 "mixture of *decimal digits* and _underscores_."
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:327
+#: doc/rust.md:326
 msgid ""
 "A _hex literal_ starts with the character sequence `U+0030` `U+0078` (`0x`) "
 "and continues as any mixture hex digits and underscores."
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:327
+#: doc/rust.md:326
 msgid ""
 "A _binary literal_ starts with the character sequence `U+0030` `U+0062` "
 "(`0b`) and continues as any mixture binary digits and underscores."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:331
+#: doc/rust.md:330
 msgid ""
 "An integer literal may be followed (immediately, without any spaces) by an "
 "_integer suffix_, which changes the type of the literal. There are two kinds "
@@ -694,13 +694,13 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:337
+#: doc/rust.md:336
 msgid ""
 "The `i` and `u` suffixes give the literal type `int` or `uint`, respectively."
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:337
+#: doc/rust.md:336
 msgid ""
 "Each of the signed and unsigned machine types `u8`, `i8`, `u16`, `i16`, "
 "`u32`, `i32`, `u64` and `i64` give the literal the corresponding machine "
@@ -708,7 +708,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:344
+#: doc/rust.md:343
 msgid ""
 "The type of an _unsuffixed_ integer literal is determined by type "
 "inference.  If a integer type can be _uniquely_ determined from the "
@@ -719,12 +719,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:346
+#: doc/rust.md:345
 msgid "Examples of integer literals of various forms:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:351
+#: doc/rust.md:350
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -734,7 +734,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:357
+#: doc/rust.md:356
 #, no-wrap
 msgid ""
 "123u;                              // type uint\n"
@@ -745,29 +745,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:359
+#: doc/rust.md:358
 msgid "##### Floating-point literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:361
+#: doc/rust.md:360
 msgid "A _floating-point literal_ has one of two forms:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:366
+#: doc/rust.md:365
 msgid ""
 "Two _decimal literals_ separated by a period character `U+002E` (`.`), with "
 "an optional _exponent_ trailing after the second decimal literal."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:366
+#: doc/rust.md:365
 msgid "A single _decimal literal_ followed by an _exponent_."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:373
+#: doc/rust.md:372
 msgid ""
 "By default, a floating-point literal is of type `float`. A floating-point "
 "literal may be followed (immediately, without any spaces) by a _floating-"
@@ -777,12 +777,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:375
+#: doc/rust.md:374
 msgid "Examples of floating-point literals of various forms:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:383
+#: doc/rust.md:382
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -795,12 +795,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:385
+#: doc/rust.md:384
 msgid "##### Unit and boolean literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:388
+#: doc/rust.md:387
 msgid ""
 "The _unit value_, the only value of the type that has the same name, is "
 "written as `()`.  The two values of the boolean type are written `true` and "
@@ -808,12 +808,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:390
+#: doc/rust.md:389
 msgid "### Symbols"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:396
+#: doc/rust.md:395
 #, no-wrap
 msgid ""
 "~~~~~~~~ {.ebnf .gram}\n"
@@ -824,7 +824,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:402
+#: doc/rust.md:401
 msgid ""
 "Symbols are a general class of printable [token](#tokens) that play "
 "structural roles in a variety of grammar productions. They are catalogued "
@@ -835,12 +835,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:405
+#: doc/rust.md:404
 msgid "## Paths"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:411
+#: doc/rust.md:410
 #, no-wrap
 msgid ""
 "expr_path : ident [ \"::\" expr_path_tail ] + ;\n"
@@ -849,7 +849,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:415
+#: doc/rust.md:414
 #, no-wrap
 msgid ""
 "type_path : ident [ type_path_tail ] + ;\n"
@@ -858,7 +858,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:422
+#: doc/rust.md:421
 msgid ""
 "A _path_ is a sequence of one or more path components _logically_ separated "
 "by a namespace qualifier (`::`). If a path consists of only one component, "
@@ -867,7 +867,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:426
+#: doc/rust.md:425
 msgid ""
 "Every item has a _canonical path_ within its crate, but the path naming an "
 "item is only meaningful within a given crate. There is no global namespace "
@@ -876,17 +876,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:428
+#: doc/rust.md:427
 msgid "Two examples of simple paths consisting of only identifier components:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:433
+#: doc/rust.md:432
 msgid "~~~~{.ignore} x; x::y::z; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:440
+#: doc/rust.md:439
 msgid ""
 "Path components are usually [identifiers](#identifiers), but the trailing "
 "component of a path may be an angle-bracket-enclosed list of type arguments. "
@@ -897,18 +897,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:442
+#: doc/rust.md:441
 msgid "Two examples of paths with type arguments:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:451
+#: doc/rust.md:450
 #, no-wrap
 msgid ""
 "~~~~\n"
 "# use std::hashmap::HashMap;\n"
 "# fn f() {\n"
-"# fn id<T:Copy>(t: T) -> T { t }\n"
+"# fn id<T>(t: T) -> T { t }\n"
 "type t = HashMap<int,~str>;  // Type arguments used in a type expression\n"
 "let x = id::<int>(10);         // Type arguments used in a call expression\n"
 "# }\n"
@@ -916,12 +916,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:453
+#: doc/rust.md:452
 msgid "# Syntax extensions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:458
+#: doc/rust.md:457
 msgid ""
 "A number of minor features of Rust are not central enough to have their own "
 "syntax, and yet are not implementable as functions. Instead, they are given "
@@ -930,60 +930,60 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`fmt!` : format data into a string"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`env!` : look up an environment variable's value at compile time"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`stringify!` : pretty-print the Rust expression given as an argument"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`proto!` : define a protocol for inter-task communication"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`include!` : include the Rust expression in the given file"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`include_str!` : include the contents of the given file as a string"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid ""
 "`include_bin!` : include the contents of the given file as a binary blob"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:467
+#: doc/rust.md:466
 msgid "`error!`, `warn!`, `info!`, `debug!` : provide diagnostic information."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:470
+#: doc/rust.md:469
 msgid ""
 "All of the above extensions, with the exception of `proto!`, are expressions "
 "with values. `proto!` is an item, defining a new name."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:472
+#: doc/rust.md:471
 msgid "## Macros"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:485
+#: doc/rust.md:484
 #, no-wrap
 msgid ""
 "expr_macro_rules : \"macro_rules\" '!' ident '(' macro_rule * ')'\n"
@@ -999,7 +999,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:491
+#: doc/rust.md:490
 msgid ""
 "User-defined syntax extensions are called \"macros\", and the `macro_rules` "
 "syntax extension defines them.  Currently, user-defined macros can expand to "
@@ -1007,14 +1007,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:494
+#: doc/rust.md:493
 msgid ""
 "(A `sep_token` is any token other than `*` and `+`.  A `non_special_token` "
 "is any token other than a delimiter or `$`.)"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:500
+#: doc/rust.md:499
 msgid ""
 "The macro expander looks up macro invocations by name, and tries each macro "
 "rule in turn.  It transcribes the first successful match.  Matching and "
@@ -1023,12 +1023,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:502
+#: doc/rust.md:501
 msgid "### Macro By Example"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:505
+#: doc/rust.md:504
 msgid ""
 "The macro expander matches and transcribes every token that does not begin "
 "with a `$` literally, including delimiters.  For parsing reasons, delimiters "
@@ -1036,7 +1036,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:511
+#: doc/rust.md:510
 msgid ""
 "In the matcher, `$` _name_ `:` _designator_ matches the nonterminal in the "
 "Rust syntax named by _designator_. Valid designators are `item`, `block`, "
@@ -1047,7 +1047,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:520
+#: doc/rust.md:519
 msgid ""
 "In both the matcher and transcriber, the Kleene star-like operator indicates "
 "repetition.  The Kleene star operator consists of `$` and parens, optionally "
@@ -1060,7 +1060,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:526
+#: doc/rust.md:525
 msgid ""
 "The rules for transcription of these repetitions are called \"Macro By "
 "Example\".  Essentially, one \"layer\" of repetition is discharged at a "
@@ -1070,7 +1070,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:534
+#: doc/rust.md:533
 msgid ""
 "When Macro By Example encounters a repetition, it examines all of the `$` "
 "_name_ s that occur in its body. At the \"current layer\", they all must "
@@ -1081,24 +1081,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:536
+#: doc/rust.md:535
 msgid "Nested repetitions are allowed."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:538
+#: doc/rust.md:537
 msgid "### Parsing limitations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:541
+#: doc/rust.md:540
 msgid ""
 "The parser used by the macro system is reasonably powerful, but the parsing "
 "of Rust syntax is restricted in two ways:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:547
+#: doc/rust.md:546
 #, no-wrap
 msgid ""
 "1. The parser will always parse as much as possible. If it attempts to match\n"
@@ -1109,40 +1109,40 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:550
+#: doc/rust.md:549
 msgid "## Syntax extensions useful for the macro author"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:555
+#: doc/rust.md:554
 msgid "`log_syntax!` : print out the arguments at compile time"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:555
+#: doc/rust.md:554
 msgid ""
 "`trace_macros!` : supply `true` or `false` to enable or disable macro "
 "expansion logging"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:555
+#: doc/rust.md:554
 msgid "`stringify!` : turn the identifier argument into a string literal"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:555
+#: doc/rust.md:554
 msgid ""
 "`concat_idents!` : create a new identifier by concatenating the arguments"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:557
+#: doc/rust.md:556
 msgid "# Crates and source files"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:564
+#: doc/rust.md:563
 msgid ""
 "Rust is a *compiled* language.  Its semantics obey a *phase distinction* "
 "between compile-time and run-time.  Those semantic rules that have a *static "
@@ -1155,7 +1155,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:570
+#: doc/rust.md:569
 msgid ""
 "The compilation model centres on artifacts called _crates_.  Each "
 "compilation processes a single crate in source form, and if successful, "
@@ -1166,7 +1166,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:574
+#: doc/rust.md:573
 msgid ""
 "A _crate_ is a unit of compilation and linking, as well as versioning, "
 "distribution and runtime loading.  A crate contains a _tree_ of nested "
@@ -1177,17 +1177,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:579
+#: doc/rust.md:577
 msgid ""
 "The Rust compiler is always invoked with a single source file as input, and "
 "always produces a single output crate.  The processing of that source file "
-"may result in other source files being loaded as modules.  Source files "
-"typically have the extension `.rs` but, by convention, source files that "
-"represent crates have the extension `.rc`, called *crate files*."
+"may result in other source files being loaded as modules.  Source files have "
+"the extension `.rs`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:584
+#: doc/rust.md:582
 msgid ""
 "A Rust source file describes a module, the name and location of which -- in "
 "the module tree of the current crate -- are defined from outside the source "
@@ -1196,7 +1195,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:589
+#: doc/rust.md:587
 msgid ""
 "Each source file contains a sequence of zero or more `item` definitions, and "
 "may optionally begin with any number of `attributes` that apply to the "
@@ -1205,7 +1204,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:595
+#: doc/rust.md:593
 #, no-wrap
 msgid ""
 "~~~~~~~~\n"
@@ -1216,24 +1215,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:600
+#: doc/rust.md:598
 msgid ""
 "// Additional metadata attributes #[ desc = \"Project X\" ]; #[ license = "
 "\"BSD\" ]; #[ author = \"Jane Doe\" ];"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:603
+#: doc/rust.md:601
 msgid "// Specify the output type #[ crate_type = \"lib\" ];"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:607
+#: doc/rust.md:605
 msgid "// Turn on a warning #[ warn(non_camel_case_types) ]; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:610
+#: doc/rust.md:608
 msgid ""
 "A crate that contains a `main` function can be compiled to an executable.  "
 "If a `main` function is present, its return type must be [`unit`](#primitive-"
@@ -1241,24 +1240,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:613
+#: doc/rust.md:611
 msgid "# Items and attributes"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:616
+#: doc/rust.md:614
 msgid ""
 "Crates contain [items](#items), each of which may have some number of "
 "[attributes](#attributes) attached to it."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:618
+#: doc/rust.md:616
 msgid "## Items"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:623
+#: doc/rust.md:621
 #, no-wrap
 msgid ""
 "~~~~~~~~ {.ebnf .gram}\n"
@@ -1268,7 +1267,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:629
+#: doc/rust.md:627
 msgid ""
 "An _item_ is a component of a crate; some module items can be defined in "
 "crate files, but most are defined in source files. Items are organized "
@@ -1278,59 +1277,59 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:632
+#: doc/rust.md:630
 msgid ""
 "Items are entirely determined at compile-time, generally remain fixed during "
 "execution, and may reside in read-only memory."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:634
+#: doc/rust.md:632
 msgid "There are several kinds of item:"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[modules](#modules)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[functions](#functions)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[type definitions](#type-definitions)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[structures](#structures)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[enumerations](#enumerations)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[static items](#static-items)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[traits](#traits)"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:643
+#: doc/rust.md:641
 msgid "[implementations](#implementations)"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:653
+#: doc/rust.md:651
 msgid ""
 "Some items form an implicit scope for the declaration of sub-items. In other "
 "words, within a function or module, declarations of items can (in many "
@@ -1344,12 +1343,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:655
+#: doc/rust.md:653
 msgid "### Type Parameters"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:664
+#: doc/rust.md:662
 msgid ""
 "All items except modules may be *parameterized* by type. Type parameters are "
 "given as a comma-separated list of identifiers enclosed in angle brackets "
@@ -1365,19 +1364,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:666
+#: doc/rust.md:664
 msgid "### Modules"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:671
+#: doc/rust.md:669
 msgid ""
 "~~~~~~~~ {.ebnf .gram} mod_item : \"mod\" ident ( ';' | '{' mod '}' ); mod : "
 "[ view_item | item ] * ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:676
+#: doc/rust.md:674
 msgid ""
 "A module is a container for zero or more [view items](#view-items) and zero "
 "or more [items](#items). The view items manage the visibility of the items "
@@ -1386,7 +1385,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:680
+#: doc/rust.md:678
 msgid ""
 "A _module item_ is a module, surrounded in braces, named, and prefixed with "
 "the keyword `mod`. A module item introduces a new, named module into the "
@@ -1394,12 +1393,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:682
+#: doc/rust.md:680
 msgid "An example of a module:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:700
+#: doc/rust.md:698
 #, no-wrap
 msgid ""
 "~~~~~~~~\n"
@@ -1422,7 +1421,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:705
+#: doc/rust.md:703
 msgid ""
 "Modules and types share the same namespace.  Declaring a named type that has "
 "the same name as a module in scope is forbidden: that is, a type definition, "
@@ -1431,7 +1430,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:710
+#: doc/rust.md:708
 msgid ""
 "A module without a body is loaded from an external file, by default with the "
 "same name as the module, plus the `.rs` extension.  When a nested submodule "
@@ -1440,12 +1439,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:714
+#: doc/rust.md:712
 msgid "~~~ {.xfail-test} // Load the `vec` module from `vec.rs` mod vec;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:720
+#: doc/rust.md:718
 #, no-wrap
 msgid ""
 "mod task {\n"
@@ -1456,14 +1455,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:723
+#: doc/rust.md:721
 msgid ""
 "The directories and files used for loading external file modules can be "
 "influenced with the `path` attribute."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:732
+#: doc/rust.md:730
 #, no-wrap
 msgid ""
 "~~~ {.xfail-test}\n"
@@ -1477,18 +1476,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:734
+#: doc/rust.md:732
 msgid "#### View items"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:738
+#: doc/rust.md:736
 msgid ""
 "~~~~~~~~ {.ebnf .gram} view_item : extern_mod_decl | use_decl ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:742
+#: doc/rust.md:740
 msgid ""
 "A view item manages the namespace of a module.  View items do not define new "
 "items, but rather, simply change other items' visibility.  There are several "
@@ -1496,30 +1495,30 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: ' * '
-#: doc/rust.md:745
+#: doc/rust.md:743
 msgid "[`extern mod` declarations](#extern-mod-declarations)"
 msgstr ""
 
 #. type: Bullet: ' * '
-#: doc/rust.md:745
+#: doc/rust.md:743
 msgid "[`use` declarations](#use-declarations)"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:747
+#: doc/rust.md:745
 msgid "##### Extern mod declarations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:753
+#: doc/rust.md:751
 msgid ""
 "~~~~~~~~ {.ebnf .gram} extern_mod_decl : \"extern\" \"mod\" ident [ '(' "
-"link_attrs ')' ] ? ; link_attrs : link_attr [ ',' link_attrs ] + ; "
-"link_attr : ident '=' literal ; ~~~~~~~~"
+"link_attrs ')' ] ? [ '=' string_lit ] ? ; link_attrs : link_attr [ ',' "
+"link_attrs ] + ; link_attr : ident '=' literal ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:757
+#: doc/rust.md:755
 msgid ""
 "An _`extern mod` declaration_ specifies a dependency on an external crate.  "
 "The external crate is then bound into the declaring scope as the `ident` "
@@ -1531,45 +1530,64 @@ msgstr ""
 msgid ""
 "The external crate is resolved to a specific `soname` at compile time, and a "
 "runtime linkage requirement to that `soname` is passed to the linker for "
-"loading at runtime. The `soname` is resolved at compile time by scanning the "
-"compiler's library path and matching the `link_attrs` provided in the "
+"loading at runtime.  The `soname` is resolved at compile time by scanning "
+"the compiler's library path and matching the `link_attrs` provided in the "
 "`use_decl` against any `#link` attributes that were declared on the external "
-"crate when it was compiled. If no `link_attrs` are provided, a default "
+"crate when it was compiled.  If no `link_attrs` are provided, a default "
 "`name` attribute is assumed, equal to the `ident` given in the `use_decl`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:767
-msgid "Three examples of `extern mod` declarations:"
+#: doc/rust.md:775
+msgid ""
+"Optionally, an identifier in an `extern mod` declaration may be followed by "
+"an equals sign, then a string literal denoting a relative path on the "
+"filesystem.  This path should exist in one of the directories in the Rust "
+"path, which by default contains the `.rust` subdirectory of the current "
+"directory and each of its parents, as well as any directories in the colon-"
+"separated (or semicolon-separated on Windows)  list of paths that is the "
+"`RUST_PATH` environment variable.  The meaning of `extern mod a = \"b/c/d\";"
+"`, supposing that `/a` is in the RUST_PATH, is that the name `a` should be "
+"taken as a reference to the crate whose absolute location is `/a/b/c/d`."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:777
+msgid "Four examples of `extern mod` declarations:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:770
+#: doc/rust.md:780
 msgid ""
 "~~~~~~~~{.xfail-test} extern mod pcre (uuid = \"54aba0f8-"
 "a7b1-4beb-92f1-4cf625264841\");"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:772
+#: doc/rust.md:782
 msgid ""
 "extern mod extra; // equivalent to: extern mod extra ( name = \"extra\" );"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:775
+#: doc/rust.md:784
 msgid ""
 "extern mod rustextra (name = \"extra\"); // linking to 'extra' under another "
-"name ~~~~~~~~"
+"name"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:777
+#: doc/rust.md:787
+msgid "extern mod complicated_mod = \"some-file/in/the-rust/path\"; ~~~~~~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:789
 msgid "##### Use declarations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:781
+#: doc/rust.md:793
 #, no-wrap
 msgid ""
 "~~~~~~~~ {.ebnf .gram}\n"
@@ -1578,7 +1596,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:786
+#: doc/rust.md:798
 #, no-wrap
 msgid ""
 "path_glob : ident [ \"::\" path_glob ] ?\n"
@@ -1588,7 +1606,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:790
+#: doc/rust.md:802
 msgid ""
 "A _use declaration_ creates one or more local name bindings synonymous with "
 "some other [path](#paths).  Usually a `use` declaration is used to shorten "
@@ -1596,7 +1614,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:794
+#: doc/rust.md:806
 #, no-wrap
 msgid ""
 "*Note*: Unlike in many languages,\n"
@@ -1605,43 +1623,43 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:796
+#: doc/rust.md:808
 msgid "Use declarations support a number of convenient shortcuts:"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:801
+#: doc/rust.md:813
 msgid ""
 "Rebinding the target name as a new local name, using the syntax `use x = p::"
 "q::r;`."
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:801
+#: doc/rust.md:813
 msgid ""
 "Simultaneously binding a list of paths differing only in their final "
 "element, using the glob-like brace syntax `use a::b::{c,d,e,f};`"
 msgstr ""
 
 #. type: Bullet: '  * '
-#: doc/rust.md:801
+#: doc/rust.md:813
 msgid ""
 "Binding all paths matching a given prefix, using the asterisk wildcard "
 "syntax `use a::b::*;`"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:803
+#: doc/rust.md:815
 msgid "An example of `use` declarations:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:807
+#: doc/rust.md:819
 msgid "~~~~ use std::num::sin; use std::option::{Some, None};"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:811
+#: doc/rust.md:823
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -1650,7 +1668,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:816
+#: doc/rust.md:828
 #, no-wrap
 msgid ""
 "    // Equivalent to 'info!(~[std::option::Some(1.0), std::option::None]);'\n"
@@ -1660,7 +1678,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:824
+#: doc/rust.md:836
 msgid ""
 "Like items, `use` declarations are private to the containing module, by "
 "default.  Also like items, a `use` declaration can be public, if qualified "
@@ -1673,7 +1691,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:830
+#: doc/rust.md:842
 #, no-wrap
 msgid ""
 "An example of re-exporting:\n"
@@ -1684,7 +1702,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:837
+#: doc/rust.md:849
 #, no-wrap
 msgid ""
 "    pub mod foo {\n"
@@ -1696,14 +1714,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:839
+#: doc/rust.md:851
 msgid ""
 "In this example, the module `quux` re-exports all of the public names "
 "defined in `foo`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:842
+#: doc/rust.md:854
 msgid ""
 "Also note that the paths contained in `use` items are relative to the crate "
 "root.  So, in the previous example, the `use` refers to `quux::foo::*`, and "
@@ -1711,12 +1729,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:844
+#: doc/rust.md:856
 msgid "### Functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:848
+#: doc/rust.md:860
 msgid ""
 "A _function item_ defines a sequence of [statements](#statements) and an "
 "optional final [expression](#expressions), along with a name and a set of "
@@ -1727,7 +1745,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:853
+#: doc/rust.md:865
 msgid ""
 "A function may also be copied into a first class *value*, in which case the "
 "value has the corresponding [*function type*](#function-types), and can be "
@@ -1736,7 +1754,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:859
+#: doc/rust.md:871
 msgid ""
 "Every control path in a function logically ends with a `return` expression "
 "or a diverging expression. If the outermost block of a function has a value-"
@@ -1746,12 +1764,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:861
+#: doc/rust.md:873
 msgid "An example of a function:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:867
+#: doc/rust.md:879
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1762,24 +1780,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:870
+#: doc/rust.md:882
 msgid ""
 "As with `let` bindings, function arguments are irrefutable patterns, so any "
 "pattern that is valid in a let binding is also valid as an argument."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:874
+#: doc/rust.md:886
 msgid "~~~ fn first((value, _): (int, int)) -> int { value } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:877
+#: doc/rust.md:889
 msgid "#### Generic functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:882
+#: doc/rust.md:894
 msgid ""
 "A _generic function_ allows one or more _parameterized types_ to appear in "
 "its signature. Each type parameter must be explicitly declared, in an angle-"
@@ -1787,7 +1805,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:893
+#: doc/rust.md:905
 #, no-wrap
 msgid ""
 "~~~~ {.xfail-test}\n"
@@ -1803,14 +1821,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:896
+#: doc/rust.md:908
 msgid ""
 "Inside the function signature and body, the name of the type parameter can "
 "be used as a type name."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:902
+#: doc/rust.md:914
 msgid ""
 "When a generic function is referenced, its type is instantiated based on the "
 "context of the reference. For example, calling the `iter` function defined "
@@ -1819,7 +1837,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:907
+#: doc/rust.md:919
 msgid ""
 "The type parameters can also be explicitly supplied in a trailing [path]"
 "(#paths) component after the function name. This might be necessary if there "
@@ -1828,33 +1846,32 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:912
+#: doc/rust.md:923
 msgid ""
 "Since a parameter type is opaque to the generic function, the set of "
 "operations that can be performed on it is limited. Values of parameter type "
-"can always be moved, but they can only be copied when the parameter is given "
-"a [`Copy` bound](#type-kinds)."
+"can only be moved, not copied."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:916
-msgid "~~~~ fn id<T: Copy>(x: T) -> T { x } ~~~~"
+#: doc/rust.md:927
+msgid "~~~~ fn id<T>(x: T) -> T { x } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:920
+#: doc/rust.md:931
 msgid ""
 "Similarly, [trait](#traits) bounds can be specified for type parameters to "
 "allow methods with that trait to be called on values of that type."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:923
+#: doc/rust.md:934
 msgid "#### Unsafe functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:926
+#: doc/rust.md:937
 msgid ""
 "Unsafe functions are those containing unsafe operations that are not "
 "contained in an [`unsafe` block](#unsafe-blocks).  Such a function must be "
@@ -1862,7 +1879,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:929
+#: doc/rust.md:940
 msgid ""
 "Unsafe operations are those that potentially violate the memory-safety "
 "guarantees of Rust's static semantics.  Specifically, the following "
@@ -1870,27 +1887,27 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:933
+#: doc/rust.md:944
 msgid "Dereferencing a [raw pointer](#pointer-types)."
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:933
+#: doc/rust.md:944
 msgid "Casting a [raw pointer](#pointer-types) to a safe pointer type."
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:933
+#: doc/rust.md:944
 msgid "Calling an unsafe function."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:935
+#: doc/rust.md:946
 msgid "##### Unsafe blocks"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:939
+#: doc/rust.md:950
 msgid ""
 "A block of code can also be prefixed with the `unsafe` keyword, to permit a "
 "sequence of unsafe operations in an otherwise-safe function.  This facility "
@@ -1902,19 +1919,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:942
+#: doc/rust.md:953
 msgid "#### Diverging functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:945
+#: doc/rust.md:956
 msgid ""
 "A special kind of function can be declared with a `!` character where the "
 "output slot type would normally be. For example:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:952
+#: doc/rust.md:963
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1926,7 +1943,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:959
+#: doc/rust.md:970
 msgid ""
 "We call such functions \"diverging\" because they never return a value to "
 "the caller. Every control path in a diverging function must end with a `fail!"
@@ -1937,7 +1954,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:965
+#: doc/rust.md:976
 msgid ""
 "It might be necessary to declare a diverging function because as mentioned "
 "previously, the typechecker checks that every control path in a function "
@@ -1947,12 +1964,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:968
+#: doc/rust.md:979
 msgid "~~~~ # fn my_err(s: &str) -> ! { fail!() }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:978
+#: doc/rust.md:989
 #, no-wrap
 msgid ""
 "fn f(i: int) -> int {\n"
@@ -1967,7 +1984,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:986
+#: doc/rust.md:997
 msgid ""
 "This will not compile without the `!` annotation on `my_err`, since the "
 "`else` branch of the conditional in `f` does not return an `int`, as "
@@ -1979,12 +1996,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:989
+#: doc/rust.md:1000
 msgid "#### Extern functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:996
+#: doc/rust.md:1007
 msgid ""
 "Extern functions are part of Rust's foreign function interface, providing "
 "the opposite functionality to [external blocks](#external-blocks).  Whereas "
@@ -1995,37 +2012,37 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1000
+#: doc/rust.md:1011
 msgid "~~~ extern fn new_vec() -> ~[int] { ~[] } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1003
+#: doc/rust.md:1014
 msgid ""
 "Extern functions may not be called from Rust code, but Rust code may take "
 "their value as a raw `u8` pointer."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1008
+#: doc/rust.md:1019
 msgid ""
 "~~~ # extern fn new_vec() -> ~[int] { ~[] } let fptr: *u8 = new_vec; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1012
+#: doc/rust.md:1023
 msgid ""
 "The primary motivation for extern functions is to create callbacks for "
 "foreign functions that expect to receive function pointers."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1014
+#: doc/rust.md:1025
 msgid "### Type definitions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1018
+#: doc/rust.md:1029
 msgid ""
 "A _type definition_ defines a new name for an existing [type](#types). Type "
 "definitions are declared with the keyword `type`. Every value has a single, "
@@ -2033,32 +2050,32 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1024
+#: doc/rust.md:1035
 msgid "Whether the value is composed of sub-values or is indivisible."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1024
+#: doc/rust.md:1035
 msgid "Whether the value represents textual or numerical information."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1024
+#: doc/rust.md:1035
 msgid "Whether the value represents integral or floating-point information."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1024
+#: doc/rust.md:1035
 msgid "The sequence of memory operations required to access the value."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1024
+#: doc/rust.md:1035
 msgid "The [kind](#type-kinds) of the type."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1027
+#: doc/rust.md:1038
 msgid ""
 "For example, the type `(u8, u8)` defines the set of immutable values that "
 "are composite pairs, each containing two unsigned 8-bit integers accessed by "
@@ -2067,45 +2084,45 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1029
+#: doc/rust.md:1040
 msgid "### Structures"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1031
+#: doc/rust.md:1042
 msgid ""
 "A _structure_ is a nominal [structure type](#structure-types) defined with "
 "the keyword `struct`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1033
+#: doc/rust.md:1044
 msgid "An example of a `struct` item and its use:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1039
+#: doc/rust.md:1050
 msgid ""
 "~~~~ struct Point {x: int, y: int} let p = Point {x: 10, y: 11}; let px: int "
 "= p.x; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1042
+#: doc/rust.md:1053
 msgid ""
 "A _tuple structure_ is a nominal [tuple type](#tuple-types), also defined "
 "with the keyword `struct`.  For example:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1048
+#: doc/rust.md:1059
 msgid ""
 "~~~~ struct Point(int, int); let p = Point(10, 11); let px: int = match p "
 "{ Point(x, _) => x }; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1052
+#: doc/rust.md:1063
 msgid ""
 "A _unit-like struct_ is a structure without any fields, defined by leaving "
 "off the list of fields entirely.  Such types will have a single value, just "
@@ -2114,17 +2131,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1057
+#: doc/rust.md:1068
 msgid "~~~~ struct Cookie; let c = [Cookie, Cookie, Cookie, Cookie]; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1059
+#: doc/rust.md:1070
 msgid "### Enumerations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1062
+#: doc/rust.md:1073
 msgid ""
 "An _enumeration_ is a simultaneous definition of a nominal [enumerated type]"
 "(#enumerated-types) as well as a set of *constructors*, that can be used to "
@@ -2132,17 +2149,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1064
+#: doc/rust.md:1075
 msgid "Enumerations are declared with the keyword `enum`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1066
+#: doc/rust.md:1077
 msgid "An example of an `enum` item and its use:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1072
+#: doc/rust.md:1083
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2153,12 +2170,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1076
+#: doc/rust.md:1087
 msgid "let mut a: Animal = Dog; a = Cat; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1083
+#: doc/rust.md:1094
 #, no-wrap
 msgid ""
 "Enumeration constructors can have either named or unnamed fields:\n"
@@ -2170,33 +2187,33 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1087
+#: doc/rust.md:1098
 msgid ""
 "let mut a: Animal = Dog(~\"Cocoa\", 37.2); a = Cat{ name: ~\"Spotty\", "
 "weight: 2.7 }; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1090
+#: doc/rust.md:1101
 msgid ""
 "In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is "
 "simply called an enum variant."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1092
+#: doc/rust.md:1103
 msgid "### Static items"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1096
+#: doc/rust.md:1107
 msgid ""
 "~~~~~~~~ {.ebnf .gram} static_item : \"static\" ident ':' type '=' expr "
 "';' ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1103
+#: doc/rust.md:1114
 msgid ""
 "A *static item* is a named _constant value_ stored in the global data "
 "section of a crate.  Immutable static items are stored in the read-only data "
@@ -2208,7 +2225,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1108
+#: doc/rust.md:1119
 msgid ""
 "Static items must be explicitly typed.  The type may be ```bool```, "
 "```char```, a number, or a type derived from those primitive types.  The "
@@ -2217,19 +2234,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1112
+#: doc/rust.md:1123
 msgid "~~~~ static BIT1: uint = 1 << 0; static BIT2: uint = 1 << 1;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1115
+#: doc/rust.md:1126
 msgid ""
 "static BITS: [uint, ..2] = [BIT1, BIT2]; static STRING: &'static str = "
 "\"bitstring\";"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1120
+#: doc/rust.md:1131
 #, no-wrap
 msgid ""
 "struct BitsNStrings<'self> {\n"
@@ -2239,7 +2256,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1126
+#: doc/rust.md:1137
 #, no-wrap
 msgid ""
 "static bits_n_strings: BitsNStrings<'static> = BitsNStrings {\n"
@@ -2250,17 +2267,81 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1128
+#: doc/rust.md:1139
+msgid "#### Mutable statics"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1147
+msgid ""
+"If a static item is declared with the ```mut``` keyword, then it is allowed "
+"to be modified by the program. One of Rust's goals is to make concurrency "
+"bugs hard to run into, and this is obviously a very large source of race "
+"conditions or other bugs. For this reason, an ```unsafe``` block is required "
+"when either reading or writing a mutable static variable. Care should be "
+"taken to ensure that modifications to a mutable static are safe with respect "
+"to other tasks running in the same process."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1150
+msgid ""
+"Mutable statics are still very useful, however. They can be used with C "
+"libraries and can also be bound from C libraries (in an ```extern``` block)."
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1153
+msgid "~~~ # fn atomic_add(_: &mut uint, _: uint) -> uint { 2 }"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1155
+msgid "static mut LEVELS: uint = 0;"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1163
+#, no-wrap
+msgid ""
+"// This violates the idea of no shared state, and this doesn't internally\n"
+"// protect against races, so this function is `unsafe`\n"
+"unsafe fn bump_levels_unsafe1() -> uint {\n"
+"    let ret = LEVELS;\n"
+"    LEVELS += 1;\n"
+"    return ret;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1170
+#, no-wrap
+msgid ""
+"// Assuming that we have an atomic_add function which returns the old value,\n"
+"// this function is \"safe\" but the meaning of the return value may not be what\n"
+"// callers expect, so it's still marked as `unsafe`\n"
+"unsafe fn bump_levels_unsafe2() -> uint {\n"
+"    return atomic_add(&mut LEVELS, 1);\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1172
+msgid "~~~"
+msgstr ""
+
+#. type: Plain text
+#: doc/rust.md:1174
 msgid "### Traits"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1130
+#: doc/rust.md:1176
 msgid "A _trait_ describes a set of method types."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1135
+#: doc/rust.md:1181
 msgid ""
 "Traits can include default implementations of methods, written in terms of "
 "some unknown [`self` type](#self-types); the `self` type may either be "
@@ -2268,19 +2349,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1137
+#: doc/rust.md:1183
 msgid ""
 "Traits are implemented for specific types through separate [implementations]"
 "(#implementations)."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1141
+#: doc/rust.md:1187
 msgid "~~~~ # type Surface = int; # type BoundingBox = int;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1147
+#: doc/rust.md:1193
 #, no-wrap
 msgid ""
 "trait Shape {\n"
@@ -2291,7 +2372,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1151
+#: doc/rust.md:1197
 msgid ""
 "This defines a trait with two methods.  All values that have "
 "[implementations](#implementations) of this trait in scope can have their "
@@ -2300,7 +2381,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1154
+#: doc/rust.md:1200
 msgid ""
 "Type parameters can be specified for a trait to make it generic.  These "
 "appear after the trait name, using the same syntax used in [generic "
@@ -2308,7 +2389,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1162
+#: doc/rust.md:1208
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2321,7 +2402,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1168
+#: doc/rust.md:1214
 msgid ""
 "Generic functions may use traits as _bounds_ on their type parameters.  This "
 "will have two effects: only types that have the trait may instantiate the "
@@ -2330,12 +2411,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1172
+#: doc/rust.md:1218
 msgid "~~~~ # type Surface = int; # trait Shape { fn draw(&self, Surface); }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1178
+#: doc/rust.md:1224
 #, no-wrap
 msgid ""
 "fn draw_twice<T: Shape>(surface: Surface, sh: T) {\n"
@@ -2346,7 +2427,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1183
+#: doc/rust.md:1229
 msgid ""
 "Traits also define an [object type](#object-types) with the same name as the "
 "trait.  Values of this type are created by [casting](#type-cast-expressions) "
@@ -2355,17 +2436,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1188
+#: doc/rust.md:1234
 msgid "~~~~ # trait Shape { } # impl Shape for int { } # let mycircle = 0;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1191
+#: doc/rust.md:1237
 msgid "let myshape: @Shape = @mycircle as @Shape; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1197
+#: doc/rust.md:1243
 msgid ""
 "The resulting value is a managed box containing the value that was cast, "
 "along with information that identifies the methods of the implementation "
@@ -2375,7 +2456,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1205
+#: doc/rust.md:1251
 msgid ""
 "Trait methods may be static, which means that they lack a `self` argument.  "
 "This means that they can only be called with function call syntax (`f(x)`)  "
@@ -2385,7 +2466,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1215
+#: doc/rust.md:1261
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2400,19 +2481,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1217
+#: doc/rust.md:1263
 msgid "Traits may inherit from other traits. For example, in"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1222
+#: doc/rust.md:1268
 msgid ""
 "~~~~ trait Shape { fn area() -> float; } trait Circle : Shape { fn radius() -"
 "> float; } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1227
+#: doc/rust.md:1273
 msgid ""
 "the syntax `Circle : Shape` means that types that implement `Circle` must "
 "also have an implementation for `Shape`.  Multiple supertraits are separated "
@@ -2423,7 +2504,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1231 doc/tutorial.md:2177
+#: doc/rust.md:1277 doc/tutorial.md:2176
 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 +2512,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1240 doc/tutorial.md:2186
+#: doc/rust.md:1286 doc/tutorial.md:2185
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2445,12 +2526,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1242 doc/tutorial.md:2188
+#: doc/rust.md:1288 doc/tutorial.md:2187
 msgid "Likewise, supertrait methods may also be called on trait objects."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1249
+#: doc/rust.md:1295
 msgid ""
 "~~~ {.xfail-test} # trait Shape { fn area(&self) -> float; } # trait "
 "Circle : Shape { fn radius(&self) -> float; } # impl Shape for int { fn "
@@ -2459,31 +2540,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1253
+#: doc/rust.md:1299
 msgid ""
 "let mycircle: Circle = @mycircle as @Circle; let nonsense = mycircle."
 "radius() * mycircle.area(); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1255
+#: doc/rust.md:1301
 msgid "### Implementations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1257
+#: doc/rust.md:1303
 msgid ""
 "An _implementation_ is an item that implements a [trait](#traits) for a "
 "specific type."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1259
+#: doc/rust.md:1305
 msgid "Implementations are defined with the keyword `impl`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1266
+#: doc/rust.md:1312
 msgid ""
 "~~~~ # struct Point {x: float, y: float}; # type Surface = int; # struct "
 "BoundingBox {x: float, y: float, width: float, height: float}; # trait Shape "
@@ -2492,7 +2573,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1271
+#: doc/rust.md:1317
 #, no-wrap
 msgid ""
 "struct Circle {\n"
@@ -2502,7 +2583,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1281
+#: doc/rust.md:1327
 #, no-wrap
 msgid ""
 "impl Shape for Circle {\n"
@@ -2517,7 +2598,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1288
+#: doc/rust.md:1334
 msgid ""
 "It is possible to define an implementation without referring to a trait.  "
 "The methods in such an implementation can only be used as direct calls on "
@@ -2529,14 +2610,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1292
+#: doc/rust.md:1338
 msgid ""
 "When a trait _is_ specified in an `impl`, all methods declared as part of "
 "the trait must be implemented, with matching types and type parameter counts."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1296
+#: doc/rust.md:1342
 msgid ""
 "An implementation can take type parameters, which can be different from the "
 "type parameters taken by the trait it implements.  Implementation parameters "
@@ -2544,12 +2625,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1299
+#: doc/rust.md:1345
 msgid "~~~~ # trait Seq<T> { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1307
+#: doc/rust.md:1353
 #, no-wrap
 msgid ""
 "impl<T> Seq<T> for ~[T] {\n"
@@ -2562,19 +2643,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1309
+#: doc/rust.md:1355
 msgid "### External blocks"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1314
+#: doc/rust.md:1360
 msgid ""
 "~~~ {.ebnf .gram} extern_block_item : \"extern\" '{' extern_block '} ; "
 "extern_block : [ foreign_fn ] * ; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1318
+#: doc/rust.md:1364
 msgid ""
 "External blocks form the basis for Rust's foreign function interface.  "
 "Declarations in an external block describe symbols in external, non-Rust "
@@ -2582,7 +2663,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1323
+#: doc/rust.md:1369
 msgid ""
 "Functions within external blocks are declared in the same way as other Rust "
 "functions, with the exception that they may not have a body and are instead "
@@ -2590,12 +2671,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1327
+#: doc/rust.md:1373
 msgid "~~~ # use std::libc::{c_char, FILE}; # #[nolink]"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1332
+#: doc/rust.md:1378
 #, no-wrap
 msgid ""
 "extern {\n"
@@ -2605,7 +2686,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1337
+#: doc/rust.md:1383
 msgid ""
 "Functions within external blocks may be called by Rust code, just like "
 "functions defined in Rust.  The Rust compiler automatically translates "
@@ -2613,14 +2694,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1340
+#: doc/rust.md:1386
 msgid ""
 "A number of [attributes](#attributes) control the behavior of external "
 "blocks."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1344
+#: doc/rust.md:1390
 msgid ""
 "By default external blocks assume that the library they are calling uses the "
 "standard C \"cdecl\" ABI.  Other ABIs may be specified using the `abi` "
@@ -2628,25 +2709,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1350
+#: doc/rust.md:1396
 msgid ""
 "~~~{.xfail-test} // Interface to the Windows API #[abi = \"stdcall\"] extern "
 "{ } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1352
+#: doc/rust.md:1398
 msgid ""
 "The `link_name` attribute allows the name of the library to be specified."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1357
+#: doc/rust.md:1403
 msgid "~~~{.xfail-test} #[link_name = \"crypto\"] extern { } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1363
+#: doc/rust.md:1409
 msgid ""
 "The `nolink` attribute tells the Rust compiler not to do any linking for the "
 "external block.  This is particularly useful for creating external blocks "
@@ -2655,12 +2736,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1365
+#: doc/rust.md:1411
 msgid "## Attributes"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1372
+#: doc/rust.md:1418
 #, no-wrap
 msgid ""
 "~~~~~~~~{.ebnf .gram}\n"
@@ -2672,7 +2753,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1378
+#: doc/rust.md:1424
 msgid ""
 "Static entities in Rust -- crates, modules and items -- may have "
 "_attributes_ applied to them. ^[Attributes in Rust are modeled on Attributes "
@@ -2682,25 +2763,25 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1382
+#: doc/rust.md:1428
 msgid "A single identifier, the attribute name"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1382
+#: doc/rust.md:1428
 msgid ""
 "An identifier followed by the equals sign '=' and a literal, providing a key/"
 "value pair"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1382
+#: doc/rust.md:1428
 msgid ""
 "An identifier followed by a parenthesized list of sub-attribute arguments"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1385
+#: doc/rust.md:1431
 msgid ""
 "Attributes terminated by a semi-colon apply to the entity that the attribute "
 "is declared within. Attributes that are not terminated by a semi-colon apply "
@@ -2708,19 +2789,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1387
+#: doc/rust.md:1433
 msgid "An example of attributes:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1391
+#: doc/rust.md:1437
 msgid ""
 "~~~~~~~~{.xfail-test} // General metadata applied to the enclosing module or "
 "crate.  #[license = \"BSD\"];"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1397
+#: doc/rust.md:1443
 #, no-wrap
 msgid ""
 "// A function marked as a unit test\n"
@@ -2731,7 +2812,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1403
+#: doc/rust.md:1449
 #, no-wrap
 msgid ""
 "// A conditionally-compiled module\n"
@@ -2742,14 +2823,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1408
+#: doc/rust.md:1454
 msgid ""
 "// A lint attribute used to suppress a warning/error "
 "#[allow(non_camel_case_types)] pub type int8_t = i8; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1411
+#: doc/rust.md:1457
 msgid ""
 "> **Note:** In future versions of Rust, user-provided extensions to the "
 "compiler will be able to interpret attributes.  > When this facility is "
@@ -2758,74 +2839,74 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1414
+#: doc/rust.md:1460
 msgid ""
 "At present, only the Rust compiler interprets attributes, so all attribute "
 "names are effectively reserved. Some significant attributes include:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid "The `doc` attribute, for documenting code in-place."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid ""
 "The `cfg` attribute, for conditional-compilation by build-configuration."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid ""
 "The `lang` attribute, for custom definitions of traits and functions that "
 "are known to the Rust compiler (see [Language items](#language-items))."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid "The `link` attribute, for describing linkage metadata for a crate."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid "The `test` attribute, for marking functions as unit tests."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid ""
 "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
+#: doc/rust.md:1471
 msgid ""
 "The `deriving` attribute, for automatically generating implementations of "
 "certain traits."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1425
+#: doc/rust.md:1471
 msgid ""
 "The `static_assert` attribute, for asserting that a static bool is true at "
 "compiletime"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1427
+#: doc/rust.md:1473
 msgid ""
 "Other attributes may be added or removed during development of the language."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1429
+#: doc/rust.md:1475
 msgid "### Lint check attributes"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1433
+#: doc/rust.md:1479
 msgid ""
 "A lint check names a potentially undesirable coding pattern, such as "
 "unreachable code or omitted documentation, for the static entity to which "
@@ -2833,22 +2914,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1435
+#: doc/rust.md:1481
 msgid "For any lint check `C`:"
 msgstr ""
 
 #. type: Bullet: ' * '
-#: doc/rust.md:1442
+#: doc/rust.md:1488
 msgid "`warn(C)` warns about violations of `C` but continues compilation,"
 msgstr ""
 
 #. type: Bullet: ' * '
-#: doc/rust.md:1442
+#: doc/rust.md:1488
 msgid "`deny(C)` signals an error after encountering a violation of `C`,"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1442
+#: doc/rust.md:1488
 #, no-wrap
 msgid ""
 " * `allow(C)` overrides the check for `C` so that violations will go\n"
@@ -2858,14 +2939,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1445
+#: doc/rust.md:1491
 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
+#: doc/rust.md:1497
 #, no-wrap
 msgid ""
 "~~~{.xfail-test}\n"
@@ -2876,7 +2957,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1455
+#: doc/rust.md:1501
 #, no-wrap
 msgid ""
 "    // Missing documentation signals a warning here\n"
@@ -2885,7 +2966,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1461
+#: doc/rust.md:1507
 #, no-wrap
 msgid ""
 "    // Missing documentation signals an error here\n"
@@ -2896,17 +2977,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1464
+#: doc/rust.md:1510
 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
+#: doc/rust.md:1518
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test}\n"
 "#[warn(missing_doc)]\n"
 "mod m2{\n"
 "    #[allow(missing_doc)]\n"
@@ -2916,7 +2997,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1478
+#: doc/rust.md:1524
 #, no-wrap
 msgid ""
 "        // Missing documentation signals a warning here,\n"
@@ -2927,7 +3008,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1483
+#: doc/rust.md:1529
 #, no-wrap
 msgid ""
 "    // Missing documentation signals a warning here\n"
@@ -2937,14 +3018,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1486
+#: doc/rust.md:1532
 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
+#: doc/rust.md:1542
 #, no-wrap
 msgid ""
 "~~~{.xfail-test}\n"
@@ -2959,12 +3040,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1498
+#: doc/rust.md:1544
 msgid "### Language items"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1504
+#: doc/rust.md:1550
 msgid ""
 "Some primitive Rust operations are defined in Rust code, rather than being "
 "implemented directly in C or assembly language.  The definitions of these "
@@ -2974,7 +3055,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1511
+#: doc/rust.md:1557
 #, no-wrap
 msgid ""
 "~~~ {.xfail-test}\n"
@@ -2986,7 +3067,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1515
+#: doc/rust.md:1561
 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 "
@@ -2994,23 +3075,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1517
+#: doc/rust.md:1563
 msgid "A complete list of the built-in language items follows:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1519
+#: doc/rust.md:1565
 msgid "#### Traits"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1560
+#: doc/rust.md:1604
 #, no-wrap
 msgid ""
 "`const`\n"
 "  : Cannot be mutated.\n"
-"`copy`\n"
-"  : Can be implicitly copied.\n"
 "`owned`\n"
 "  : Are uniquely owned.\n"
 "`durable`\n"
@@ -3050,12 +3129,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1562
+#: doc/rust.md:1606
 msgid "#### Operations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1591
+#: doc/rust.md:1636
 #, no-wrap
 msgid ""
 "`str_eq`\n"
@@ -3085,23 +3164,24 @@ msgid ""
 "`check_not_borrowed`\n"
 "  : Fail if a value has existing borrowed pointers to it.\n"
 "`strdup_uniq`\n"
-"  : Return a new unique string containing a copy of the contents of a unique string.\n"
+"  : Return a new unique string\n"
+"    containing a copy of the contents of a unique string.\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1594
+#: doc/rust.md:1639
 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:1596
+#: doc/rust.md:1641
 msgid "### Deriving"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1602
+#: doc/rust.md:1647
 msgid ""
 "The `deriving` attribute allows certain traits to be automatically "
 "implemented for data structures. For example, the following will create an "
@@ -3110,7 +3190,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1610
+#: doc/rust.md:1655
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -3123,12 +3203,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1612
+#: doc/rust.md:1657
 msgid "The generated `impl` for `Eq` is equivalent to"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1619
+#: doc/rust.md:1664
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -3140,7 +3220,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1625
+#: doc/rust.md:1670
 #, no-wrap
 msgid ""
 "    fn ne(&self, other: &Foo<T>) -> bool {\n"
@@ -3151,42 +3231,42 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1627
+#: doc/rust.md:1672
 msgid "Supported traits for `deriving` are:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "Serialization: `Encodable`, `Decodable`. These require `extra`."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "`Clone` and `DeepClone`, to perform (deep) copies."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "`IterBytes`, to iterate over the bytes in a data type."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "`Rand`, to create a random instance of a data type."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 msgid "`Zero`, to create an zero (or empty) instance of a data type."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:1638
+#: doc/rust.md:1683
 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 "
@@ -3195,12 +3275,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1640
+#: doc/rust.md:1685
 msgid "# Statements and expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1647
+#: doc/rust.md:1692
 msgid ""
 "Rust is _primarily_ an expression language. This means that most forms of "
 "value-producing or effect-causing evaluation are directed by the uniform "
@@ -3211,38 +3291,38 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1650
+#: doc/rust.md:1695
 msgid ""
 "In contrast, statements in Rust serve _mostly_ to contain and explicitly "
 "sequence expression evaluation."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1652
+#: doc/rust.md:1697
 msgid "## Statements"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1655
+#: doc/rust.md:1700
 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:1659
+#: doc/rust.md:1704
 msgid ""
 "Rust has two kinds of statement: [declaration statements](#declaration-"
 "statements) and [expression statements](#expression-statements)."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1661
+#: doc/rust.md:1706
 msgid "### Declaration statements"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1664
+#: doc/rust.md:1709
 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 "
@@ -3250,12 +3330,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1666
+#: doc/rust.md:1711
 msgid "#### Item declarations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1673
+#: doc/rust.md:1718
 msgid ""
 "An _item declaration statement_ has a syntactic form identical to an [item]"
 "(#items) declaration within a module. Declaring an item -- a function, "
@@ -3266,26 +3346,26 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1676
+#: doc/rust.md:1721
 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:1679
+#: doc/rust.md:1724
 msgid "#### Slot declarations"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1684
+#: doc/rust.md:1729
 msgid ""
 "~~~~~~~~{.ebnf .gram} let_decl : \"let\" pat [':' type ] ? [ init ] ? ';' ; "
 "init : [ '=' ] expr ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1690
+#: doc/rust.md:1735
 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 "
@@ -3296,12 +3376,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1692
+#: doc/rust.md:1737
 msgid "### Expression statements"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1697
+#: doc/rust.md:1742
 msgid ""
 "An _expression statement_ is one that evaluates an [expression]"
 "(#expressions)  and ignores its result.  The type of an expression statement "
@@ -3311,12 +3391,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1699
+#: doc/rust.md:1744
 msgid "## Expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1708
+#: doc/rust.md:1753
 #, no-wrap
 msgid ""
 "An expression may have two roles: it always produces a *value*, and it may have *effects*\n"
@@ -3330,7 +3410,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1713
+#: doc/rust.md:1758
 msgid ""
 "In this way, the structure of expressions dictates the structure of "
 "execution.  Blocks are just another kind of expression, so blocks, "
@@ -3339,12 +3419,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1715
+#: doc/rust.md:1760
 msgid "#### Lvalues, rvalues and temporaries"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1719
+#: doc/rust.md:1764
 msgid ""
 "Expressions are divided into two main categories: _lvalues_ and _rvalues_.  "
 "Likewise within each expression, sub-expressions may occur in _lvalue "
@@ -3353,14 +3433,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1722
+#: doc/rust.md:1767
 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:1730
+#: doc/rust.md:1775
 msgid ""
 "The left operand of an [assignment](#assignment-expressions), [binary move]"
 "(#binary-move-expressions) or [compound-assignment](#compound-assignment-"
@@ -3371,7 +3451,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1733
+#: doc/rust.md:1778
 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 "
@@ -3379,7 +3459,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1736
+#: doc/rust.md:1781
 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 "
@@ -3387,27 +3467,27 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1738
+#: doc/rust.md:1783
 msgid "#### Moved and copied types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1744
+#: doc/rust.md:1792
 msgid ""
 "When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-"
 "rvalues-and-temporaries)  the variable will either be [moved](#move-"
-"expressions) or [copied](#copy-expressions), depending on its type.  For "
-"types that contain mutable fields or [owning pointers](#owning-pointers), "
-"the variable is moved.  All other types are copied."
+"expressions) or copied, depending on its type.  For types that contain "
+"[owning pointers](#owning-pointers)  or values that implement the special "
+"trait `Drop`, the variable is moved.  All other types are copied."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1747
+#: doc/rust.md:1795
 msgid "### Literal expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1751
+#: doc/rust.md:1799
 msgid ""
 "A _literal expression_ consists of one of the [literal](#literals)  forms "
 "described earlier. It directly describes a number, character, string, "
@@ -3415,7 +3495,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1758
+#: doc/rust.md:1806
 #, no-wrap
 msgid ""
 "~~~~~~~~ {.literals}\n"
@@ -3427,12 +3507,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1760
+#: doc/rust.md:1808
 msgid "### Path expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1763
+#: doc/rust.md:1811
 msgid ""
 "A [path](#paths) used as an expression context denotes either a local "
 "variable or an item.  Path expressions are [lvalues](#lvalues-rvalues-and-"
@@ -3440,29 +3520,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1765
+#: doc/rust.md:1813
 msgid "### Tuple expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1769
+#: doc/rust.md:1817
 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:1775
+#: doc/rust.md:1823
 msgid "~~~~~~~~ {.tuple} (0,); (0f, 4.5f); (\"a\", 4u, true); ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1777
+#: doc/rust.md:1825
 msgid "### Structure expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1786
+#: doc/rust.md:1834
 #, no-wrap
 msgid ""
 "~~~~~~~~{.ebnf .gram}\n"
@@ -3476,7 +3556,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1793
+#: doc/rust.md:1841
 msgid ""
 "There are several forms of structure expressions.  A _structure expression_ "
 "consists of the [path](#paths) of a [structure item](#structures), followed "
@@ -3488,7 +3568,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1798
+#: doc/rust.md:1846
 msgid ""
 "A _tuple structure expression_ consists of the [path](#paths) of a "
 "[structure item](#structures), followed by a parenthesized list of one or "
@@ -3498,19 +3578,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1800
+#: doc/rust.md:1848
 msgid ""
 "A _unit-like structure expression_ consists only of the [path](#paths) of a "
 "[structure item](#structures)."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1802
+#: doc/rust.md:1850
 msgid "The following are examples of structure expressions:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1813
+#: doc/rust.md:1861
 msgid ""
 "~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, "
 "float); # mod game { pub struct User<'self> { name: &'self str, age: uint, "
@@ -3520,7 +3600,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1816
+#: doc/rust.md:1864
 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 "
@@ -3528,7 +3608,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1823
+#: doc/rust.md:1871
 msgid ""
 "A structure expression can terminate with the syntax `..` followed by an "
 "expression to denote a functional update.  The expression following `..` "
@@ -3540,19 +3620,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1829
+#: doc/rust.md:1877
 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:1831
+#: doc/rust.md:1879
 msgid "### Record expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1837
+#: doc/rust.md:1885
 #, no-wrap
 msgid ""
 "~~~~~~~~{.ebnf .gram}\n"
@@ -3563,19 +3643,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1839
+#: doc/rust.md:1887
 msgid "### Method-call expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1843
+#: doc/rust.md:1891
 msgid ""
 "~~~~~~~~{.ebnf .gram} method_call_expr : expr '.' ident paren_expr_list ; "
 "~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1848
+#: doc/rust.md:1896
 msgid ""
 "A _method call_ consists of an expression followed by a single dot, an "
 "identifier, and a parenthesized expression-list.  Method calls are resolved "
@@ -3586,17 +3666,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1851
+#: doc/rust.md:1899
 msgid "### Field expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1855
+#: doc/rust.md:1903
 msgid "~~~~~~~~{.ebnf .gram} field_expr : expr '.' ident ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1859
+#: doc/rust.md:1907
 msgid ""
 "A _field expression_ consists of an expression followed by a single dot and "
 "an identifier, when not immediately followed by a parenthesized expression-"
@@ -3605,12 +3685,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1864
+#: doc/rust.md:1912
 msgid "~~~~~~~~ {.field} myrecord.myfield; {a: 10, b: 20}.a; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1867
+#: doc/rust.md:1915
 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 "
@@ -3618,7 +3698,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1870
+#: doc/rust.md:1918
 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 "
@@ -3626,29 +3706,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1873
+#: doc/rust.md:1921
 msgid "### Vector expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1876
+#: doc/rust.md:1924
 msgid "~~~~~~~~{.ebnf .gram} vec_expr : '[' \"mut\"? vec_elems? ']'"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1879
+#: doc/rust.md:1927
 msgid "vec_elems : [expr [',' expr]*] | [expr ',' \"..\" expr] ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1882
+#: doc/rust.md:1930
 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:1886
+#: doc/rust.md:1934
 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 "
@@ -3656,7 +3736,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1893
+#: doc/rust.md:1941
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3668,17 +3748,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1895
+#: doc/rust.md:1943
 msgid "### Index expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1899
+#: doc/rust.md:1947
 msgid "~~~~~~~~{.ebnf .gram} idx_expr : expr '[' expr ']' ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1904
+#: doc/rust.md:1952
 msgid ""
 "[Vector](#vector-types)-typed expressions can be indexed by writing a square-"
 "bracket-enclosed expression (the index) after them. When the vector is "
@@ -3687,7 +3767,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1908
+#: doc/rust.md:1956
 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 "
@@ -3695,36 +3775,34 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1912
+#: doc/rust.md:1960
 msgid "~~~~ # use std::task; # do task::spawn_unlinked {"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1915
+#: doc/rust.md:1963
 msgid "([1, 2, 3, 4])[0]; ([\"a\", \"b\"])[10]; // fails"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1918 doc/tutorial-tasks.md:649
+#: doc/rust.md:1966 doc/tutorial-tasks.md:648
 msgid "# } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1920
+#: doc/rust.md:1968
 msgid "### Unary operator expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1924
+#: doc/rust.md:1972
 msgid ""
-"Rust defines six symbolic unary operators, in addition to the unary [copy]"
-"(#unary-copy-expressions) and [move](#unary-move-expressions) operators.  "
-"They are all written as prefix operators, before the expression they apply "
-"to."
+"Rust defines six symbolic unary operators.  They are all written as prefix "
+"operators, before the expression they apply to."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1943
+#: doc/rust.md:1991
 #, no-wrap
 msgid ""
 "`-`\n"
@@ -3748,29 +3826,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1945
+#: doc/rust.md:1993
 msgid "### Binary operator expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1949
+#: doc/rust.md:1997
 msgid "~~~~~~~~{.ebnf .gram} binop_expr : expr binop expr ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1952
+#: doc/rust.md:2000
 msgid ""
 "Binary operators expressions are given in terms of [operator precedence]"
 "(#operator-precedence)."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1954
+#: doc/rust.md:2002
 msgid "#### Arithmetic operators"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1959
+#: doc/rust.md:2007
 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 "
@@ -3779,7 +3857,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1975
+#: doc/rust.md:2023
 #, no-wrap
 msgid ""
 "`+`\n"
@@ -3800,12 +3878,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1977
+#: doc/rust.md:2025
 msgid "#### Bitwise operators"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1982
+#: doc/rust.md:2030
 msgid ""
 "Like the [arithmetic operators](#arithmetic-operators), bitwise operators "
 "are syntactic sugar for calls to methods of built-in traits.  This means "
@@ -3814,7 +3892,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1998
+#: doc/rust.md:2046
 #, no-wrap
 msgid ""
 "`&`\n"
@@ -3835,12 +3913,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2000
+#: doc/rust.md:2048
 msgid "#### Lazy boolean operators"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2007
+#: doc/rust.md:2055
 msgid ""
 "The operators `||` and `&&` may be applied to operands of boolean type.  The "
 "`||` operator denotes logical 'or', and the `&&` operator denotes logical "
@@ -3852,12 +3930,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2009
+#: doc/rust.md:2057
 msgid "#### Comparison operators"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2015
+#: doc/rust.md:2063
 msgid ""
 "Comparison operators are, like the [arithmetic operators](#arithmetic-"
 "operators), and [bitwise operators](#bitwise-operators), syntactic sugar for "
@@ -3867,7 +3945,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2034
+#: doc/rust.md:2082
 #, no-wrap
 msgid ""
 "`==`\n"
@@ -3891,24 +3969,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2037
+#: doc/rust.md:2085
 msgid "#### Type cast expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2039
+#: doc/rust.md:2087
 msgid "A type cast expression is denoted with the binary operator `as`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2042
+#: doc/rust.md:2090
 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:2046
+#: doc/rust.md:2094
 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 "
@@ -3916,19 +3994,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2048
+#: doc/rust.md:2096
 msgid "An example of an `as` expression:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2052
+#: doc/rust.md:2100
 msgid ""
 "~~~~ # fn sum(v: &[float]) -> float { 0.0 } # fn len(v: &[float]) -> int "
 "{ 0 }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2059
+#: doc/rust.md:2107
 #, no-wrap
 msgid ""
 "fn avg(v: &[float]) -> float {\n"
@@ -3940,12 +4018,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2061
+#: doc/rust.md:2109
 msgid "#### Assignment expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2064
+#: doc/rust.md:2112
 msgid ""
 "An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-"
 "temporaries) expression followed by an equals sign (`=`) and an [rvalue]"
@@ -3953,29 +4031,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2066
+#: doc/rust.md:2114
 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:2070
+#: doc/rust.md:2118
 msgid "~~~~ # let mut x = 0; # let y = 0;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2073
+#: doc/rust.md:2121
 msgid "x = y; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2075
+#: doc/rust.md:2123
 msgid "#### Compound assignment expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2080
+#: doc/rust.md:2128
 msgid ""
 "The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be "
 "composed with the `=` operator. The expression `lval OP= val` is equivalent "
@@ -3983,24 +4061,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2082
+#: doc/rust.md:2130
 msgid "Any such expression always has the [`unit`](#primitive-types) type."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2084
+#: doc/rust.md:2132
 msgid "#### Operator precedence"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2087
+#: doc/rust.md:2135
 msgid ""
 "The precedence of Rust binary operators is ordered as follows, going from "
 "strong to weak:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2100
+#: doc/rust.md:2148
 #, no-wrap
 msgid ""
 "~~~~ {.precedence}\n"
@@ -4019,12 +4097,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2102 doc/rust.md:2243 doc/tutorial-macros.md:323
+#: doc/rust.md:2150 doc/rust.md:2237 doc/tutorial-macros.md:323
 msgid "~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2105
+#: doc/rust.md:2153
 msgid ""
 "Operators at the same precedence level are evaluated left-to-right. [Unary "
 "operators](#unary-operator-expressions)  have the same precedence level and "
@@ -4032,12 +4110,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2107
+#: doc/rust.md:2155
 msgid "### Grouped expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2111
+#: doc/rust.md:2159
 msgid ""
 "An expression enclosed in parentheses evaluates to the result of the "
 "enclosed expression.  Parentheses can be used to explicitly specify "
@@ -4045,135 +4123,27 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2115
+#: doc/rust.md:2163
 msgid "~~~~~~~~{.ebnf .gram} paren_expr : '(' expr ')' ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2117
+#: doc/rust.md:2165
 msgid "An example of a parenthesized expression:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2121
+#: doc/rust.md:2169
 msgid "~~~~ let x = (2 + 3) * 4; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2123
-msgid "### Unary copy expressions"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2127
-msgid "~~~~~~~~{.ebnf .gram} copy_expr : \"copy\" expr ; ~~~~~~~~"
-msgstr ""
-
-#. type: Plain text
-#: 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:2133
-msgid ""
-"A _unary copy expression_ consists of the unary `copy` operator applied to "
-"some argument expression."
-msgstr ""
-
-#. type: Plain text
-#: 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 "
-"copy."
-msgstr ""
-
-#. type: Plain text
-#: 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 "
-"vectors](#vector-types) and similar owned types are deep-copied."
-msgstr ""
-
-#. type: Plain text
-#: 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 "
-"cause an argument to a function to be copied and passed by value."
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2146
-msgid "An example of a copy expression:"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2151
-#, no-wrap
-msgid ""
-"~~~~\n"
-"fn mutate(mut vec: ~[int]) {\n"
-"   vec[0] = 10;\n"
-"}\n"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2153
-msgid "let v = ~[1,2,3];"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2155
-#, no-wrap
-msgid "mutate(copy v);   // Pass a copy\n"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2158
-msgid "assert!(v[0] == 1); // Original was not modified ~~~~"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2160
-msgid "### Unary move expressions"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2164
-msgid "~~~~~~~~{.ebnf .gram} move_expr : \"move\" expr ; ~~~~~~~~"
-msgstr ""
-
-#. type: Plain text
-#: 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 "
-"variable](#memory-slots), and it performs a _move_ on its operand, rather "
-"than a copy.  That is, the memory location denoted by its operand is de-"
-"initialized after evaluation, and the resulting value is a shallow copy of "
-"the operand, even if the operand is an [owning type](#type-kinds)."
-msgstr ""
-
-#. type: Plain text
-#: 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) "
-"for most cases `move` would be appropriate."
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2178
+#: doc/rust.md:2172
 msgid "### Call expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2184
+#: doc/rust.md:2178
 msgid ""
 "~~~~~~~~ {.abnf .gram} expr_list : [ expr [ ',' expr ]* ] ? ; "
 "paren_expr_list : '(' expr_list ')' ; call_expr : expr paren_expr_list ; "
@@ -4181,7 +4151,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2189
+#: doc/rust.md:2183
 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 "
@@ -4190,36 +4160,36 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2191
+#: doc/rust.md:2185
 msgid "Some examples of call expressions:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2195
+#: doc/rust.md:2189
 msgid ""
 "~~~~ # use std::from_str::FromStr; # fn add(x: int, y: int) -> int { 0 }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2199
+#: doc/rust.md:2193
 msgid ""
 "let x: int = add(1, 2); let pi = FromStr::from_str::<f32>(\"3.14\"); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2201
+#: doc/rust.md:2195
 msgid "### Lambda expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2206
+#: doc/rust.md:2200
 msgid ""
 "~~~~~~~~ {.abnf .gram} ident_list : [ ident [ ',' ident ]* ] ? ; "
 "lambda_expr : '|' ident_list '|' expr ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2210
+#: doc/rust.md:2204
 msgid ""
 "A _lambda expression_ (sometimes called an \"anonymous function expression"
 "\") defines a function and denotes it as a value, in a single expression.  A "
@@ -4228,7 +4198,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2215
+#: doc/rust.md:2209
 msgid ""
 "A lambda expression denotes a function that maps a list of parameters "
 "(`ident_list`)  onto the expression that follows the `ident_list`.  The "
@@ -4238,7 +4208,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2218
+#: doc/rust.md:2212
 msgid ""
 "Lambda expressions are most useful when passing functions as arguments to "
 "other functions, as an abbreviation for defining and capturing a separate "
@@ -4246,7 +4216,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2227
+#: doc/rust.md:2221
 msgid ""
 "Significantly, lambda expressions _capture their environment_, which regular "
 "[function definitions](#functions) do not.  The exact type of capture "
@@ -4260,14 +4230,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2230
+#: doc/rust.md:2224
 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:2239
+#: doc/rust.md:2233
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -4281,23 +4251,23 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2241
+#: doc/rust.md:2235
 msgid "ten_times(|j| println(fmt!(\"hello, %d\", j)));"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2245
+#: doc/rust.md:2239
 msgid "### While loops"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2249
+#: doc/rust.md:2243
 msgid ""
 "~~~~~~~~{.ebnf .gram} while_expr : \"while\" expr '{' block '}' ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2254
+#: doc/rust.md:2248
 msgid ""
 "A `while` loop begins by evaluating the boolean loop conditional "
 "expression.  If the loop conditional expression evaluates to `true`, the "
@@ -4307,17 +4277,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2256
+#: doc/rust.md:2250
 msgid "An example:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2259
+#: doc/rust.md:2253
 msgid "~~~~ let mut i = 0;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2265
+#: doc/rust.md:2259
 #, no-wrap
 msgid ""
 "while i < 10 {\n"
@@ -4328,12 +4298,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2267
+#: doc/rust.md:2261
 msgid "### Infinite loops"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2271
+#: doc/rust.md:2265
 msgid ""
 "The keyword `loop` in Rust appears both in _loop expressions_ and in "
 "_continue expressions_.  A loop expression denotes an infinite loop; see "
@@ -4341,14 +4311,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2275
+#: doc/rust.md:2269
 msgid ""
 "~~~~~~~~{.ebnf .gram} loop_expr : [ lifetime ':' ] \"loop\" '{' block '}'; "
 "~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2280
+#: doc/rust.md:2274
 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 "
@@ -4357,17 +4327,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2282
+#: doc/rust.md:2276
 msgid "### Break expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2286
+#: doc/rust.md:2280
 msgid "~~~~~~~~{.ebnf .gram} break_expr : \"break\" [ lifetime ]; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2293
+#: doc/rust.md:2287
 msgid ""
 "A `break` expression has an optional `label`.  If the label is absent, then "
 "executing a `break` expression immediately terminates the innermost loop "
@@ -4378,17 +4348,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2295
+#: doc/rust.md:2289
 msgid "### Continue expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2299
+#: doc/rust.md:2293
 msgid "~~~~~~~~{.ebnf .gram} continue_expr : \"loop\" [ lifetime ]; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2310
+#: doc/rust.md:2304
 msgid ""
 "A continue expression, written `loop`, also has an optional `label`.  If the "
 "label is absent, then executing a `loop` expression immediately terminates "
@@ -4402,24 +4372,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2312
+#: doc/rust.md:2306
 msgid "A `loop` expression is only permitted in the body of a loop."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2315
+#: doc/rust.md:2309
 msgid "### Do expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2319
+#: doc/rust.md:2313
 msgid ""
 "~~~~~~~~{.ebnf .gram} do_expr : \"do\" expr [ '|' ident_list '|' ] ? '{' "
 "block '}' ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2322
+#: doc/rust.md:2316
 msgid ""
 "A _do expression_ provides a more-familiar block-syntax for a [lambda "
 "expression](#lambda-expressions), including a special translation of [return "
@@ -4427,7 +4397,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2330
+#: doc/rust.md:2324
 msgid ""
 "Any occurrence of a [return expression](#return-expressions)  inside this "
 "`block` expression is rewritten as a reference to an (anonymous) flag set in "
@@ -4439,7 +4409,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2333
+#: doc/rust.md:2327
 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 "
@@ -4447,7 +4417,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2339
+#: doc/rust.md:2333
 msgid ""
 "The lambda expression is then provided as a _trailing argument_ to the "
 "outermost [call](#call-expressions) or [method call](#method-call-"
@@ -4458,22 +4428,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2341
+#: doc/rust.md:2335
 msgid "In this example, both calls to `f` are equivalent:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2345
+#: doc/rust.md:2339
 msgid "~~~~ # fn f(f: &fn(int)) { } # fn g(i: int) { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2347
+#: doc/rust.md:2341
 msgid "f(|j| g(j));"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2352
+#: doc/rust.md:2346
 #, no-wrap
 msgid ""
 "do f |j| {\n"
@@ -4483,23 +4453,23 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2354
+#: doc/rust.md:2348
 msgid ""
 "In this example, both calls to the (binary) function `k` are equivalent:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2358
+#: doc/rust.md:2352
 msgid "~~~~ # fn k(x:int, f: &fn(int)) { } # fn l(i: int) { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2360
+#: doc/rust.md:2354
 msgid "k(3, |j| l(j));"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2365
+#: doc/rust.md:2359
 #, no-wrap
 msgid ""
 "do k(3) |j| {\n"
@@ -4509,19 +4479,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2368
+#: doc/rust.md:2362
 msgid "### For expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2372
+#: doc/rust.md:2366
 msgid ""
 "~~~~~~~~{.ebnf .gram} for_expr : \"for\" expr [ '|' ident_list '|' ] ? '{' "
 "block '}' ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2376
+#: doc/rust.md:2370
 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 "
@@ -4529,7 +4499,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2382
+#: doc/rust.md:2376
 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 "
@@ -4539,7 +4509,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2389
+#: doc/rust.md:2383
 msgid ""
 "In addition, [`break`](#break-expressions) and [`loop`](#loop-expressions) "
 "expressions are rewritten inside `for` expressions in the same way that "
@@ -4550,24 +4520,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2391
+#: doc/rust.md:2385
 msgid "An example of a for loop over the contents of a vector:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2398
+#: doc/rust.md:2392
 msgid ""
 "~~~~ # type foo = int; # fn bar(f: foo) { } # let a = 0; # let b = 0; # let "
 "c = 0;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2400
+#: doc/rust.md:2394
 msgid "let v: &[foo] = &[a, b, c];"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2405
+#: doc/rust.md:2399
 #, no-wrap
 msgid ""
 "for e in v.iter() {\n"
@@ -4577,30 +4547,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2407
+#: doc/rust.md:2401
 msgid "An example of a for loop over a series of integers:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2415
+#: doc/rust.md:2408
 #, no-wrap
 msgid ""
 "~~~~\n"
-"# use std::uint;\n"
 "# fn bar(b:uint) { }\n"
-"for uint::range(0, 256) |i| {\n"
+"for i in range(0u, 256) {\n"
 "    bar(i);\n"
 "}\n"
 "~~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2417
+#: doc/rust.md:2410
 msgid "### If expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2421
+#: doc/rust.md:2414
 #, no-wrap
 msgid ""
 "~~~~~~~~{.ebnf .gram}\n"
@@ -4609,7 +4578,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2425
+#: doc/rust.md:2418
 #, no-wrap
 msgid ""
 "else_tail : \"else\" [ if_expr\n"
@@ -4618,7 +4587,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2436
+#: doc/rust.md:2429
 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 "
@@ -4632,29 +4601,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2439
+#: doc/rust.md:2432
 msgid "### Match expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2442
+#: doc/rust.md:2435
 msgid ""
 "~~~~~~~~{.ebnf .gram} match_expr : \"match\" expr '{' match_arm [ '|' "
 "match_arm ] * '}' ;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2444
+#: doc/rust.md:2437
 msgid "match_arm : match_pat '=>' [ expr \",\" | '{' block '}' ] ;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2447
+#: doc/rust.md:2440
 msgid "match_pat : pat [ \"..\" pat ] ? [ \"if\" expr ] ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2455
+#: doc/rust.md:2448
 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 "
@@ -4666,7 +4635,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2459
+#: doc/rust.md:2452
 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* "
@@ -4674,17 +4643,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2462
+#: doc/rust.md:2455
 msgid "~~~~ enum List<X> { Nil, Cons(X, @List<X>) }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2464 doc/rust.md:2493
+#: doc/rust.md:2457 doc/rust.md:2486
 msgid "let x: List<int> = Cons(10, @Cons(11, @Nil));"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2471
+#: doc/rust.md:2464
 #, no-wrap
 msgid ""
 "match x {\n"
@@ -4696,7 +4665,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2476
+#: doc/rust.md:2469
 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 "
@@ -4707,7 +4676,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2482
+#: doc/rust.md:2475
 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 "
@@ -4717,22 +4686,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2484
+#: doc/rust.md:2477
 msgid "An example of an `match` expression:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2489
+#: doc/rust.md:2482
 msgid "~~~~ # fn process_pair(a: int, b: int) { } # fn process_ten() { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2491
+#: doc/rust.md:2484
 msgid "enum List<X> { Nil, Cons(X, @List<X>) }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2509
+#: doc/rust.md:2502
 #, no-wrap
 msgid ""
 "match x {\n"
@@ -4753,17 +4722,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2515
+#: doc/rust.md:2509
 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 "
-"explicit using the ```copy``` keyword, changed to bind to a borrowed pointer "
-"by using the ```ref``` keyword, or to a mutable borrowed pointer using "
-"```ref mut```."
+"matched value (depending on the matched value's type).  This can be changed "
+"to bind to a borrowed pointer by using the ```ref``` keyword, or to a "
+"mutable borrowed pointer using ```ref mut```."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2526
+#: doc/rust.md:2520
 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 "
@@ -4778,19 +4746,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2530
+#: doc/rust.md:2524
 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:2533
+#: doc/rust.md:2527
 msgid "~~~~ # let x = 2;"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2540
+#: doc/rust.md:2534
 #, no-wrap
 msgid ""
 "let message = match x {\n"
@@ -4802,7 +4770,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2544
+#: doc/rust.md:2538
 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 "
@@ -4810,7 +4778,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2549
+#: doc/rust.md:2543
 msgid ""
 "Finally, match patterns can accept *pattern guards* to further refine the "
 "criteria for matching a case. Pattern guards appear after the pattern and "
@@ -4819,14 +4787,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2554
+#: doc/rust.md:2548
 msgid ""
 "~~~~ # let maybe_digit = Some(0); # fn process_digit(i: int) { } # fn "
 "process_other(i: int) { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2561
+#: doc/rust.md:2555
 #, no-wrap
 msgid ""
 "let message = match maybe_digit {\n"
@@ -4838,17 +4806,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2563
+#: doc/rust.md:2557
 msgid "### Return expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2567
+#: doc/rust.md:2561
 msgid "~~~~~~~~{.ebnf .gram} return_expr : \"return\" expr ? ; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2572
+#: doc/rust.md:2566
 msgid ""
 "Return expressions are denoted with the keyword `return`. Evaluating a "
 "`return` expression moves its argument into the output slot of the current "
@@ -4857,12 +4825,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2574
+#: doc/rust.md:2568
 msgid "An example of a `return` expression:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2583
+#: doc/rust.md:2577
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -4876,24 +4844,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2586
+#: doc/rust.md:2580
 msgid "# Type system"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2588
+#: doc/rust.md:2582
 msgid "## Types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2591
+#: doc/rust.md:2585
 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:2595
+#: doc/rust.md:2589
 msgid ""
 "Built-in types and type-constructors are tightly integrated into the "
 "language, in nontrivial ways that are not possible to emulate in user-"
@@ -4901,17 +4869,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2597
+#: doc/rust.md:2591
 msgid "### Primitive types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2599
+#: doc/rust.md:2593
 msgid "The primitive types are the following:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2605
+#: doc/rust.md:2599
 msgid ""
 "The \"unit\" type `()`, having the single \"unit\" value `()` (occasionally "
 "called \"nil\").  ^[The \"unit\" value `()` is *not* a sentinel \"null "
@@ -4922,32 +4890,32 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2605
+#: doc/rust.md:2599
 msgid "The boolean type `bool` with values `true` and `false`."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2605
+#: doc/rust.md:2599
 msgid "The machine types."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2605
+#: doc/rust.md:2599
 msgid "The machine-dependent integer and floating-point types."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2607
+#: doc/rust.md:2601
 msgid "#### Machine types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2609
+#: doc/rust.md:2603
 msgid "The machine types are the following:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2614
+#: doc/rust.md:2608
 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]$ "
@@ -4955,7 +4923,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2619
+#: doc/rust.md:2613
 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}), "
@@ -4964,19 +4932,19 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2622
+#: doc/rust.md:2616
 msgid ""
 "The IEEE 754-2008 `binary32` and `binary64` floating-point types: `f32` and "
 "`f64`, respectively."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2624
+#: doc/rust.md:2618
 msgid "#### Machine-dependent integer types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2629
+#: doc/rust.md:2623
 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 "
@@ -4985,7 +4953,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2634
+#: doc/rust.md:2628
 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 "
@@ -4994,12 +4962,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2637
+#: doc/rust.md:2631
 msgid "#### Machine-dependent floating point type"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2644
+#: doc/rust.md:2638
 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 "
@@ -5010,31 +4978,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2647
+#: doc/rust.md:2641
 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:2650
+#: doc/rust.md:2644
 msgid "### Textual types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2652
+#: doc/rust.md:2646
 msgid "The types `char` and `str` hold textual data."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2655
+#: doc/rust.md:2649
 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:2661
+#: doc/rust.md:2655
 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 "
@@ -5043,61 +5011,61 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2664
+#: doc/rust.md:2658
 msgid "### Tuple types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2667
+#: doc/rust.md:2661
 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:2670
+#: doc/rust.md:2664
 msgid "tuple elements cannot be mutable, unlike record fields"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:2670
+#: doc/rust.md:2664
 msgid ""
 "tuple elements are not named and can be accessed only by pattern-matching"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2674
+#: doc/rust.md:2668
 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:2677
+#: doc/rust.md:2671
 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:2679
+#: doc/rust.md:2673
 msgid "An example of a tuple type and its use:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2686
+#: doc/rust.md:2680
 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:2689
+#: doc/rust.md:2683
 msgid "### Vector types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2702
+#: doc/rust.md:2696
 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 "
@@ -5112,7 +5080,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2706
+#: doc/rust.md:2700
 msgid ""
 "Expressions producing vectors of definite size cannot be evaluated in a "
 "context expecting a vector of indefinite size; one must copy the definite-"
@@ -5120,30 +5088,30 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2708
+#: doc/rust.md:2702
 msgid "An example of a vector type and its use:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2714
+#: doc/rust.md:2708
 msgid ""
 "~~~~ let v: &[int] = &[7, 5, 3]; let i: int = v[2]; assert!(i == 3); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2717
+#: doc/rust.md:2711
 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:2720
+#: doc/rust.md:2714
 msgid "### Structure types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2725
+#: doc/rust.md:2719
 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, "
@@ -5152,14 +5120,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2727
+#: doc/rust.md:2721
 msgid ""
 "New instances of a `struct` can be constructed with a [struct expression]"
 "(#struct-expressions)."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2731
+#: doc/rust.md:2725
 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 "
@@ -5168,7 +5136,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2734
+#: doc/rust.md:2728
 msgid ""
 "The fields of a `struct` may be qualified by [visibility modifiers]"
 "(#visibility-modifiers), to restrict access to implementation-private data "
@@ -5176,14 +5144,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2736
+#: doc/rust.md:2730
 msgid ""
 "A _tuple struct_ type is just like a structure type, except that the fields "
 "are anonymous."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2739
+#: doc/rust.md:2733
 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]"
@@ -5191,12 +5159,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2741
+#: doc/rust.md:2735
 msgid "### Enumerated types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2746
+#: doc/rust.md:2740
 msgid ""
 "An *enumerated type* is a nominal, heterogeneous disjoint union type, "
 "denoted by the name of an [`enum` item](#enumerations).  ^[The `enum` type "
@@ -5205,7 +5173,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2749
+#: doc/rust.md:2743
 msgid ""
 "An [`enum` item](#enumerations) declares both the type and a number of "
 "*variant constructors*, each of which is independently named and takes an "
@@ -5213,33 +5181,33 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2752
+#: doc/rust.md:2746
 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:2754
+#: doc/rust.md:2748
 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:2757
+#: doc/rust.md:2751
 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:2760
+#: doc/rust.md:2754
 msgid "### Recursive types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2764
+#: doc/rust.md:2758
 msgid ""
 "Nominal types -- [enumerations](#enumerated-types) and [structures]"
 "(#structure-types) -- may be recursive.  That is, each `enum` constructor or "
@@ -5248,7 +5216,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2774
+#: doc/rust.md:2768
 #, no-wrap
 msgid ""
 "* Recursive types must include a nominal type in the recursion\n"
@@ -5263,12 +5231,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2776
+#: doc/rust.md:2770
 msgid "An example of a *recursive* type and its use:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2782
+#: doc/rust.md:2776
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -5279,17 +5247,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2785
+#: doc/rust.md:2779
 msgid "let a: List<int> = Cons(7, @Cons(13, @Nil)); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2788
+#: doc/rust.md:2782
 msgid "### Pointer types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2792
+#: doc/rust.md:2786
 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 "
@@ -5297,7 +5265,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2802
+#: doc/rust.md:2796
 #, no-wrap
 msgid ""
 "Managed pointers (`@`)\n"
@@ -5312,7 +5280,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2811
+#: doc/rust.md:2805
 #, no-wrap
 msgid ""
 "Owning pointers (`~`)\n"
@@ -5326,7 +5294,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2824
+#: doc/rust.md:2818
 #, no-wrap
 msgid ""
 "Borrowed pointers (`&`)\n"
@@ -5344,7 +5312,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2834
+#: doc/rust.md:2828
 #, no-wrap
 msgid ""
 "Raw pointers (`*`)\n"
@@ -5359,12 +5327,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2837
+#: doc/rust.md:2831
 msgid "### Function types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2841
+#: doc/rust.md:2835
 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 "
@@ -5372,12 +5340,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2843
+#: doc/rust.md:2837
 msgid "An example of a `fn` type:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2848
+#: doc/rust.md:2842
 #, no-wrap
 msgid ""
 "~~~~~~~~\n"
@@ -5387,24 +5355,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2850
+#: doc/rust.md:2844
 msgid "let mut x = add(5,7);"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2855
+#: doc/rust.md:2849
 msgid ""
 "type Binop<'self> = &'self fn(int,int) -> int; let bo: Binop = add; x = "
 "bo(5,7); ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2857
+#: doc/rust.md:2851
 msgid "### Object types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2864
+#: doc/rust.md:2858
 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 "
@@ -5417,7 +5385,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2869
+#: doc/rust.md:2863
 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`, "
@@ -5427,12 +5395,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2871
+#: doc/rust.md:2865
 msgid "An example of an object type:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2877
+#: doc/rust.md:2871
 #, no-wrap
 msgid ""
 "~~~~~~~~\n"
@@ -5443,7 +5411,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2881
+#: doc/rust.md:2875
 #, no-wrap
 msgid ""
 "impl Printable for int {\n"
@@ -5452,7 +5420,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2885
+#: doc/rust.md:2879
 #, no-wrap
 msgid ""
 "fn print(a: @Printable) {\n"
@@ -5461,7 +5429,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2890
+#: doc/rust.md:2884
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -5471,59 +5439,61 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2893
+#: doc/rust.md:2887
 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:2895
+#: doc/rust.md:2889
 msgid "### Type parameters"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2897
+#: doc/rust.md:2891
 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:2906
+#: doc/rust.md:2902
 #, no-wrap
 msgid ""
 "~~~~~~~\n"
-"fn map<A: Copy, B: Copy>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {\n"
-"   if xs.len() == 0 { return ~[]; }\n"
-"   let first: B = f(copy xs[0]);\n"
-"   let rest: ~[B] = map(f, xs.slice(1, xs.len()));\n"
-"   return ~[first] + rest;\n"
+"fn map<A: Clone, B: Clone>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {\n"
+"    if xs.len() == 0 {\n"
+"       return ~[];\n"
+"    }\n"
+"    let first: B = f(xs[0].clone());\n"
+"    let rest: ~[B] = map(f, xs.slice(1, xs.len()));\n"
+"    return ~[first] + rest;\n"
 "}\n"
 "~~~~~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2909
+#: doc/rust.md:2905
 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:2911
+#: doc/rust.md:2907
 msgid "### Self types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2915
+#: doc/rust.md:2911
 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:2920
+#: doc/rust.md:2916
 #, no-wrap
 msgid ""
 "~~~~~~~~\n"
@@ -5533,61 +5503,69 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2925
+#: doc/rust.md:2923
 #, no-wrap
 msgid ""
 "impl Printable for ~str {\n"
-"  fn make_string(&self) -> ~str { copy *self }\n"
+"    fn make_string(&self) -> ~str {\n"
+"        (*self).clone()\n"
+"    }\n"
 "}\n"
 "~~~~~~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2928
+#: doc/rust.md:2926
 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:2930
+#: doc/rust.md:2928
 msgid "## Type kinds"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2933
+#: doc/rust.md:2931
 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:2953
+#: doc/rust.md:2957
 #, no-wrap
 msgid ""
 "`Freeze`\n"
 "  : Types of this kind are deeply immutable;\n"
-"    they contain no mutable memory locations directly or indirectly via pointers.\n"
+"    they contain no mutable memory locations\n"
+"    directly or indirectly via pointers.\n"
 "`Send`\n"
 "  : Types of this kind can be safely sent between tasks.\n"
 "    This kind includes scalars, owning pointers, owned closures, and\n"
-"    structural types containing only other owned types. All `Send` types are `Static`.\n"
-"`Copy`\n"
-"  : This kind includes all types that can be copied. All types with\n"
-"    sendable kind are copyable, as are managed boxes, managed closures,\n"
-"    trait types, and structural types built out of these.\n"
-"    Types with destructors (types that implement `Drop`) can not implement `Copy`.\n"
+"    structural types containing only other owned types.\n"
+"    All `Send` types are `'static`.\n"
+"`'static`\n"
+"  : Types of this kind do not contain any borrowed pointers;\n"
+"    this can be a useful guarantee for code\n"
+"    that breaks borrowing assumptions\n"
+"    using [`unsafe` operations](#unsafe-functions).\n"
 "`Drop`\n"
-"  : This is not strictly a kind, but its presence interacts with kinds: the `Drop`\n"
-"    trait provides a single method `drop` that takes no parameters, and is run\n"
-"    when values of the type are dropped. Such a method is called a \"destructor\",\n"
-"    and are always executed in \"top-down\" order: a value is completely destroyed\n"
-"    before any of the values it owns run their destructors. Only `Send` types\n"
-"    that do not implement `Copy` can implement `Drop`.\n"
+"  : This is not strictly a kind,\n"
+"    but its presence interacts with kinds:\n"
+"    the `Drop` trait provides a single method `drop`\n"
+"    that takes no parameters,\n"
+"    and is run when values of the type are dropped.\n"
+"    Such a method is called a \"destructor\",\n"
+"    and are always executed in \"top-down\" order:\n"
+"    a value is completely destroyed\n"
+"    before any of the values it owns run their destructors.\n"
+"    Only `Send` types can implement `Drop`.\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2960
+#: doc/rust.md:2964
 #, no-wrap
 msgid ""
 "_Default_\n"
@@ -5599,67 +5577,36 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2963
+#: doc/rust.md:2967
 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:2965
-msgid ""
-"By default, type parameters do not carry any assumed kind-bounds at all."
-msgstr ""
-
-#. type: Plain text
-#: 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 "
-"function type parameters.  For example, this is not a valid program:"
-msgstr ""
-
 #. type: Plain text
 #: doc/rust.md:2973
-msgid "~~~~{.xfail-test} fn box<T>(x: T) -> @T { @x } ~~~~"
-msgstr ""
-
-#. type: Plain text
-#: 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:2980
-msgid "~~~~ fn box<T: Copy>(x: T) -> @T { @x } ~~~~"
-msgstr ""
-
-#. type: Plain text
-#: doc/rust.md:2985
-msgid ""
-"Calling this second version of `box` on a noncopyable type is not allowed. "
+"By default, type parameters do not carry any assumed kind-bounds at all.  "
 "When instantiating a type parameter, the kind bounds on the parameter are "
 "checked to be the same or narrower than the kind of the type that it is "
 "instantiated with."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2989
+#: doc/rust.md:2978
 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 "
+"the library.  Generic functions that send values bound the kind of these "
 "values to sendable."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2991
+#: doc/rust.md:2980
 msgid "# Memory and concurrency models"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2996
+#: doc/rust.md:2985
 msgid ""
 "Rust has a memory model centered around concurrently-executing _tasks_. Thus "
 "its memory model and its concurrency model are best discussed "
@@ -5668,7 +5615,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3001
+#: doc/rust.md:2990
 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 "
@@ -5677,12 +5624,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3003
+#: doc/rust.md:2992
 msgid "## Memory model"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3007
+#: doc/rust.md:2996
 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 "
@@ -5690,19 +5637,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3010
+#: doc/rust.md:2999
 msgid ""
 "Allocations in the stack consist of *slots*, and allocations in the heap "
 "consist of *boxes*."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3013
+#: doc/rust.md:3002
 msgid "### Memory allocation and lifetime"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3018
+#: doc/rust.md:3007
 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 "
@@ -5710,7 +5657,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3022
+#: doc/rust.md:3011
 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 "
@@ -5718,7 +5665,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3029
+#: doc/rust.md:3018
 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 "
@@ -5729,19 +5676,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3031
+#: doc/rust.md:3020
 msgid "### Memory ownership"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3034
+#: doc/rust.md:3023
 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:3041
+#: doc/rust.md:3030
 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 "
@@ -5752,14 +5699,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3044
+#: doc/rust.md:3033
 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:3050
+#: doc/rust.md:3039
 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 "
@@ -5769,38 +5716,38 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3053
+#: doc/rust.md:3042
 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:3056
+#: doc/rust.md:3045
 msgid "### Memory slots"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3058
+#: doc/rust.md:3047
 msgid "A task's stack contains slots."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3061
+#: doc/rust.md:3050
 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:3064
+#: doc/rust.md:3053
 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:3069
+#: doc/rust.md:3058
 msgid ""
 "Local variables are immutable unless declared with `let mut`.  The `mut` "
 "keyword applies to all local variables declared within that declaration (so "
@@ -5808,7 +5755,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3074
+#: doc/rust.md:3063
 msgid ""
 "Function parameters are immutable unless declared with `mut`. The `mut` "
 "keyword applies only to the following parameter (so `|mut x, y|` and `fn "
@@ -5817,7 +5764,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3080
+#: doc/rust.md:3069
 msgid ""
 "Local variables are not initialized when allocated; the entire frame worth "
 "of local variables are allocated at once, on frame-entry, in an "
@@ -5827,31 +5774,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3083
+#: doc/rust.md:3072
 msgid "### Memory boxes"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3086
+#: doc/rust.md:3075
 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:3088
+#: doc/rust.md:3077
 msgid ""
 "A _managed box_ type or value is constructed by the prefix *at* sigil `@`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3090
+#: doc/rust.md:3079
 msgid ""
 "An _owned box_ type or value is constructed by the prefix *tilde* sigil `~`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3095
+#: doc/rust.md:3084
 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 "
@@ -5860,41 +5807,39 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3099
+#: doc/rust.md:3086
 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 "
-"produces a pointer to the new allocation."
+"Owned box values exist in 1:1 correspondence with their heap allocation."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3102
+#: doc/rust.md:3089
 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:3107
+#: doc/rust.md:3094
 msgid "~~~~~~~~ let x: @int = @10; let x: ~int = ~10; ~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3110
+#: doc/rust.md:3097
 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:3116
+#: doc/rust.md:3103
 msgid ""
 "~~~~~~~~ struct Foo { y: int } let x = @Foo{y: 10}; assert!(x.y == 10); "
 "~~~~~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3122
+#: doc/rust.md:3109
 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 "
@@ -5904,33 +5849,33 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3125
+#: doc/rust.md:3112
 msgid "copying box values (`x = y`)"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3125
+#: doc/rust.md:3112
 msgid "passing box values to functions (`f(x,y)`)"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3128
+#: doc/rust.md:3115
 msgid ""
 "An example of an explicit-dereference operation performed on box values:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3132
+#: doc/rust.md:3119
 msgid "~~~~~~~~ fn takes_boxed(b: @int) { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3135
+#: doc/rust.md:3122
 msgid "fn takes_unboxed(b: int) { }"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3142
+#: doc/rust.md:3129
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -5942,12 +5887,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3144
+#: doc/rust.md:3131
 msgid "## Tasks"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3152
+#: doc/rust.md:3139
 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 "
@@ -5958,7 +5903,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3167
+#: doc/rust.md:3154
 msgid ""
 "Multiple Rust tasks may coexist in a single operating-system process.  The "
 "runtime scheduler maps tasks to a certain number of operating-system "
@@ -5977,12 +5922,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3170
+#: doc/rust.md:3157
 msgid "### Communication between tasks"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3175
+#: doc/rust.md:3162
 msgid ""
 "Rust tasks are isolated and generally unable to interfere with one another's "
 "memory directly, except through [`unsafe` code](#unsafe-functions).  All "
@@ -5991,33 +5936,33 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3178
+#: doc/rust.md:3165
 msgid ""
 "Inter-task communication and co-ordination facilities are provided in the "
 "standard library.  These include:"
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:3182
+#: doc/rust.md:3169
 msgid ""
 "synchronous and asynchronous communication channels with various "
 "communication topologies"
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:3182
+#: doc/rust.md:3169
 msgid ""
 "read-only and read-write shared variables with various safe mutual exclusion "
 "patterns"
 msgstr ""
 
 #. type: Bullet: '  - '
-#: doc/rust.md:3182
+#: doc/rust.md:3169
 msgid "simple locks and semaphores"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3187
+#: doc/rust.md:3174
 msgid ""
 "When such facilities carry values, the values are restricted to the [`Send` "
 "type-kind](#type-kinds).  Restricting communication interfaces to this kind "
@@ -6028,39 +5973,39 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3190
+#: doc/rust.md:3177
 msgid "### Task lifecycle"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3193
+#: doc/rust.md:3180
 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:3198
+#: doc/rust.md:3185
 msgid "running"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3198
+#: doc/rust.md:3185
 msgid "blocked"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3198
+#: doc/rust.md:3185
 msgid "failing"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3198
+#: doc/rust.md:3185
 msgid "dead"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3202
+#: doc/rust.md:3189
 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 "
@@ -6068,7 +6013,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3208
+#: doc/rust.md:3195
 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 "
@@ -6078,7 +6023,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3227
+#: doc/rust.md:3214
 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!()` "
@@ -6101,7 +6046,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3231
+#: doc/rust.md:3218
 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 "
@@ -6109,12 +6054,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3234
+#: doc/rust.md:3221
 msgid "### Task scheduling"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3238
+#: doc/rust.md:3225
 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 "
@@ -6122,7 +6067,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3242
+#: doc/rust.md:3229
 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-"
@@ -6130,12 +6075,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3245
+#: doc/rust.md:3232
 msgid "# Runtime services, linkage and debugging"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3252
+#: doc/rust.md:3239
 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-"
@@ -6145,19 +6090,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3254
+#: doc/rust.md:3241
 msgid ""
 "> **Note:** The runtime library will merge with the `std` library in future "
 "versions of Rust."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3256
+#: doc/rust.md:3243
 msgid "### Memory allocation"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3262
+#: doc/rust.md:3249
 msgid ""
 "The runtime memory-management system is based on a _service-provider "
 "interface_, through which the runtime requests blocks of memory from its "
@@ -6167,7 +6112,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3266
+#: doc/rust.md:3253
 msgid ""
 "The runtime memory-management system, in turn, supplies Rust tasks with "
 "facilities for allocating, extending and releasing stacks, as well as "
@@ -6175,12 +6120,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3268
+#: doc/rust.md:3255
 msgid "### Built in types"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3272
+#: doc/rust.md:3259
 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, "
@@ -6188,19 +6133,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3275
+#: doc/rust.md:3262
 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:3279
+#: doc/rust.md:3266
 msgid "### Task scheduling and communication"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3285
+#: doc/rust.md:3272
 msgid ""
 "The runtime provides code to manage inter-task communication.  This includes "
 "the system of task-lifecycle state transitions depending on the contents of "
@@ -6210,12 +6155,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3288
+#: doc/rust.md:3275
 msgid "### Logging system"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3292
+#: doc/rust.md:3279
 msgid ""
 "The runtime contains a system for directing [logging expressions](#log-"
 "expressions) to a logging console and/or internal logging buffers. Logging "
@@ -6223,7 +6168,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3299
+#: doc/rust.md:3286
 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 "
@@ -6234,7 +6179,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3307
+#: doc/rust.md:3294
 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 "
@@ -6245,7 +6190,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3313
+#: doc/rust.md:3300
 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` "
@@ -6255,17 +6200,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3318
+#: doc/rust.md:3305
 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, "
-"with the extension removed. In that case, to turn on logging for a program "
-"compiled from, e.g. `helloworld.rs`, `RUST_LOG` should be set to "
-"`helloworld`."
+"Note that when compiling source files that don't specify a crate name the "
+"crate is given a default name that matches the source file, with the "
+"extension removed. In that case, to turn on logging for a program compiled "
+"from, e.g. `helloworld.rs`, `RUST_LOG` should be set to `helloworld`."
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3322
+#: doc/rust.md:3309
 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 "
@@ -6273,7 +6217,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3327
+#: doc/rust.md:3314
 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, "
@@ -6282,84 +6226,84 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::mem` Memory management"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::comm` Messaging and task communication"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::task` Task management"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::dom` Task scheduling"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::trace` Unused"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::cache` Type descriptor cache"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::upcall` Compiler-generated runtime calls"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::timer` The scheduler timer"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::gc` Garbage collection"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::stdlib` Functions used directly by the standard library"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::kern` The runtime kernel"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::backtrace` Log a backtrace on task failure"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3341
+#: doc/rust.md:3328
 msgid "`::rt::callback` Unused"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3343
+#: doc/rust.md:3330
 msgid "#### Logging Expressions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3346
+#: doc/rust.md:3333
 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:3355
+#: doc/rust.md:3342
 #, no-wrap
 msgid ""
 "```rust\n"
@@ -6373,13 +6317,13 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3357
+#: doc/rust.md:3344
 msgid ""
 "These four log levels correspond to levels 1-4, as controlled by `RUST_LOG`:"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3364
+#: doc/rust.md:3351
 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\\\"\" "
@@ -6387,28 +6331,28 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3366
+#: doc/rust.md:3353
 msgid "# Appendix: Rationales and design tradeoffs"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3368
+#: doc/rust.md:3355
 #, no-wrap
 msgid "*TODO*.\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3370
+#: doc/rust.md:3357
 msgid "# Appendix: Influences and further references"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3372
+#: doc/rust.md:3359
 msgid "## Influences"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3381
+#: doc/rust.md:3368
 msgid ""
 "> The essential problem that must be solved in making a fault-tolerant > "
 "software system is therefore that of fault-isolation. Different programmers "
@@ -6419,7 +6363,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3393
+#: doc/rust.md:3380
 msgid ""
 "> In our approach, all data is private to some process, and processes can > "
 "only communicate through communications channels. *Security*, as used > in "
@@ -6431,7 +6375,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3401
+#: doc/rust.md:3388
 msgid ""
 "> Concurrent and applicative programming complement each other. The > "
 "ability to send messages on channels provides I/O without side effects, > "
@@ -6440,7 +6384,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3408
+#: doc/rust.md:3395
 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 "
@@ -6450,7 +6394,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3412
+#: doc/rust.md:3399
 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 "
@@ -6458,7 +6402,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3416
+#: doc/rust.md:3403
 msgid ""
 "The Erlang (1987) language, developed by Joe Armstrong, Robert Virding, "
 "Claes Wikstr&ouml;m, Mike Williams and others in their group at the Ericsson "
@@ -6466,7 +6410,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3421
+#: doc/rust.md:3408
 msgid ""
 "The Sather (1990) language, developed by Stephen Omohundro, Chu-Cheow Lim, "
 "Heinz Schmidt and others in their group at The International Computer "
@@ -6475,7 +6419,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3426
+#: doc/rust.md:3413
 msgid ""
 "The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These languages "
 "were developed by Rob Pike, Phil Winterbottom, Sean Dorward and others in "
@@ -6484,7 +6428,7 @@ msgid ""
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3430
+#: doc/rust.md:3417
 msgid ""
 "The Napier (1985) and Napier88 (1988) family. These languages were developed "
 "by Malcolm Atkinson, Ron Morrison and others in their group at the "
@@ -6492,47 +6436,47 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:3432
+#: doc/rust.md:3419
 msgid ""
 "Additional specific influences can be seen from the following languages:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The stack-growth implementation of Go."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The structural algebraic types and compilation manager of SML."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The attribute and assembly systems of C#."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The references and deterministic destructor system of C++."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The memory region systems of the ML Kit and Cyclone."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The typeclass system of Haskell."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The lexical identifier rule of Python."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rust.md:3440
+#: doc/rust.md:3427
 msgid "The block syntax of Ruby."
 msgstr ""
index 134aa56b3dab48ca8154096594c19faf987e3ef4..9c4fa4b6c2a9d7ed8c289b19ba3b51ac6295d0e5 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-07-30 07:07+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -160,7 +160,7 @@ msgid "# Package identifiers"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:79
+#: doc/rustpkg.md:87
 msgid ""
 "A package identifier identifies a package uniquely.  A package can be stored "
 "in a workspace on the local file system, or on a remote Web server, in which "
@@ -169,51 +169,59 @@ msgid ""
 "github.com/mozilla/rust`.  A package ID can also specify a version, like: "
 "`github.com/mozilla/rust#0.3`.  In this case, `rustpkg` will check that the "
 "repository `github.com/mozilla/rust` has a tag named `0.3`, and report an "
-"error otherwise."
+"error otherwise.  A package ID can also specify a particular revision of a "
+"repository, like: `github.com/mozilla/rust#release-0.7`.  When the refspec "
+"(portion of the package ID after the `#`) can't be parsed as a decimal "
+"number, rustpkg passes the refspec along to the version control system "
+"without interpreting it.  rustpkg also interprets any dependencies on such a "
+"package ID literally (as opposed to versions, where a newer version "
+"satisfies a dependency on an older version).  Thus, `github.com/mozilla/"
+"rust#5c4cd30f80` is also a valid package ID, since git can deduce that "
+"5c4cd30f80 refers to a revision of the desired repository."
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:81
+#: doc/rustpkg.md:89
 msgid "## Source files"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:83
+#: doc/rustpkg.md:91
 msgid ""
 "rustpkg searches for four different fixed filenames in order to determine "
 "the crates to build:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rustpkg.md:88
+#: doc/rustpkg.md:96
 msgid "`main.rs`: Assumed to be a main entry point for building an executable."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rustpkg.md:88
+#: doc/rustpkg.md:96
 msgid "`lib.rs`: Assumed to be a library crate."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rustpkg.md:88
+#: doc/rustpkg.md:96
 msgid ""
 "`test.rs`: Assumed to contain tests declared with the `#[test]` attribute."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/rustpkg.md:88
+#: doc/rustpkg.md:96
 msgid ""
 "`bench.rs`: Assumed to contain benchmarks declared with the `#[bench]` "
 "attribute."
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:90
+#: doc/rustpkg.md:98
 msgid "## Versions"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:97
+#: doc/rustpkg.md:105
 msgid ""
 "`rustpkg` packages do not need to declare their versions with an attribute "
 "inside one of the source files, because `rustpkg` infers it from the version "
@@ -224,12 +232,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:99
+#: doc/rustpkg.md:107
 msgid "# Dependencies"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:103
+#: doc/rustpkg.md:111
 msgid ""
 "rustpkg infers dependencies from `extern mod` directives.  Thus, there "
 "should be no need to pass a `-L` flag to rustpkg to tell it where to find a "
@@ -238,12 +246,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:105
+#: doc/rustpkg.md:113
 msgid "# Custom build scripts"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:109
+#: doc/rustpkg.md:117
 msgid ""
 "A file called `pkg.rs` at the root level in a workspace is called a *package "
 "script*.  If a package script exists, rustpkg executes it to build the "
@@ -251,7 +259,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:113
+#: doc/rustpkg.md:121
 msgid ""
 "Inside `pkg.rs`, it's possible to call back into rustpkg to finish up the "
 "build.  `rustpkg::api` contains functions to build, install, or clean "
@@ -260,17 +268,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:115
+#: doc/rustpkg.md:123
 msgid "# Command reference"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:117
+#: doc/rustpkg.md:125
 msgid "## build"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:123
+#: doc/rustpkg.md:131
 msgid ""
 "`rustpkg build foo` searches for a package with ID `foo` and builds it in "
 "any workspace(s) where it finds one.  Supposing such packages are found in "
@@ -279,22 +287,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:125
+#: doc/rustpkg.md:133
 msgid "## clean"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:127
+#: doc/rustpkg.md:135
 msgid "`rustpkg clean foo` deletes the contents of `foo`'s `build` directory."
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:129
+#: doc/rustpkg.md:137
 msgid "## install"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:133
+#: doc/rustpkg.md:141
 msgid ""
 "`rustpkg install foo` builds the libraries and/or executables that are "
 "targets for `foo`, and then installs them either into `foo`'s `lib` and "
@@ -303,12 +311,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:135
+#: doc/rustpkg.md:143
 msgid "## test"
 msgstr ""
 
 #. type: Plain text
-#: doc/rustpkg.md:137
+#: doc/rustpkg.md:145
 msgid ""
 "`rustpkg test foo` builds `foo`'s `test.rs` file if necessary, then runs the "
 "resulting test executable."
index 816b3eeea61e61e88611d1c6bd92bbda4d0c2547..4678d3ae366023c9957b760a2e0af14ffcca6a6c 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-07-22 23:37+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -24,7 +24,7 @@ msgid "# Introduction"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72
+#: doc/tutorial.md:1108 doc/tutorial-borrowed-ptr.md:72
 msgid "Now we can call `compute_distance()` in various ways:"
 msgstr ""
 
@@ -60,8 +60,8 @@ msgstr ""
 msgid ""
 "Although borrowed pointers have rather elaborate theoretical underpinnings "
 "(region pointers), the core concepts will be familiar to anyone who has "
-"worked with C or C++. Therefore, the best way to explain how they are "
-"usedand their limitationsis probably just to work through several examples."
+"worked with C or C++. Therefore, the best way to explain how they are used—"
+"and their limitations—is probably just to work through several examples."
 msgstr ""
 
 #. type: Plain text
@@ -115,7 +115,7 @@ msgid ""
 "any two points, no matter where they were stored. For example, we might like "
 "to compute the distance between `on_the_stack` and `managed_box`, or between "
 "`managed_box` and `owned_box`. One option is to define a function that takes "
-"two arguments of type `Point`that is, it takes the points by value. But if "
+"two arguments of type `Point`that is, it takes the points by value. But if "
 "we define it this way, calling the function will cause the points to be "
 "copied. For points, this is probably not so bad, but often copies are "
 "expensive. Worse, if the data type contains mutable fields, copying can "
@@ -313,8 +313,8 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial-borrowed-ptr.md:186
 msgid ""
-"Weve seen a few examples so far of borrowing heap boxes, both managed and "
-"owned. Up till this point, weve glossed over issues of safety. As stated in "
+"Weve seen a few examples so far of borrowing heap boxes, both managed and "
+"owned. Up till this point, weve glossed over issues of safety. As stated in "
 "the introduction, at runtime a borrowed pointer is simply a pointer, nothing "
 "more. Therefore, avoiding C's problems with dangling pointers requires a "
 "compile-time safety check."
@@ -626,7 +626,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial-borrowed-ptr.md:376
 msgid ""
-"As an example, lets look at the following `shape` type that can represent "
+"As an example, lets look at the following `shape` type that can represent "
 "both rectangles and circles:"
 msgstr ""
 
@@ -792,7 +792,7 @@ msgstr ""
 #: doc/tutorial-borrowed-ptr.md:483
 msgid ""
 "So far, all of the examples we have looked at, use borrowed pointers in a "
-"downward direction. That is, a method or code block creates a borrowed "
+"“downward” direction. That is, a method or code block creates a borrowed "
 "pointer, then uses it within the same scope. It is also possible to return "
 "borrowed pointers as the result of a function, but as we'll see, doing so "
 "requires some explicit annotation."
@@ -844,7 +844,7 @@ msgstr ""
 msgid ""
 "Named lifetimes that appear in function signatures are conceptually the same "
 "as the other lifetimes we have seen before, but they are a bit abstract: "
-"they dont refer to a specific expression within `get_x()`, but rather to "
+"they dont refer to a specific expression within `get_x()`, but rather to "
 "some expression within the *caller of `get_x()`*.  The lifetime `r` is "
 "actually a kind of *lifetime parameter*: it is defined by the caller to "
 "`get_x()`, just as the value for the parameter `p` is defined by that caller."
@@ -862,7 +862,7 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial-borrowed-ptr.md:526
 msgid ""
-"To emphasize this point, lets look at a variation on the example, this time "
+"To emphasize this point, lets look at a variation on the example, this time "
 "one that does not compile:"
 msgstr ""
 
index 3435a51dbeff15a5d93247a3a3161f58b11b0a65..a93d5801dccf8b26a68426a672516dc5830dbfe1 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-08-05 19:40+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -242,40 +242,41 @@ msgstr ""
 #: doc/tutorial-container.md:112
 msgid ""
 "Containers implement iteration over the contained elements by returning an "
-"iterator object. For example, vector slices have four iterators available:"
+"iterator object. For example, vector slices several iterators available:"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial-container.md:117
-msgid "`vector.iter()`, for immutable references to the elements"
+#: doc/tutorial-container.md:116
+msgid "`iter()` and `rev_iter()`, for immutable references to the elements"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial-container.md:117
-msgid "`vector.mut_iter()`, for mutable references to the elements"
+#: doc/tutorial-container.md:116
+msgid ""
+"`mut_iter()` and `mut_rev_iter()`, for mutable references to the elements"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial-container.md:117
+#: doc/tutorial-container.md:116
 msgid ""
-"`vector.rev_iter()`, for immutable references to the elements in reverse "
-"order"
+"`consume_iter()` and `consume_rev_iter`, to move the elements out by-value"
 msgstr ""
 
-#. type: Bullet: '* '
-#: doc/tutorial-container.md:117
+#. type: Plain text
+#: doc/tutorial-container.md:119
 msgid ""
-"`vector.mut_rev_iter()`, for mutable references to the elements in reverse "
-"order"
+"A typical mutable container will implement at least `iter()`, `mut_iter()` "
+"and `consume_iter()` along with the reverse variants if it maintains an "
+"order."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:119
+#: doc/tutorial-container.md:121
 msgid "### Freezing"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:123
+#: doc/tutorial-container.md:125
 msgid ""
 "Unlike most other languages with external iterators, Rust has no *iterator "
 "invalidation*. As long an iterator is still in scope, the compiler will "
@@ -283,7 +284,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:128
+#: doc/tutorial-container.md:130
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -293,7 +294,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:134
+#: doc/tutorial-container.md:136
 #, no-wrap
 msgid ""
 "    // the vector is frozen for this scope, the compiler will statically\n"
@@ -304,19 +305,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:137
+#: doc/tutorial-container.md:139
 msgid ""
 "These semantics are due to most container iterators being implemented with "
 "`&` and `&mut`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:139
+#: doc/tutorial-container.md:141
 msgid "## Iterator adaptors"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:143
+#: doc/tutorial-container.md:145
 msgid ""
 "The `IteratorUtil` trait implements common algorithms as methods extending "
 "every `Iterator` implementation. For example, the `fold` method will "
@@ -324,28 +325,28 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:149
+#: doc/tutorial-container.md:151
 msgid ""
 "~~~ let xs = [1, 9, 2, 3, 14, 12]; let result = xs.iter().fold(0, |"
 "accumulator, item| accumulator - *item); assert_eq!(result, -41); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:151
+#: doc/tutorial-container.md:153
 msgid ""
 "Some adaptors return an adaptor object implementing the `Iterator` trait "
 "itself:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:158
+#: doc/tutorial-container.md:160
 msgid ""
 "~~~ let xs = [1, 9, 2, 3, 14, 12]; let ys = [5, 2, 1, 8]; let sum = xs."
 "iter().chain_(ys.iter()).fold(0, |a, b| a + *b); assert_eq!(sum, 57); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:162
+#: doc/tutorial-container.md:164
 msgid ""
 "Note that some adaptors like the `chain_` method above use a trailing "
 "underscore to work around an issue with method resolve. The underscores will "
@@ -353,17 +354,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:164
+#: doc/tutorial-container.md:166
 msgid "## For loops"
 msgstr ""
 
 #. type: Plain text
 #: doc/tutorial-container.md:168
 msgid ""
-"The `for` loop syntax is currently in transition, and will switch from the "
-"old closure-based iteration protocol to iterator objects. For now, the "
-"`advance` adaptor is required as a compatibility shim to use iterators with "
-"for loops."
+"The `for` keyword can be used as sugar for iterating through any iterator:"
 msgstr ""
 
 #. type: Plain text
@@ -419,7 +417,7 @@ msgstr ""
 msgid ""
 "// print out the pairs of elements up to (&3, &\"baz\")\n"
 "for (x, y) in it {\n"
-"    println(fmt!(\"%d %s\", *x, *y));\n"
+"    printfln!(\"%d %s\", *x, *y);\n"
 msgstr ""
 
 #. type: Plain text
@@ -435,8 +433,8 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial-container.md:204
 msgid ""
-"// yield and print the last pair from the iterator println(fmt!(\"last: %?"
-"\", it.next()));"
+"// yield and print the last pair from the iterator printfln!(\"last: %?\", "
+"it.next());"
 msgstr ""
 
 #. type: Plain text
@@ -483,8 +481,8 @@ msgstr ""
 #, no-wrap
 msgid ""
 "~~~\n"
-"impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {\n"
-"    pub fn from_iterator(iterator: &mut T) -> ~[A] {\n"
+"impl<A> FromIterator<A> for ~[A] {\n"
+"    pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {\n"
 "        let (lower, _) = iterator.size_hint();\n"
 "        let mut xs = with_capacity(lower);\n"
 "        for x in iterator {\n"
@@ -577,9 +575,9 @@ 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)`"
+"~~~ let xs = [1, 2, 3, 4, 5, 6]; let mut it = xs.iter(); printfln!(\"%?\", "
+"it.next()); // prints `Some(&1)` printfln!(\"%?\", it.next()); // prints "
+"`Some(&2)` printfln!(\"%?\", it.next_back()); // prints `Some(&6)`"
 msgstr ""
 
 #. type: Plain text
@@ -588,14 +586,88 @@ msgstr ""
 msgid ""
 "// prints `5`, `4` and `3`\n"
 "for &x in it.invert() {\n"
-"    println(fmt!(\"%?\", x))\n"
+"    printfln!(\"%?\", x)\n"
 "}\n"
 "~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-container.md:308
+#: doc/tutorial-container.md:309
 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 ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:312
+msgid ""
+"The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are "
+"`DoubleEndedIterator` implementations if the underlying iterators are."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:317
+msgid ""
+"~~~ let xs = [1, 2, 3, 4]; let ys = [5, 6, 7, 8]; let mut it = xs.iter()."
+"chain_(ys.iter()).transform(|&x| x * 2);"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:319
+msgid "printfln!(\"%?\", it.next()); // prints `Some(2)`"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:325
+#, no-wrap
+msgid ""
+"// prints `16`, `14`, `12`, `10`, `8`, `6`, `4`\n"
+"for x in it.invert() {\n"
+"    printfln!(\"%?\", x);\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:327
+msgid "## Random-access iterators"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:331
+msgid ""
+"The `RandomAccessIterator` trait represents an iterator offering random "
+"access to the whole range. The `indexable` method retrieves the number of "
+"elements accessible with the `idx` method."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:334
+msgid ""
+"The `chain_` adaptor is an implementation of `RandomAccessIterator` if the "
+"underlying iterators are."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:343
+msgid ""
+"~~~ let xs = [1, 2, 3, 4, 5]; let ys = ~[7, 9, 11]; let mut it = xs.iter()."
+"chain_(ys.iter()); printfln!(\"%?\", it.idx(0)); // prints `Some(&1)` "
+"printfln!(\"%?\", it.idx(5)); // prints `Some(&7)` printfln!(\"%?\", it."
+"idx(7)); // prints `Some(&11)` printfln!(\"%?\", it.idx(8)); // prints `None`"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:348
+msgid ""
+"// yield two elements from the beginning, and one from the end it.next(); it."
+"next(); it.next_back();"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-container.md:352
+msgid ""
+"printfln!(\"%?\", it.idx(0)); // prints `Some(&3)` printfln!(\"%?\", it."
+"idx(4)); // prints `Some(&9)` printfln!(\"%?\", it.idx(6)); // prints `None` "
+"~~~"
+msgstr ""
index c43b6652331ff0282cd4efa1867fd67c3ede6b05..97d3a44d7088437ff5d40a598d45db8a27c7fdd1 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-08-10 07:44+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -24,7 +24,7 @@ msgid "# Introduction"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:876 doc/tutorial-ffi.md:143
+#: doc/tutorial.md:868 doc/tutorial-ffi.md:143
 msgid "# Destructors"
 msgstr ""
 
@@ -446,11 +446,87 @@ msgstr ""
 
 #. type: Plain text
 #: doc/tutorial-ffi.md:232
+msgid "# Accessing foreign globals"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:236
+msgid ""
+"Foreign APIs often export a global variable which could do something like "
+"track global state. In order to access these variables, you declare them in "
+"`extern` blocks with the `static` keyword:"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:239
+msgid "~~~{.xfail-test} use std::libc;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:244
+#, no-wrap
+msgid ""
+"#[link_args = \"-lreadline\"]\n"
+"extern {\n"
+"    static rl_readline_version: libc::c_int;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:250
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    println(fmt!(\"You have readline version %d installed.\",\n"
+"                 rl_readline_version as int));\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:254
+msgid ""
+"Alternatively, you may need to alter global state provided by a foreign "
+"interface. To do this, statics can be declared with `mut` so rust can mutate "
+"them."
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:258
+msgid "~~~{.xfail-test} use std::libc; use std::ptr;"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:263
+#, no-wrap
+msgid ""
+"#[link_args = \"-lreadline\"]\n"
+"extern {\n"
+"    static mut rl_prompt: *libc::c_char;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:272
+#, no-wrap
+msgid ""
+"fn main() {\n"
+"    do \"[my-awesome-shell] $\".as_c_str |buf| {\n"
+"        unsafe { rl_prompt = buf; }\n"
+"        // get a line, process it\n"
+"        unsafe { rl_prompt = ptr::null(); }\n"
+"    }\n"
+"}\n"
+"~~~\n"
+msgstr ""
+
+#. type: Plain text
+#: doc/tutorial-ffi.md:274
 msgid "# Foreign calling conventions"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:237
+#: doc/tutorial-ffi.md:279
 msgid ""
 "Most foreign code exposes a C ABI, and Rust uses the platform's C calling "
 "convention by default when calling foreign functions. Some foreign "
@@ -460,7 +536,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:246
+#: doc/tutorial-ffi.md:288
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -474,7 +550,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:250
+#: doc/tutorial-ffi.md:292
 msgid ""
 "The `abi` attribute applies to a foreign module (it cannot be applied to a "
 "single function within a module), and must be either `\"cdecl\"` or `"
@@ -482,12 +558,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:252
+#: doc/tutorial-ffi.md:294
 msgid "# Interoperability with foreign code"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:256
+#: doc/tutorial-ffi.md:298
 msgid ""
 "Rust guarantees that the layout of a `struct` is compatible with the "
 "platform's representation in C.  A `#[packed]` attribute is available, which "
@@ -496,7 +572,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:263
+#: doc/tutorial-ffi.md:305
 msgid ""
 "Rust's owned and managed boxes use non-nullable pointers as handles which "
 "point to the contained object. However, they should not be manually created "
@@ -508,7 +584,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:268
+#: doc/tutorial-ffi.md:310
 msgid ""
 "Vectors and strings share the same basic memory layout, and utilities are "
 "available in the `vec` and `str` modules for working with C APIs. Strings "
@@ -518,7 +594,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-ffi.md:270
+#: doc/tutorial-ffi.md:312
 msgid ""
 "The standard library includes type aliases and function definitions for the "
 "C standard library in the `libc` module, and Rust links against `libc` and "
index 5487ab5ebbd8c3d8667ee8952bded2f835b3b4c3..1b540ea8b1e85eb3ade8fb8df0a02261853f17d0 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-07-22 23:37+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -24,7 +24,7 @@ msgid "# Introduction"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:2033 doc/rust.md:2174 doc/tutorial-macros.md:323
+#: doc/rust.md:2136 doc/rust.md:2223 doc/tutorial-macros.md:323
 msgid "~~~~"
 msgstr ""
 
index ff1f25f83b32576f9c7f0621f872ec782e0bfa55..893b3dc149193fd6f39eebada743b7fce959861a 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-08-08 22:27+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -24,7 +24,7 @@ msgid "# Introduction"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1849 doc/tutorial-tasks.md:649
+#: doc/rust.md:1952 doc/tutorial-tasks.md:648
 msgid "# } ~~~~"
 msgstr ""
 
@@ -249,15 +249,15 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:124
-msgid "~~~ # use std::io::print; # use std::task::spawn; # use std::int;"
+#: doc/tutorial-tasks.md:123
+msgid "~~~ # use std::io::print; # use std::task::spawn;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:131
+#: doc/tutorial-tasks.md:130
 #, no-wrap
 msgid ""
-"for int::range(0, 20) |child_task_number| {\n"
+"for child_task_number in range(0, 20) {\n"
 "    do spawn {\n"
 "       print(fmt!(\"I am child number %d\\n\", child_task_number));\n"
 "    }\n"
@@ -266,12 +266,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:133
+#: doc/tutorial-tasks.md:132
 msgid "## Communication"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:138
+#: doc/tutorial-tasks.md:137
 msgid ""
 "Now that we have spawned a new task, it would be nice if we could "
 "communicate with it. Recall that Rust does not have shared mutable state, so "
@@ -280,7 +280,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:143
+#: doc/tutorial-tasks.md:142
 msgid ""
 "A pipe is simply a pair of endpoints: one for sending messages and another "
 "for receiving messages. Pipes are low-level communication building-blocks "
@@ -289,7 +289,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:149
+#: doc/tutorial-tasks.md:148
 msgid ""
 "The simplest way to create a pipe is to use the `pipes::stream` function to "
 "create a `(Port, Chan)` pair. In Rust parlance, a *channel* is a sending "
@@ -298,17 +298,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:153
+#: doc/tutorial-tasks.md:152
 msgid "~~~~ # use std::task::spawn; # use std::comm::{stream, Port, Chan};"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:155
+#: doc/tutorial-tasks.md:154
 msgid "let (port, chan): (Port<int>, Chan<int>) = stream();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:160
+#: doc/tutorial-tasks.md:159
 #, no-wrap
 msgid ""
 "do spawn || {\n"
@@ -318,7 +318,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:166
+#: doc/tutorial-tasks.md:165
 msgid ""
 "some_other_expensive_computation(); let result = port.recv(); # fn "
 "some_expensive_computation() -> int { 42 } # fn "
@@ -326,7 +326,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:171
+#: doc/tutorial-tasks.md:170
 msgid ""
 "Let's examine this example in detail. First, the `let` statement creates a "
 "stream for sending and receiving integers (the left-hand side of the `let`, "
@@ -335,14 +335,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:176
+#: doc/tutorial-tasks.md:175
 msgid ""
 "~~~~ # use std::comm::{stream, Chan, Port}; let (port, chan): (Port<int>, "
 "Chan<int>) = stream(); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:180
+#: doc/tutorial-tasks.md:179
 msgid ""
 "The child task will use the channel to send data to the parent task, which "
 "will wait to receive the data on the port. The next statement spawns the "
@@ -350,7 +350,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:191
+#: doc/tutorial-tasks.md:190
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -366,7 +366,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:197
+#: doc/tutorial-tasks.md:196
 msgid ""
 "Notice that the creation of the task closure transfers `chan` to the child "
 "task implicitly: the closure captures `chan` in its environment. Both `Chan` "
@@ -376,14 +376,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:201
+#: doc/tutorial-tasks.md:200
 msgid ""
 "Finally, the parent continues with some other expensive computation, then "
 "waits for the child's result to arrive on the port:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:210
+#: doc/tutorial-tasks.md:209
 msgid ""
 "~~~~ # use std::comm::{stream}; # fn some_other_expensive_computation() {} # "
 "let (port, chan) = stream::<int>(); # chan.send(0); "
@@ -391,7 +391,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:216
+#: doc/tutorial-tasks.md:215
 msgid ""
 "The `Port` and `Chan` pair created by `stream` enables efficient "
 "communication between a single sender and a single receiver, but multiple "
@@ -401,7 +401,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:222
+#: doc/tutorial-tasks.md:221
 msgid ""
 "~~~ {.xfail-test} # use std::task::{spawn}; # use std::comm::{stream, Port, "
 "Chan}; # fn some_expensive_computation() -> int { 42 } let (port, chan) = "
@@ -409,7 +409,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:226
+#: doc/tutorial-tasks.md:225
 #, no-wrap
 msgid ""
 "do spawn {\n"
@@ -418,7 +418,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:233
+#: doc/tutorial-tasks.md:232
 #, no-wrap
 msgid ""
 "// ERROR! The previous spawn statement already owns the channel,\n"
@@ -430,29 +430,27 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:236
+#: doc/tutorial-tasks.md:235
 msgid ""
 "Instead we can use a `SharedChan`, a type that allows a single `Chan` to be "
 "shared by multiple senders."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:241
-msgid ""
-"~~~ # use std::task::spawn; # use std::comm::{stream, SharedChan}; # use "
-"std::uint;"
+#: doc/tutorial-tasks.md:239
+msgid "~~~ # use std::task::spawn; # use std::comm::{stream, SharedChan};"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:244
+#: doc/tutorial-tasks.md:242
 msgid "let (port, chan) = stream(); let chan = SharedChan::new(chan);"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:252
+#: doc/tutorial-tasks.md:250
 #, no-wrap
 msgid ""
-"for uint::range(0, 3) |init_val| {\n"
+"for init_val in range(0u, 3) {\n"
 "    // Create a new channel handle to distribute to the child task\n"
 "    let child_chan = chan.clone();\n"
 "    do spawn {\n"
@@ -462,14 +460,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:256
+#: doc/tutorial-tasks.md:254
 msgid ""
 "let result = port.recv() + port.recv() + port.recv(); # fn "
 "some_expensive_computation(_i: uint) -> int { 42 } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:265
+#: doc/tutorial-tasks.md:263
 msgid ""
 "Here we transfer ownership of the channel into a new `SharedChan` value.  "
 "Like `Chan`, `SharedChan` is a non-copyable, owned type (sometimes also "
@@ -482,7 +480,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:270
+#: doc/tutorial-tasks.md:268
 msgid ""
 "Note that the above `SharedChan` example is somewhat contrived since you "
 "could also simply use three `stream` pairs, but it serves to illustrate the "
@@ -491,12 +489,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:275
+#: doc/tutorial-tasks.md:273
 msgid "~~~ # use std::task::spawn; # use std::comm::stream; # use std::vec;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:284
+#: doc/tutorial-tasks.md:282
 #, no-wrap
 msgid ""
 "// Create a vector of ports, one for each child task\n"
@@ -510,7 +508,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:289
+#: doc/tutorial-tasks.md:287
 msgid ""
 "// Wait on each port, accumulating the results let result = ports.iter()."
 "fold(0, |accum, port| accum + port.recv() ); # fn "
@@ -518,14 +516,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:293
+#: doc/tutorial-tasks.md:291
 msgid ""
 "## Backgrounding computations: Futures With `extra::future`, rust has a "
 "mechanism for requesting a computation and getting the result later."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:301
+#: doc/tutorial-tasks.md:299
 #, no-wrap
 msgid ""
 "The basic example below illustrates this.\n"
@@ -538,14 +536,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:306
+#: doc/tutorial-tasks.md:304
 msgid ""
 "let mut delayed_fib = extra::future::spawn (|| fib(50) ); make_a_sandwich(); "
 "println(fmt!(\"fib(50) = %?\", delayed_fib.get()))  ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:312
+#: doc/tutorial-tasks.md:310
 msgid ""
 "The call to `future::spawn` returns immediately a `future` object regardless "
 "of how long it takes to run `fib(50)`. You can then make yourself a sandwich "
@@ -557,17 +555,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:325
+#: doc/tutorial-tasks.md:322
 #, no-wrap
 msgid ""
 "Here is another example showing how futures allow you to background computations. The workload will\n"
 "be distributed on the available cores.\n"
 "~~~\n"
 "# use std::vec;\n"
-"# use std::uint;\n"
 "fn partial_sum(start: uint) -> f64 {\n"
 "    let mut local_sum = 0f64;\n"
-"    for uint::range(start*100000, (start+1)*100000) |num| {\n"
+"    for num in range(start*100000, (start+1)*100000) {\n"
 "        local_sum += (num as f64 + 1.0).pow(&-2.0);\n"
 "    }\n"
 "    local_sum\n"
@@ -575,7 +572,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:328
+#: doc/tutorial-tasks.md:325
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -583,25 +580,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:336
+#: doc/tutorial-tasks.md:333
 #, no-wrap
 msgid ""
 "    let mut final_res = 0f64;\n"
 "    for ft in futures.mut_iter()  {\n"
 "        final_res += ft.get();\n"
 "    }\n"
-"    println(fmt!(\"^2/6 is not far from : %?\", final_res));\n"
+"    println(fmt!(\"π^2/6 is not far from : %?\", final_res));\n"
 "}\n"
 "~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:338
+#: doc/tutorial-tasks.md:335
 msgid "## Sharing immutable data without copy: Arc"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:343
+#: doc/tutorial-tasks.md:340
 msgid ""
 "To share immutable data between tasks, a first approach would be to only use "
 "pipes as we have seen previously. A copy of the data to share would then be "
@@ -610,7 +607,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:347
+#: doc/tutorial-tasks.md:344
 msgid ""
 "To tackle this issue, one can use an Atomically Reference Counted wrapper "
 "(`Arc`) as implemented in the `extra` library of Rust. With an Arc, the data "
@@ -619,16 +616,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:355
+#: doc/tutorial-tasks.md:351
 msgid ""
 "Here is a small example showing how to use Arcs. We wish to run concurrently "
 "several computations on a single large vector of floats. Each task needs the "
-"full vector to perform its duty.  ~~~ # use std::vec; # use std::uint; # use "
-"std::rand; use extra::arc::Arc;"
+"full vector to perform its duty.  ~~~ # use std::vec; # use std::rand; use "
+"extra::arc::Arc;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:359
+#: doc/tutorial-tasks.md:355
 #, no-wrap
 msgid ""
 "fn pnorm(nums: &~[float], p: uint) -> float {\n"
@@ -637,7 +634,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:363
+#: doc/tutorial-tasks.md:359
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -646,22 +643,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:365
+#: doc/tutorial-tasks.md:361
 #, no-wrap
 msgid "    let numbers_arc = Arc::new(numbers);\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:369
+#: doc/tutorial-tasks.md:365
 #, no-wrap
 msgid ""
-"    for uint::range(1,10) |num| {\n"
+"    for num in range(1u, 10) {\n"
 "        let (port, chan)  = stream();\n"
 "        chan.send(numbers_arc.clone());\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:378
+#: doc/tutorial-tasks.md:374
 #, no-wrap
 msgid ""
 "        do spawn {\n"
@@ -675,45 +672,45 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:400
+#: doc/tutorial-tasks.md:396
 msgid ""
 "The function `pnorm` performs a simple computation on the vector (it "
 "computes the sum of its items at the power given as argument and takes the "
 "inverse power of this value). The Arc on the vector is created by the line "
 "~~~ # use extra::arc::Arc; # use std::vec; # use std::rand; # let numbers = "
-"vec::from_fn(1000000, |_| rand::random::<float>()); let "
-"numbers_arc=Arc::new(numbers); ~~~ and a clone of it is sent to each task ~~~ # "
-"use extra::arc::Arc; # use std::vec; # use std::rand; # let numbers=vec::"
-"from_fn(1000000, |_| rand::random::<float>()); # let numbers_arc = "
-"Arc::new(numbers); # let (port, chan)  = stream(); chan.send(numbers_arc."
+"vec::from_fn(1000000, |_| rand::random::<float>()); let numbers_arc=Arc::"
+"new(numbers); ~~~ and a clone of it is sent to each task ~~~ # use extra::"
+"arc::Arc; # use std::vec; # use std::rand; # let numbers=vec::"
+"from_fn(1000000, |_| rand::random::<float>()); # let numbers_arc = Arc::"
+"new(numbers); # let (port, chan)  = stream(); chan.send(numbers_arc."
 "clone()); ~~~ copying only the wrapper and not its contents."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:414
+#: doc/tutorial-tasks.md:410
 msgid ""
 "Each task recovers the underlying data by ~~~ # use extra::arc::Arc; # use "
 "std::vec; # use std::rand; # let numbers=vec::from_fn(1000000, |_| rand::"
-"random::<float>()); # let numbers_arc=Arc::new(numbers); # let (port, chan)  "
-"stream(); # chan.send(numbers_arc.clone()); # let local_arc : Arc<~[float]> "
-"= port.recv(); let task_numbers = local_arc.get(); ~~~ and can use it as if "
-"it were local."
+"random::<float>()); # let numbers_arc=Arc::new(numbers); # let (port, chan)  "
+"= stream(); # chan.send(numbers_arc.clone()); # let local_arc : "
+"Arc<~[float]> = port.recv(); let task_numbers = local_arc.get(); ~~~ and can "
+"use it as if it were local."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:416
+#: doc/tutorial-tasks.md:412
 msgid ""
 "The `arc` module also implements Arcs around mutable data that are not "
 "covered here."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:418
+#: doc/tutorial-tasks.md:414
 msgid "# Handling task failure"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:427
+#: doc/tutorial-tasks.md:423
 msgid ""
 "Rust has a built-in mechanism for raising exceptions. The `fail!()` macro "
 "(which can also be written with an error string as an argument: `fail!"
@@ -726,29 +723,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:430
+#: doc/tutorial-tasks.md:426
 msgid ""
 "All tasks are, by default, _linked_ to each other. That means that the fates "
 "of all tasks are intertwined: if one fails, so do all the others."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:438
+#: doc/tutorial-tasks.md:434
 msgid ""
-"~~~ # use std::task::spawn; # use std::task; # fn do_some_work() { loop "
-"{ task::yield() } } # do task::try { // Create a child task that fails do "
-"spawn { fail!() }"
+"~~~{.xfail-test .linked-failure} # use std::task::spawn; # use std::task; # "
+"fn do_some_work() { loop { task::yield() } } # do task::try { // Create a "
+"child task that fails do spawn { fail!() }"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:443
+#: doc/tutorial-tasks.md:439
 msgid ""
 "// This will also fail because the task we spawned failed do_some_work(); "
 "# }; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:453
+#: doc/tutorial-tasks.md:449
 msgid ""
 "While it isn't possible for a task to recover from failure, tasks may notify "
 "each other of failure. The simplest way of handling task failure is with the "
@@ -762,10 +759,10 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:467
+#: doc/tutorial-tasks.md:463
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::task;\n"
 "# fn some_condition() -> bool { false }\n"
 "# fn calculate_result() -> int { 0 }\n"
@@ -781,7 +778,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:473
+#: doc/tutorial-tasks.md:469
 msgid ""
 "Unlike `spawn`, the function spawned using `try` may return a value, which "
 "`try` will dutifully propagate back to the caller in a [`Result`] enum. If "
@@ -790,12 +787,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:475
+#: doc/tutorial-tasks.md:471
 msgid "[`Result`]: std/result.html"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:480
+#: doc/tutorial-tasks.md:476
 msgid ""
 "> ***Note:*** A failed task does not currently produce a useful error > "
 "value (`try` always returns `Err(())`). In the > future, it may be possible "
@@ -803,14 +800,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:483
+#: doc/tutorial-tasks.md:479
 msgid ""
 "TODO: Need discussion of `future_result` in order to make failure modes "
 "useful."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:491
+#: doc/tutorial-tasks.md:487
 msgid ""
 "But not all failures are created equal. In some cases you might need to "
 "abort the entire program (perhaps you're writing an assert which, if it "
@@ -822,24 +819,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:493
+#: doc/tutorial-tasks.md:489
 msgid "## Failure modes"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:496
+#: doc/tutorial-tasks.md:492
 msgid ""
 "By default, task failure is _bidirectionally linked_, which means that if "
 "either task fails, it kills the other one."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:510
+#: doc/tutorial-tasks.md:507
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::task;\n"
-"# fn sleep_forever() { loop { task::yield() } }\n"
+"# use std::comm::oneshot;\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
 "# do task::try {\n"
 "do spawn {\n"
 "    do spawn {\n"
@@ -853,7 +851,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:517
+#: doc/tutorial-tasks.md:514
 msgid ""
 "If you want parent tasks to be able to kill their children, but do not want "
 "a parent to fail automatically if one of its child task fails, you can call "
@@ -864,14 +862,15 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:538
+#: doc/tutorial-tasks.md:536
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::comm::{stream, Chan, Port};\n"
+"# use std::comm::oneshot;\n"
 "# use std::task::{spawn, try};\n"
 "# use std::task;\n"
-"# fn sleep_forever() { loop { task::yield() } }\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
 "# do task::try {\n"
 "let (receiver, sender): (Port<int>, Chan<int>) = stream();\n"
 "do spawn {  // Bidirectionally linked\n"
@@ -890,7 +889,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:544
+#: doc/tutorial-tasks.md:542
 msgid ""
 "Supervised failure is useful in any situation where one task manages "
 "multiple fallible child tasks, and the parent task can recover if any child "
@@ -899,20 +898,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:547
+#: doc/tutorial-tasks.md:545
 msgid ""
 "Supervised task failure propagates across multiple generations even if an "
 "intermediate generation has already exited:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:563
+#: doc/tutorial-tasks.md:562
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::task;\n"
-"# fn sleep_forever() { loop { task::yield() } }\n"
-"# fn wait_for_a_while() { for 1000.times { task::yield() } }\n"
+"# use std::comm::oneshot;\n"
+"# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }\n"
+"# fn wait_for_a_while() { for _ in range(0, 1000u) { task::yield() } }\n"
 "# do task::try::<int> {\n"
 "do task::spawn_supervised {\n"
 "    do task::spawn_supervised {\n"
@@ -927,20 +927,20 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:566
+#: doc/tutorial-tasks.md:565
 msgid ""
 "Finally, tasks can be configured to not propagate failure to each other at "
 "all, using `task::spawn_unlinked` for _isolated failure_."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:582
+#: doc/tutorial-tasks.md:581
 #, no-wrap
 msgid ""
-"~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::task;\n"
 "# fn random() -> uint { 100 }\n"
-"# fn sleep_for(i: uint) { for i.times { task::yield() } }\n"
+"# fn sleep_for(i: uint) { for _ in range(0, i) { task::yield() } }\n"
 "# do task::try::<()> {\n"
 "let (time1, time2) = (random(), random());\n"
 "do task::spawn_unlinked {\n"
@@ -955,12 +955,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:584
+#: doc/tutorial-tasks.md:583
 msgid "## Creating a task with a bi-directional communication path"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:589
+#: doc/tutorial-tasks.md:588
 msgid ""
 "A very common thing to do is to spawn a child task where the parent and "
 "child both need to exchange messages with each other. The function `extra::"
@@ -969,7 +969,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:594
+#: doc/tutorial-tasks.md:593
 msgid ""
 "To see how `DuplexStream()` works, we will create a child task that "
 "repeatedly receives a `uint` message, converts it to a string, and sends the "
@@ -978,10 +978,10 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:607
+#: doc/tutorial-tasks.md:606
 #, no-wrap
 msgid ""
-"~~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use extra::comm::DuplexStream;\n"
 "# use std::uint;\n"
 "fn stringifier(channel: &DuplexStream<~str, uint>) {\n"
@@ -996,7 +996,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:615
+#: doc/tutorial-tasks.md:614
 msgid ""
 "The implementation of `DuplexStream` supports both sending and receiving. "
 "The `stringifier` function takes a `DuplexStream` that can send strings (the "
@@ -1007,15 +1007,15 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:617
+#: doc/tutorial-tasks.md:616
 msgid "Here is the code for the parent task:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:631
+#: doc/tutorial-tasks.md:630
 #, no-wrap
 msgid ""
-"~~~~\n"
+"~~~{.xfail-test .linked-failure}\n"
 "# use std::task::spawn;\n"
 "# use std::uint;\n"
 "# use extra::comm::DuplexStream;\n"
@@ -1031,12 +1031,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:633
+#: doc/tutorial-tasks.md:632
 msgid "let (from_child, to_child) = DuplexStream();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:637
+#: doc/tutorial-tasks.md:636
 #, no-wrap
 msgid ""
 "do spawn {\n"
@@ -1045,23 +1045,23 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:640
+#: doc/tutorial-tasks.md:639
 msgid "from_child.send(22); assert!(from_child.recv() == ~\"22\");"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:643
+#: doc/tutorial-tasks.md:642
 msgid "from_child.send(23); from_child.send(0);"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:646
+#: doc/tutorial-tasks.md:645
 msgid ""
 "assert!(from_child.recv() == ~\"23\"); assert!(from_child.recv() == ~\"0\");"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial-tasks.md:653
+#: doc/tutorial-tasks.md:652
 msgid ""
 "The parent task first calls `DuplexStream` to create a pair of bidirectional "
 "endpoints. It then uses `task::spawn` to create the child task, which "
index 5d8a03343ae33ebcb4cb3a695557f3a2581cc533..2aea69cc57332e98140d80ad3ab10fce558fd323 100644 (file)
@@ -7,13 +7,13 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: Rust 0.8-pre\n"
-"POT-Creation-Date: 2013-07-17 07:18+0900\n"
+"POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. type: Plain text
@@ -24,7 +24,7 @@ msgid "# Introduction"
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1231 doc/tutorial.md:2177
+#: doc/rust.md:1277 doc/tutorial.md:2176
 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:2186
+#: doc/rust.md:1286 doc/tutorial.md:2185
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -46,7 +46,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/rust.md:1242 doc/tutorial.md:2188
+#: doc/rust.md:1288 doc/tutorial.md:2187
 msgid "Likewise, supertrait methods may also be called on trait objects."
 msgstr ""
 
@@ -226,8 +226,8 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:88
 msgid ""
-"[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]:"
-"\thttps://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
+"[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
+"https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
 msgstr ""
 
 #. type: Plain text
@@ -296,27 +296,26 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:124
+#: doc/tutorial.md:123
 msgid ""
-"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
-"developing-Rust [tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz "
-"[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe"
+"[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz [win-exe]: "
+"http://static.rust-lang.org/dist/rust-0.7-install.exe"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:126
+#: doc/tutorial.md:125
 msgid "## Compiling your first program"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:129
+#: doc/tutorial.md:128
 msgid ""
 "Rust program files are, by convention, given the extension `.rs`. Say we "
 "have a file `hello.rs` containing this program:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:135
+#: doc/tutorial.md:134
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -327,7 +326,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:139
+#: doc/tutorial.md:138
 msgid ""
 "If the Rust compiler was installed successfully, running `rustc hello.rs` "
 "will produce an executable called `hello` (or `hello.exe` on Windows) which, "
@@ -335,7 +334,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:144
+#: doc/tutorial.md:143
 msgid ""
 "The Rust compiler tries to provide useful information when it encounters an "
 "error. If you introduce an error into the program (for example, by changing "
@@ -344,7 +343,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:150
+#: doc/tutorial.md:149
 #, no-wrap
 msgid ""
 "~~~~ {.notrust}\n"
@@ -355,7 +354,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:157
+#: doc/tutorial.md:156
 msgid ""
 "In its simplest form, a Rust program is a `.rs` file with some types and "
 "functions defined in it. If it has a `main` function, it can be compiled to "
@@ -366,12 +365,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:159
+#: doc/tutorial.md:158
 msgid "## Using the rust tool"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:164
+#: doc/tutorial.md:163
 msgid ""
 "While using `rustc` directly to generate your executables, and then running "
 "them manually is a perfectly valid way to test your code, for smaller "
@@ -380,7 +379,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:170
+#: doc/tutorial.md:169
 msgid ""
 "The `rust` tool provides central access to the other rust tools, as well as "
 "handy shortcuts for directly running source files.  For example, if you have "
@@ -389,19 +388,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:173
+#: doc/tutorial.md:172
 msgid ""
 "To get a list of all available commands, simply call `rust` without any "
 "argument."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:175
+#: doc/tutorial.md:174
 msgid "## Editing Rust code"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:185
+#: doc/tutorial.md:184
 msgid ""
 "There are vim highlighting and indentation scripts in the Rust source "
 "distribution under `src/etc/vim/`. There is an emacs mode under `src/etc/"
@@ -414,7 +413,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:189
+#: doc/tutorial.md:188
 msgid ""
 "There is ctags support via `src/etc/ctags.rust`, but many other tools and "
 "editors are not yet supported. If you end up writing a Rust mode for your "
@@ -422,19 +421,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:192
+#: doc/tutorial.md:191
 msgid ""
 "[sublime]: http://github.com/dbp/sublime-rust [sublime-pkg]: http://wbond."
 "net/sublime_packages/package_control"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:194
+#: doc/tutorial.md:193
 msgid "# Syntax basics"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:202
+#: doc/tutorial.md:201
 msgid ""
 "Assuming you've programmed in any C-family language (C++, Java, JavaScript, "
 "C#, or PHP), Rust will feel familiar. Code is arranged in blocks delineated "
@@ -446,7 +445,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:207
+#: doc/tutorial.md:206
 msgid ""
 "The main surface difference to be aware of is that the condition at the head "
 "of control structures like `if` and `while` does not require parentheses, "
@@ -455,7 +454,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:220
+#: doc/tutorial.md:219
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -473,7 +472,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:224
+#: doc/tutorial.md:223
 msgid ""
 "The `let` keyword introduces a local variable. Variables are immutable by "
 "default. To introduce a local variable that you can re-assign later, use "
@@ -481,12 +480,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:228
+#: doc/tutorial.md:227
 msgid "~~~~ let hi = \"hi\"; let mut count = 0;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:234
+#: doc/tutorial.md:233
 #, no-wrap
 msgid ""
 "while count < 10 {\n"
@@ -497,7 +496,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:238
+#: doc/tutorial.md:237
 msgid ""
 "Although Rust can almost always infer the types of local variables, you can "
 "specify a variable's type by following it with a colon, then the type name. "
@@ -505,14 +504,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:244
+#: doc/tutorial.md:243
 msgid ""
 "~~~~ static MONSTER_FACTOR: float = 57.8; let monster_size = MONSTER_FACTOR "
 "* 10.0; let monster_size: int = 50; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:253
+#: doc/tutorial.md:252
 msgid ""
 "Local variables may shadow earlier declarations, as in the previous example: "
 "`monster_size` was first declared as a `float`, and then a second "
@@ -525,7 +524,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:259
+#: doc/tutorial.md:258
 msgid ""
 "Rust identifiers start with an alphabetic character or an underscore, and "
 "after that may contain any sequence of alphabetic characters, numbers, or "
@@ -535,7 +534,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:264
+#: doc/tutorial.md:263
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -545,12 +544,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:266
+#: doc/tutorial.md:265
 msgid "## Expressions and semicolons"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:272
+#: doc/tutorial.md:271
 msgid ""
 "Though it isn't apparent in all code, there is a fundamental difference "
 "between Rust's syntax and predecessors like C.  Many constructs that are "
@@ -559,7 +558,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:284
+#: doc/tutorial.md:283
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -576,12 +575,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:286
+#: doc/tutorial.md:285
 msgid "But, in Rust, you don't have to repeat the name `price`:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:298
+#: doc/tutorial.md:297
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -598,7 +597,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:304
+#: doc/tutorial.md:303
 msgid ""
 "Both pieces of code are exactly equivalent: they assign a value to `price` "
 "depending on the condition that holds. Note that there are no semicolons in "
@@ -608,7 +607,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:310
+#: doc/tutorial.md:309
 msgid ""
 "Put another way, the semicolon in Rust *ignores the value of an "
 "expression*.  Thus, if the branches of the `if` had looked like `{ 4; }`, "
@@ -618,16 +617,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:315
+#: doc/tutorial.md:314
 msgid ""
 "In short, everything that's not a declaration (declarations are `let` for "
 "variables; `fn` for functions; and any top-level named items such as [traits]"
-"(#traits), [enum types](#enums), and [constants](#constants)) is an "
-"expression, including function bodies."
+"(#traits), [enum types](#enums), and static items) is an expression, "
+"including function bodies."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:323
+#: doc/tutorial.md:322
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -640,12 +639,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:325
+#: doc/tutorial.md:324
 msgid "## Primitive types and literals"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:332
+#: doc/tutorial.md:331
 msgid ""
 "There are general signed and unsigned integer types, `int` and `uint`, as "
 "well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc.  Integers can "
@@ -656,7 +655,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:338
+#: doc/tutorial.md:337
 msgid ""
 "In the absence of an integer literal suffix, Rust will infer the integer "
 "type based on type annotations and function signatures in the surrounding "
@@ -665,7 +664,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:345
+#: doc/tutorial.md:344
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -677,7 +676,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:350
+#: doc/tutorial.md:349
 msgid ""
 "There are three floating-point types: `float`, `f32`, and `f64`.  Floating-"
 "point numbers are written `0.0`, `1e6`, or `2.1e-4`.  Like integers, "
@@ -686,12 +685,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:352
+#: doc/tutorial.md:351
 msgid "The keywords `true` and `false` produce literals of type `bool`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:359
+#: doc/tutorial.md:358
 msgid ""
 "Characters, the `char` type, are four-byte Unicode codepoints, whose "
 "literals are written between single quotes, as in `'x'`.  Just like C, Rust "
@@ -702,17 +701,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:361
+#: doc/tutorial.md:360
 msgid "The nil type, written `()`, has a single value, also written `()`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:363
+#: doc/tutorial.md:362
 msgid "## Operators"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:368
+#: doc/tutorial.md:367
 msgid ""
 "Rust's set of operators contains very few surprises. Arithmetic is done with "
 "`*`, `/`, `%`, `+`, and `-` (multiply, quotient, remainder, add, and "
@@ -721,14 +720,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:371
+#: doc/tutorial.md:370
 msgid ""
 "Note that, if applied to an integer value, `!` flips all the bits (like `~` "
 "in C)."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:375
+#: doc/tutorial.md:374
 msgid ""
 "The comparison operators are the traditional `==`, `!=`, `<`, `>`, `<=`, and "
 "`>=`. Short-circuiting (lazy) boolean operators are written `&&` (and) and "
@@ -736,7 +735,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:380
+#: doc/tutorial.md:379
 msgid ""
 "For type casting, Rust uses the binary `as` operator.  It takes an "
 "expression on the left side and a type on the right side and will, if a "
@@ -745,18 +744,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:386
+#: doc/tutorial.md:385
 msgid ""
 "~~~~ let x: float = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:388
+#: doc/tutorial.md:387
 msgid "## Syntax extensions"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:395
+#: doc/tutorial.md:394
 #, no-wrap
 msgid ""
 "*Syntax extensions* are special forms that are not built into the language,\n"
@@ -768,7 +767,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:399
+#: doc/tutorial.md:398
 msgid ""
 "`fmt!` supports most of the directives that [printf][pf] supports, but "
 "unlike printf, will give you a compile-time error when the types of the "
@@ -776,51 +775,46 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:402
+#: doc/tutorial.md:401
 msgid "~~~~ # let mystery_object = ();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:404
+#: doc/tutorial.md:403
 msgid "println(fmt!(\"%s is %d\", \"the answer\", 43));"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:408
+#: doc/tutorial.md:407
 msgid ""
 "// %? will conveniently print any type println(fmt!(\"what is this thing: %?"
 "\", mystery_object)); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:410
+#: doc/tutorial.md:409
 msgid "[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:412
+#: doc/tutorial.md:411
 msgid ""
 "You can define your own syntax extensions with the macro system. For "
 "details, see the [macro tutorial][macros]."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:414
-msgid "[macros]: tutorial-macros.html"
-msgstr ""
-
-#. type: Plain text
-#: doc/tutorial.md:416
+#: doc/tutorial.md:413
 msgid "# Control structures"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:418
+#: doc/tutorial.md:415
 msgid "## Conditionals"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:422
+#: doc/tutorial.md:419
 msgid ""
 "We've seen `if` expressions a few times already. To recap, braces are "
 "compulsory, an `if` can have an optional `else` clause, and multiple `if`/"
@@ -828,7 +822,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:432
+#: doc/tutorial.md:429
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -843,7 +837,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:437
+#: doc/tutorial.md:434
 msgid ""
 "The condition given to an `if` construct *must* be of type `bool` (no "
 "implicit conversion happens). If the arms are blocks that have a value, this "
@@ -852,7 +846,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:445
+#: doc/tutorial.md:442
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -865,12 +859,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:447
+#: doc/tutorial.md:444
 msgid "## Pattern matching"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:453
+#: doc/tutorial.md:450
 msgid ""
 "Rust's `match` construct is a generalized, cleaned-up version of C's "
 "`switch` construct. You provide it with a value and a number of *arms*, each "
@@ -880,7 +874,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:463
+#: doc/tutorial.md:460
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -895,7 +889,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:467
+#: doc/tutorial.md:464
 msgid ""
 "Unlike in C, there is no \"falling through\" between arms: only one arm "
 "executes, and it doesn't have to explicitly `break` out of the construct "
@@ -903,7 +897,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:477
+#: doc/tutorial.md:474
 msgid ""
 "A `match` arm consists of a *pattern*, then an arrow `=>`, followed by an "
 "*action* (expression). Literals are valid patterns and match only their own "
@@ -916,7 +910,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:482
+#: doc/tutorial.md:479
 msgid ""
 "The patterns in a match arm are followed by a fat arrow, `=>`, then an "
 "expression to evaluate. Each case is separated by commas. It's often "
@@ -925,7 +919,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:490
+#: doc/tutorial.md:487
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -938,7 +932,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:495
+#: doc/tutorial.md:492
 msgid ""
 "`match` constructs must be *exhaustive*: they must have an arm covering "
 "every possible case. For example, the typechecker would reject the previous "
@@ -946,14 +940,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:499
+#: doc/tutorial.md:496
 msgid ""
 "A powerful application of pattern matching is *destructuring*: matching in "
 "order to bind names to the contents of data types."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:503
+#: doc/tutorial.md:500
 msgid ""
 "> ***Note:*** The following code makes use of tuples (`(float, float)`) "
 "which > are explained in section 5.3. For now you can think of tuples as a "
@@ -961,12 +955,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:516
+#: doc/tutorial.md:513
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::float;\n"
-"use std::num::atan;\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"
@@ -979,7 +973,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:522
+#: doc/tutorial.md:519
 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)` "
@@ -989,7 +983,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:529
+#: doc/tutorial.md:526
 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, "
@@ -999,7 +993,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:534
+#: doc/tutorial.md:531
 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. "
@@ -1008,14 +1002,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:539
+#: doc/tutorial.md:536
 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:543
+#: doc/tutorial.md:540
 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 "
@@ -1023,12 +1017,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:545
+#: doc/tutorial.md:542
 msgid "## Loops"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:550
+#: doc/tutorial.md:547
 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 "
@@ -1037,7 +1031,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:557
+#: doc/tutorial.md:554
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1049,18 +1043,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:559
+#: doc/tutorial.md:556
 msgid ""
 "`loop` denotes an infinite loop, and is the preferred way of writing `while "
 "true`:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:569
+#: doc/tutorial.md:566
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::int;\n"
+"use std::int;\n"
 "let mut x = 5;\n"
 "loop {\n"
 "    x += x - 3;\n"
@@ -1071,33 +1065,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:572
+#: doc/tutorial.md:569
 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: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]"
-"(#closures)  to find out how to use `for` and higher-order functions for "
-"enumerating elements of a collection."
-msgstr ""
-
-#. type: Plain text
-#: doc/tutorial.md:579
+#: doc/tutorial.md:571
 msgid "# Data structures"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:581
+#: doc/tutorial.md:573
 msgid "## Structs"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:586
+#: doc/tutorial.md:578
 msgid ""
 "Rust struct types must be declared before they are used using the `struct` "
 "syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, "
@@ -1106,7 +1091,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:590
+#: doc/tutorial.md:582
 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 "
@@ -1114,7 +1099,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:597
+#: doc/tutorial.md:589
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1126,7 +1111,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:601
+#: doc/tutorial.md:593
 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 "
@@ -1134,7 +1119,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:605
+#: doc/tutorial.md:597
 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 "
@@ -1142,28 +1127,28 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:610
+#: doc/tutorial.md:602
 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:614
+#: doc/tutorial.md:606
 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:617
+#: doc/tutorial.md:609
 msgid ""
 "`match` patterns destructure structs. The basic syntax is `Name { fieldname: "
 "pattern, ... }`:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:626
+#: doc/tutorial.md:618
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1177,7 +1162,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:633
+#: doc/tutorial.md:625
 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 "
@@ -1188,7 +1173,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:641
+#: doc/tutorial.md:633
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -1201,19 +1186,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:643
+#: doc/tutorial.md:635
 msgid "## Enums"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:646
+#: doc/tutorial.md:638
 msgid ""
 "Enums are datatypes that have several alternate representations. For "
 "example, consider the type shown earlier:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:654
+#: doc/tutorial.md:646
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1226,7 +1211,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:660
+#: doc/tutorial.md:652
 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 "
@@ -1236,7 +1221,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:666
+#: doc/tutorial.md:658
 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 "
@@ -1245,14 +1230,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:669
+#: doc/tutorial.md:661
 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:678
+#: doc/tutorial.md:670
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1266,14 +1251,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:681
+#: doc/tutorial.md:673
 msgid ""
 "This declaration defines `North`, `East`, `South`, and `West` as constants, "
 "all of which have type `Direction`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:685
+#: doc/tutorial.md:677
 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 "
@@ -1281,7 +1266,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:693
+#: doc/tutorial.md:685
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1294,7 +1279,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:698
+#: doc/tutorial.md:690
 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 "
@@ -1303,14 +1288,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:701
+#: doc/tutorial.md:693
 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:705
+#: doc/tutorial.md:697
 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 "
@@ -1318,11 +1303,11 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:717
+#: doc/tutorial.md:709
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::float;\n"
+"use std::float;\n"
 "# struct Point {x: float, y: float}\n"
 "# enum Shape { Circle(Point, float), Rectangle(Point, Point) }\n"
 "fn area(sh: Shape) -> float {\n"
@@ -1335,7 +1320,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:722
+#: doc/tutorial.md:714
 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, "
@@ -1343,7 +1328,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:735
+#: doc/tutorial.md:727
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1361,16 +1346,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:737
+#: doc/tutorial.md:729
 msgid "Enum variants may also be structs. For example:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:755
+#: doc/tutorial.md:747
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::float;\n"
+"use std::float;\n"
 "# struct Point { x: float, y: float }\n"
 "# fn square(x: float) -> float { x * x }\n"
 "enum Shape {\n"
@@ -1389,12 +1374,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:757
+#: doc/tutorial.md:749
 msgid "## Tuples"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:762
+#: doc/tutorial.md:754
 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 "
@@ -1403,7 +1388,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:769
+#: doc/tutorial.md:761
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1415,12 +1400,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:771
+#: doc/tutorial.md:763
 msgid "## Tuple structs"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:776
+#: doc/tutorial.md:768
 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 "
@@ -1429,7 +1414,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:785
+#: doc/tutorial.md:777
 #, no-wrap
 msgid ""
 "For example:\n"
@@ -1443,12 +1428,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:787
+#: doc/tutorial.md:779
 msgid "<a name=\"newtype\"></a>"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:792
+#: doc/tutorial.md:784
 msgid ""
 "There is a special case for tuple structs with a single field, which are "
 "sometimes called \"newtypes\" (after Haskell's \"newtype\" feature). These "
@@ -1457,50 +1442,50 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:796
+#: doc/tutorial.md:788
 msgid "~~~~ struct GizmoId(int); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:799
+#: doc/tutorial.md:791
 msgid ""
 "For convenience, you can extract the contents of such a struct with the "
 "dereference (`*`) unary operator:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:805
+#: doc/tutorial.md:797
 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:808
+#: doc/tutorial.md:800
 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:813
+#: doc/tutorial.md:805
 msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:816
+#: doc/tutorial.md:808
 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:818
+#: doc/tutorial.md:810
 msgid "# Functions"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:826
+#: doc/tutorial.md:818
 msgid ""
 "We've already seen several function definitions. Like all other static "
 "declarations, such as `type`, functions can be declared both at the top "
@@ -1512,7 +1497,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:832
+#: doc/tutorial.md:824
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1523,7 +1508,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:837
+#: doc/tutorial.md:829
 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 "
@@ -1531,7 +1516,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:843
+#: doc/tutorial.md:835
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1542,7 +1527,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:850
+#: doc/tutorial.md:842
 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 "
@@ -1552,35 +1537,35 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:853
+#: doc/tutorial.md:845
 msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:856
+#: doc/tutorial.md:848
 msgid "fn do_nothing_the_easy_way() { } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:858
+#: doc/tutorial.md:850
 msgid ""
 "Ending the function with a semicolon like so is equivalent to returning `()`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:862
+#: doc/tutorial.md:854
 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:866
+#: doc/tutorial.md:858
 msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:870
+#: doc/tutorial.md:862
 msgid ""
 "As with `match` expressions and `let` bindings, function arguments support "
 "pattern destructuring. Like `let`, argument patterns must be irrefutable, as "
@@ -1588,17 +1573,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:874
+#: doc/tutorial.md:866
 msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:876 doc/tutorial-ffi.md:143
+#: doc/tutorial.md:868 doc/tutorial-ffi.md:143
 msgid "# Destructors"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:880
+#: doc/tutorial.md:872
 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 "
@@ -1606,7 +1591,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:884
+#: doc/tutorial.md:876
 msgid ""
 "Objects are never accessible after their destructor has been called, so "
 "there are no dynamic failures from accessing freed resources. When a task "
@@ -1614,13 +1599,13 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:886
+#: doc/tutorial.md:878
 msgid ""
 "The `~` sigil represents a unique handle for a memory allocation on the heap:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:894
+#: doc/tutorial.md:886
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1633,7 +1618,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:898
+#: doc/tutorial.md:890
 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 "
@@ -1641,12 +1626,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:900
+#: doc/tutorial.md:892
 msgid "# Ownership"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:905
+#: doc/tutorial.md:897
 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 "
@@ -1656,7 +1641,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:911
+#: doc/tutorial.md:903
 msgid ""
 "Ownership is recursive, so mutability is inherited recursively and a "
 "destructor destroys the contained tree of owned objects. Variables are top-"
@@ -1666,14 +1651,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:915
+#: doc/tutorial.md:907
 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:922
+#: doc/tutorial.md:914
 #, no-wrap
 msgid ""
 "{\n"
@@ -1685,14 +1670,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:927
+#: doc/tutorial.md:919
 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:933
+#: doc/tutorial.md:925
 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 "
@@ -1702,12 +1687,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:935
+#: doc/tutorial.md:927
 msgid "# Boxes"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:942
+#: doc/tutorial.md:934
 msgid ""
 "Many modern languages represent values as pointers to heap memory by "
 "default. In contrast, Rust, like C and C++, represents such types directly.  "
@@ -1718,7 +1703,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:947
+#: doc/tutorial.md:939
 msgid ""
 "For small structs like `Point`, this is usually more efficient than "
 "allocating memory and indirecting through a pointer. But for big structs, or "
@@ -1727,31 +1712,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:949
+#: doc/tutorial.md:941
 msgid "## Owned boxes"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:952
+#: doc/tutorial.md:944
 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:957
+#: doc/tutorial.md:949
 msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:962
+#: doc/tutorial.md:954
 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:967
+#: doc/tutorial.md:959
 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 "
@@ -1760,14 +1745,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:970
+#: doc/tutorial.md:962
 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:976
+#: doc/tutorial.md:968
 #, no-wrap
 msgid ""
 "~~~~ {.xfail-test}\n"
@@ -1778,7 +1763,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:980
+#: doc/tutorial.md:972
 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 "
@@ -1786,7 +1771,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:984
+#: doc/tutorial.md:976
 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 "
@@ -1794,7 +1779,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:990
+#: doc/tutorial.md:982
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1805,46 +1790,46 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:992
+#: doc/tutorial.md:984
 msgid "## Managed boxes"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1000
+#: doc/tutorial.md:992
 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 "
 "no references left to the box, no later than the end of the task. Managed "
 "boxes lack an owner, so they start a new ownership tree and don't inherit "
 "mutability. They do own the contained object, and mutability is defined by "
-"the type of the shared box (`@` or `@mut`). An object containing a managed "
+"the type of the managed box (`@` or `@mut`). An object containing a managed "
 "box is not `Owned`, and can't be sent between tasks."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1003
+#: doc/tutorial.md:995
 msgid "~~~~ let a = @5; // immutable"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1006
+#: doc/tutorial.md:998
 msgid "let mut b = @5; // mutable variable, immutable box b = @10;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1009
+#: doc/tutorial.md:1001
 msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1014
+#: doc/tutorial.md:1006
 msgid ""
 "let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; "
 "~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1019
+#: doc/tutorial.md:1011
 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 "
@@ -1853,7 +1838,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1023
+#: doc/tutorial.md:1015
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -1862,7 +1847,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1026
+#: doc/tutorial.md:1018
 #, no-wrap
 msgid ""
 "let mut c : @int;       // declare a variable with type managed immutable int\n"
@@ -1870,7 +1855,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1030
+#: doc/tutorial.md:1022
 #, no-wrap
 msgid ""
 "c = a;          // box type is the same, okay\n"
@@ -1879,7 +1864,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1035
+#: doc/tutorial.md:1027
 #, no-wrap
 msgid ""
 "~~~~ {.xfail-test}\n"
@@ -1889,12 +1874,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1037
+#: doc/tutorial.md:1029
 msgid "# Move semantics"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1043
+#: doc/tutorial.md:1035
 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 "
@@ -1904,33 +1889,33 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1049
+#: doc/tutorial.md:1041
 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:1052
+#: doc/tutorial.md:1044
 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:1059
+#: doc/tutorial.md:1051
 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:1061
+#: doc/tutorial.md:1053
 msgid "# Borrowed pointers"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1067
+#: doc/tutorial.md:1059
 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 "
@@ -1940,12 +1925,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1069
+#: doc/tutorial.md:1061
 msgid "As an example, consider a simple struct type, `Point`:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1076
+#: doc/tutorial.md:1068
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -1957,7 +1942,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1080
+#: doc/tutorial.md:1072
 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 "
@@ -1965,7 +1950,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1087
+#: doc/tutorial.md:1079
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -1977,22 +1962,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1099
+#: doc/tutorial.md:1089
 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 "
 "compute the distance between `on_the_stack` and `managed_box`, or between "
 "`managed_box` and `owned_box`. One option is to define a function that takes "
-"two arguments of type pointthat is, it takes the points by value. But this "
+"two arguments of type pointthat is, it takes the points by value. But this "
 "will cause the points to be copied when we call the function. For points, "
-"this is probably not so bad, but often copies are expensive or, worse, if "
-"there are mutable fields, they can change the semantics of your program. So "
-"wed like to define a function that takes the points by pointer. We can use "
-"borrowed pointers to do this:"
+"this is probably not so bad, but often copies are expensive. So we’d like to "
+"define a function that takes the points by pointer. We can use borrowed "
+"pointers to do this:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1109
+#: doc/tutorial.md:1099
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2007,12 +1991,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72
+#: doc/tutorial.md:1101 doc/tutorial-borrowed-ptr.md:72
 msgid "Now we can call `compute_distance()` in various ways:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1121
+#: doc/tutorial.md:1111
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2027,7 +2011,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1128
+#: doc/tutorial.md:1118
 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 "
@@ -2037,7 +2021,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1134
+#: doc/tutorial.md:1124
 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 "
@@ -2047,7 +2031,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1143
+#: doc/tutorial.md:1133
 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 "
@@ -2059,31 +2043,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1146
+#: doc/tutorial.md:1136
 msgid ""
 "For a more in-depth explanation of borrowed pointers, read the [borrowed "
 "pointer tutorial][borrowtut]."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1148
+#: doc/tutorial.md:1138
 msgid "[borrowtut]: tutorial-borrowed-ptr.html"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1150
+#: doc/tutorial.md:1140
 msgid "## Freezing"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1153
+#: doc/tutorial.md:1143
 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:1161
+#: doc/tutorial.md:1152
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2092,11 +2076,12 @@ msgid ""
 "    let y = &x; // x is now frozen, it cannot be modified\n"
 "}\n"
 "// x is now unfrozen again\n"
+"# x = 3;\n"
 "~~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1165
+#: doc/tutorial.md:1156
 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 "
@@ -2104,7 +2089,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1175
+#: doc/tutorial.md:1166
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2119,29 +2104,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1177
+#: doc/tutorial.md:1168
 msgid "# Dereferencing pointers"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1180
+#: doc/tutorial.md:1171
 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:1185
+#: doc/tutorial.md:1176
 msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1188
+#: doc/tutorial.md:1179
 msgid "let sum = *managed + *owned + *borrowed; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1192
+#: doc/tutorial.md:1183
 msgid ""
 "Dereferenced mutable pointers may appear on the left hand side of "
 "assignments. Such an assignment modifies the value that the pointer points "
@@ -2149,17 +2134,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1196
+#: doc/tutorial.md:1187
 msgid "~~~ let managed = @mut 10; let mut owned = ~20;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1199
+#: doc/tutorial.md:1190
 msgid "let mut value = 30; let borrowed = &mut value;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1204
+#: doc/tutorial.md:1195
 #, no-wrap
 msgid ""
 "*managed = *owned + 10;\n"
@@ -2169,7 +2154,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1208
+#: doc/tutorial.md:1199
 msgid ""
 "Pointers have high operator precedence, but lower precedence than the dot "
 "operator used for field and method access. This precedence order can "
@@ -2177,7 +2162,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1218
+#: doc/tutorial.md:1209
 msgid ""
 "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, "
 "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point "
@@ -2186,7 +2171,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1222
+#: doc/tutorial.md:1213
 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), "
@@ -2194,7 +2179,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1232
+#: doc/tutorial.md:1223
 msgid ""
 "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, "
 "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point "
@@ -2203,7 +2188,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1236
+#: doc/tutorial.md:1227
 msgid ""
 "You can write an expression that dereferences any number of pointers "
 "automatically. For example, if you feel inclined, you could write something "
@@ -2211,24 +2196,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1242
+#: doc/tutorial.md:1233
 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:1244
+#: doc/tutorial.md:1235
 msgid "The indexing operator (`[]`) also auto-dereferences."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1246
+#: doc/tutorial.md:1237
 msgid "# Vectors and strings"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1251
+#: doc/tutorial.md:1242
 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, "
@@ -2237,7 +2222,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1261
+#: doc/tutorial.md:1252
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2252,64 +2237,69 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1264
+#: doc/tutorial.md:1255
 msgid ""
 "// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] "
 "= &[Aquamarine, Asparagus, AtomicTangerine];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1267
+#: doc/tutorial.md:1258
 msgid ""
 "// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = "
 "@[BananaMania, Beaver, Bittersweet];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1271
+#: doc/tutorial.md:1262
 msgid ""
 "// An exchange heap (owned) vector of crayons let exchange_crayons: "
 "~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1273
+#: doc/tutorial.md:1264
 msgid "The `+` operator means concatenation when applied to vector types."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1278
+#: doc/tutorial.md:1274
 #, no-wrap
 msgid ""
 "~~~~\n"
 "# enum Crayon { Almond, AntiqueBrass, Apricot,\n"
 "#               Aquamarine, Asparagus, AtomicTangerine,\n"
 "#               BananaMania, Beaver, Bittersweet };\n"
+"# impl Clone for Crayon {\n"
+"#     fn clone(&self) -> Crayon {\n"
+"#         *self\n"
+"#     }\n"
+"# }\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1281
+#: doc/tutorial.md:1277
 msgid ""
 "let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = "
 "~[BananaMania, Beaver, Bittersweet];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1284
+#: doc/tutorial.md:1280
 msgid ""
 "// Add two vectors to create a new one let our_crayons = my_crayons + "
 "your_crayons;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1289
+#: doc/tutorial.md:1285
 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:1294
+#: doc/tutorial.md:1290
 msgid ""
 "> ***Note:*** The above examples of vector addition use owned > vectors. "
 "Some operations on slices and stack vectors are > not yet well-supported. "
@@ -2317,12 +2307,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1296
+#: doc/tutorial.md:1292
 msgid "Square brackets denote indexing into a vector:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1308
+#: doc/tutorial.md:1304
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2339,16 +2329,16 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1310
+#: doc/tutorial.md:1306
 msgid "A vector can be destructured using pattern matching:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1320
+#: doc/tutorial.md:1316
 #, no-wrap
 msgid ""
 "~~~~\n"
-"let numbers: [int, ..3] = [1, 2, 3];\n"
+"let numbers: &[int] = &[1, 2, 3];\n"
 "let score = match numbers {\n"
 "    [] => 0,\n"
 "    [a] => a * 10,\n"
@@ -2359,7 +2349,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1324
+#: doc/tutorial.md:1320
 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 "
@@ -2367,7 +2357,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1330
+#: doc/tutorial.md:1326
 #, no-wrap
 msgid ""
 "~~~ {.xfail-test}\n"
@@ -2378,17 +2368,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1333
+#: doc/tutorial.md:1329
 msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1335
+#: doc/tutorial.md:1331
 msgid "Moving it into a mutable slot makes the elements assignable."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1341
+#: doc/tutorial.md:1337
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2399,25 +2389,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1344
+#: doc/tutorial.md:1340
 msgid ""
 "// Put the vector into a mutable slot let mut mutable_crayons = crayons;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1348
+#: doc/tutorial.md:1344
 msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1351
+#: doc/tutorial.md:1347
 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:1359
+#: doc/tutorial.md:1355
 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 "
@@ -2428,47 +2418,47 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1363
+#: doc/tutorial.md:1359
 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:1366
+#: doc/tutorial.md:1362
 msgid ""
 "// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, "
 "Asparagus, AtomicTangerine\";"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1369
+#: doc/tutorial.md:1365
 msgid ""
 "// A local heap (managed) string let local_crayons: @str = @\"BananaMania, "
 "Beaver, Bittersweet\";"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1373
+#: doc/tutorial.md:1369
 msgid ""
 "// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, "
 "BlizzardBlue, Blue\"; ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1377
+#: doc/tutorial.md:1373
 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."
+"Both vectors and strings support a number of useful [methods](#methods), "
+"defined in [`std::vec`] and [`std::str`]. Here are some examples."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1380
+#: doc/tutorial.md:1376
 msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1391
+#: doc/tutorial.md:1387
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2484,23 +2474,23 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1393
+#: doc/tutorial.md:1389
 msgid "let crayons = [Almond, AntiqueBrass, Apricot];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1397
+#: doc/tutorial.md:1393
 msgid ""
 "// Check the length of the vector assert!(crayons.len() == 3); assert!(!"
 "crayons.is_empty());"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1404
+#: doc/tutorial.md:1400
 #, no-wrap
 msgid ""
 "// Iterate over a vector, obtaining a pointer to each element\n"
-"// (`for` is explained in the next section)\n"
+"// (`for` is explained in the container/iterator tutorial)\n"
 "for crayon in crayons.iter() {\n"
 "    let delicious_crayon_wax = unwrap_crayon(*crayon);\n"
 "    eat_crayon_wax(delicious_crayon_wax);\n"
@@ -2508,21 +2498,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1408
+#: doc/tutorial.md:1404
 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:1411
+#: doc/tutorial.md:1407
 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:1417
+#: doc/tutorial.md:1413
 #, no-wrap
 msgid ""
 "if favorite_crayon_name.len() > 5 {\n"
@@ -2533,12 +2523,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1419
+#: doc/tutorial.md:1415
 msgid "# Closures"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1424
+#: doc/tutorial.md:1420
 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 "
@@ -2547,12 +2537,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1427
+#: doc/tutorial.md:1423
 msgid "~~~~ {.ignore} let foo = 10;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1432
+#: doc/tutorial.md:1428
 #, no-wrap
 msgid ""
 "fn bar() -> int {\n"
@@ -2562,31 +2552,31 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1435
+#: doc/tutorial.md:1431
 msgid ""
 "Rust also supports _closures_, functions that can access variables in the "
 "enclosing scope."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1438
+#: doc/tutorial.md:1434
 msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1441
+#: doc/tutorial.md:1437
 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:1444
+#: doc/tutorial.md:1440
 msgid "call_closure_with_ten(closure); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1450
+#: doc/tutorial.md:1446
 msgid ""
 "Closures begin with the argument list between vertical bars and are followed "
 "by a single expression. Remember that a block, `{ <expr1>; <expr2>; ... }`, "
@@ -2596,7 +2586,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1455
+#: doc/tutorial.md:1451
 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 "
@@ -2605,12 +2595,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1459
-msgid "~~~~ let square = |x: int| -> uint { x * x as uint }; ~~~~"
+#: doc/tutorial.md:1455
+msgid "~~~~ let square = |x: int| -> uint { (x * x) as uint }; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1463
+#: doc/tutorial.md:1459
 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 "
@@ -2618,12 +2608,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1468
+#: doc/tutorial.md:1464
 msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1477
+#: doc/tutorial.md:1473
 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 "
@@ -2635,12 +2625,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1479
+#: doc/tutorial.md:1475
 msgid "## Managed closures"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1485
+#: doc/tutorial.md:1481
 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 "
@@ -2650,7 +2640,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1490
+#: doc/tutorial.md:1486
 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. "
@@ -2659,14 +2649,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1493
+#: doc/tutorial.md:1489
 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:1499
+#: doc/tutorial.md:1495
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2677,7 +2667,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1505
+#: doc/tutorial.md:1501
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -2688,12 +2678,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1507
+#: doc/tutorial.md:1503
 msgid "## Owned closures"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1514
+#: doc/tutorial.md:1510
 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 "
@@ -2703,17 +2693,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1516
-msgid "[tasks]: tutorial-tasks.html"
-msgstr ""
-
-#. type: Plain text
-#: doc/tutorial.md:1518
+#: doc/tutorial.md:1512
 msgid "## Closure compatibility"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1525
+#: doc/tutorial.md:1519
 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 "
@@ -2724,7 +2709,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1533
+#: doc/tutorial.md:1527
 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 "
@@ -2732,7 +2717,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1537
+#: doc/tutorial.md:1531
 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 "
@@ -2740,26 +2725,26 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1539
+#: doc/tutorial.md:1533
 msgid "## Do syntax"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1542
+#: doc/tutorial.md:1536
 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:1545
+#: doc/tutorial.md:1539
 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:1555
+#: doc/tutorial.md:1549
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2774,14 +2759,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1559
+#: doc/tutorial.md:1553
 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:1567
+#: doc/tutorial.md:1561
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2794,14 +2779,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1570
+#: doc/tutorial.md:1564
 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:1578
+#: doc/tutorial.md:1572
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -2814,7 +2799,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1583
+#: doc/tutorial.md:1577
 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, "
@@ -2822,7 +2807,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1588
+#: doc/tutorial.md:1582
 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 "
@@ -2830,12 +2815,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1591
+#: doc/tutorial.md:1585 doc/tutorial.md:1597
 msgid "~~~~ use std::task::spawn;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1596
+#: doc/tutorial.md:1590
 #, no-wrap
 msgid ""
 "do spawn() || {\n"
@@ -2845,7 +2830,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1600
+#: doc/tutorial.md:1594
 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 "
@@ -2853,11 +2838,9 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1607
+#: doc/tutorial.md:1602
 #, no-wrap
 msgid ""
-"~~~~\n"
-"# use std::task::spawn;\n"
 "do spawn {\n"
 "   debug!(\"Kablam!\");\n"
 "}\n"
@@ -2865,7 +2848,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1610
+#: doc/tutorial.md:1605
 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 "
@@ -2874,12 +2857,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1612
+#: doc/tutorial.md:1607
 msgid "# Methods"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1618
+#: doc/tutorial.md:1613
 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 "
@@ -2888,7 +2871,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1622
+#: doc/tutorial.md:1617
 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 "
@@ -2896,7 +2879,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1630
+#: doc/tutorial.md:1625
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2909,7 +2892,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1635
+#: doc/tutorial.md:1630
 #, no-wrap
 msgid ""
 "enum Shape {\n"
@@ -2919,7 +2902,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1644
+#: doc/tutorial.md:1639
 #, no-wrap
 msgid ""
 "impl Shape {\n"
@@ -2933,12 +2916,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1648
+#: doc/tutorial.md:1643
 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1652
+#: doc/tutorial.md:1647
 msgid ""
 "This defines an _implementation_ for `Shape` containing a single method, "
 "`draw`. In most respects the `draw` method is defined like any other "
@@ -2946,7 +2929,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1657
+#: doc/tutorial.md:1652
 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`, "
@@ -2955,7 +2938,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1672
+#: doc/tutorial.md:1667
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -2975,26 +2958,26 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1674
+#: doc/tutorial.md:1669
 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1680
+#: doc/tutorial.md:1675
 msgid ""
 "(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s."
 "draw_value(); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1684
+#: doc/tutorial.md:1679
 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:1702
+#: doc/tutorial.md:1697
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -3017,29 +3000,29 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1705
+#: doc/tutorial.md:1700
 msgid "(@s).draw_borrowed(); (~s).draw_borrowed();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1709
+#: doc/tutorial.md:1704
 msgid ""
 "// Unlike typical function arguments, the self value will // automatically "
 "be referenced ...  s.draw_borrowed();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1712
+#: doc/tutorial.md:1707
 msgid "// ... and dereferenced (& &s).draw_borrowed();"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1716
+#: doc/tutorial.md:1711
 msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1720
+#: doc/tutorial.md:1715
 msgid ""
 "Implementations may also define standalone (sometimes called \"static\")  "
 "methods. The absence of a `self` parameter distinguishes such methods.  "
@@ -3047,7 +3030,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1727
+#: doc/tutorial.md:1722
 #, no-wrap
 msgid ""
 "~~~~ {.xfail-test}\n"
@@ -3059,17 +3042,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1729
+#: doc/tutorial.md:1724
 msgid ""
 "To call such a method, just prefix it with the type name and a double colon:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1738
+#: doc/tutorial.md:1733
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::float::consts::pi;\n"
+"use std::float::consts::pi;\n"
 "struct Circle { radius: float }\n"
 "impl Circle {\n"
 "    fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n"
@@ -3079,12 +3062,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1740
+#: doc/tutorial.md:1735
 msgid "# Generics"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1748
+#: doc/tutorial.md:1743
 msgid ""
 "Throughout this tutorial, we've been defining functions that act only on "
 "specific data types. With type parameters we can also define functions whose "
@@ -3095,7 +3078,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1758
+#: doc/tutorial.md:1753
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3110,7 +3093,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1763
+#: doc/tutorial.md:1758
 msgid ""
 "When defined with type parameters, as denoted by `<T, U>`, this function can "
 "be applied to any type of vector, as long as the type of `function`'s "
@@ -3118,7 +3101,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1773
+#: doc/tutorial.md:1768
 msgid ""
 "Inside a generic function, the names of the type parameters (capitalized by "
 "convention) stand for opaque types. All you can do with instances of these "
@@ -3131,18 +3114,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1775
+#: doc/tutorial.md:1770
 msgid ""
 "Generic `type`, `struct`, and `enum` declarations follow the same pattern:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1779
-msgid "~~~~ use std::hashmap::HashMap; type Set<T> = HashMap<T, ()>;"
+#: doc/tutorial.md:1774
+msgid "~~~~ use std::hashmap::HashMap; type Set<T> = HashMap<T, ()>;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1783
+#: doc/tutorial.md:1778
 #, no-wrap
 msgid ""
 "struct Stack<T> {\n"
@@ -3151,7 +3134,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1789
+#: doc/tutorial.md:1784
 #, no-wrap
 msgid ""
 "enum Option<T> {\n"
@@ -3162,14 +3145,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1792
+#: doc/tutorial.md:1787
 msgid ""
 "These declarations can be instantiated to valid types like `Set<int>`, "
 "`Stack<int>`, and `Option<int>`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1798
+#: doc/tutorial.md:1793
 msgid ""
 "The last type in that example, `Option`, appears frequently in Rust code.  "
 "Because Rust does not have null pointers (except in unsafe code), we need "
@@ -3179,7 +3162,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1809
+#: doc/tutorial.md:1804
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3195,7 +3178,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1817
+#: doc/tutorial.md:1812
 msgid ""
 "The Rust compiler compiles generic functions very efficiently by "
 "*monomorphizing* them. *Monomorphization* is a fancy name for a simple idea: "
@@ -3206,12 +3189,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1819
+#: doc/tutorial.md:1814
 msgid "## Traits"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1829
+#: doc/tutorial.md:1824
 msgid ""
 "Within a generic function the operations available on generic types are very "
 "limited. After all, since the function doesn't know what types it is "
@@ -3224,26 +3207,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1836
+#: doc/tutorial.md:1832
 msgid ""
-"As motivation, let us consider copying in Rust. The `copy` operation is not "
-"defined for all Rust types. One reason is user-defined destructors: copying "
+"As motivation, let us consider copying in Rust.  The `clone` method is not "
+"defined for all Rust types.  One reason is user-defined destructors: copying "
 "a type that has a destructor could result in the destructor running multiple "
-"times. Therefore, types with user-defined destructors cannot be copied, "
-"either implicitly or explicitly, and neither can types that own other types "
-"containing destructors."
+"times.  Therefore, types with destructors cannot be copied unless you "
+"explicitly implement `Clone` for them."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1840
+#: doc/tutorial.md:1837
 msgid ""
-"This complicates handling of generic functions. If you have a type parameter "
-"`T`, can you copy values of that type? In Rust, you can't, and if you try to "
-"run the following code the compiler will complain."
+"This complicates handling of generic functions.  If you have a type "
+"parameter `T`, can you copy values of that type? In Rust, you can't, and if "
+"you try to run the following code the compiler will complain."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1847
+#: doc/tutorial.md:1844
 #, no-wrap
 msgid ""
 "~~~~ {.xfail-test}\n"
@@ -3255,77 +3237,71 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1852
+#: doc/tutorial.md:1851
 msgid ""
 "However, we can tell the compiler that the `head` function is only for "
-"copyable types: that is, those that have the `Copy` trait. In that case, we "
-"can explicitly create a second copy of the value we are returning using the "
-"`copy` keyword:"
+"copyable types: that is, those that implement the `Clone` trait.  In that "
+"case, we can explicitly create a second copy of the value we are returning "
+"using the `clone` keyword:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1859
+#: doc/tutorial.md:1858
 #, no-wrap
 msgid ""
 "~~~~\n"
 "// This does\n"
-"fn head<T: Copy>(v: &[T]) -> T {\n"
-"    copy v[0]\n"
+"fn head<T: Clone>(v: &[T]) -> T {\n"
+"    v[0].clone()\n"
 "}\n"
 "~~~~\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1867
+#: doc/tutorial.md:1866
 msgid ""
 "This says that we can call `head` on any type `T` as long as that type "
-"implements the `Copy` trait. When instantiating a generic function, you can "
-"only instantiate it with types that implement the correct trait, so you "
-"could not apply `head` to a type with a destructor. (`Copy` is a special "
-"trait that is built in to the compiler, making it possible for the compiler "
-"to enforce this restriction.)"
+"implements the `Clone` trait.  When instantiating a generic function, you "
+"can only instantiate it with types that implement the correct trait, so you "
+"could not apply `head` to a type that does not implement `Clone`."
 msgstr ""
 
 #. type: Plain text
 #: doc/tutorial.md:1871
 msgid ""
-"While most traits can be defined and implemented by user code, three traits "
+"While most traits can be defined and implemented by user code, two traits "
 "are automatically derived and implemented for all applicable types by the "
 "compiler, and may not be overridden:"
 msgstr ""
 
-#. type: Bullet: '* '
+#. type: Plain text
 #: doc/tutorial.md:1875
+#, no-wrap
 msgid ""
-"`Copy` - Types that can be copied, either implicitly, or explicitly with the "
-"`copy` operator. All types are copyable unless they have destructors or "
-"contain types with destructors."
-msgstr ""
-
-#. type: Bullet: '* '
-#: doc/tutorial.md:1879
-msgid ""
-"`Owned` - Owned types. Types are owned unless they contain managed boxes, "
-"managed closures, or borrowed pointers. Owned types may or may not be "
-"copyable."
+"* `Send` - Sendable types.\n"
+"Types are sendable\n"
+"unless they contain managed boxes, managed closures, or borrowed pointers.\n"
 msgstr ""
 
-#. type: Bullet: '* '
-#: doc/tutorial.md:1882
+#. type: Plain text
+#: doc/tutorial.md:1880
+#, no-wrap
 msgid ""
-"`Const` - Constant (immutable) types. These are types that do not contain "
-"mutable fields."
+"* `Freeze` - Constant (immutable) types.\n"
+"These are types that do not contain anything intrinsically mutable.\n"
+"Intrinsically mutable values include `@mut`\n"
+"and `Cell` in the standard library.\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1885
+#: doc/tutorial.md:1883
 msgid ""
-"> ***Note:*** These three traits were referred to as 'kinds' in earlier > "
+"> ***Note:*** These two traits were referred to as 'kinds' in earlier > "
 "iterations of the language, and often still are."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1891
+#: doc/tutorial.md:1889
 msgid ""
 "Additionally, the `Drop` trait is used to define destructors. This trait "
 "defines one method called `drop`, which is automatically called when a value "
@@ -3334,7 +3310,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1896
+#: doc/tutorial.md:1894
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -3344,12 +3320,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1905
+#: doc/tutorial.md:1903
 #, no-wrap
 msgid ""
 "impl Drop for TimeBomb {\n"
 "    fn drop(&self) {\n"
-"        for self.explosivity.times {\n"
+"        for _ in range(0, self.explosivity) {\n"
 "            println(\"blam!\");\n"
 "        }\n"
 "    }\n"
@@ -3358,28 +3334,28 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1908
+#: doc/tutorial.md:1906
 msgid ""
 "It is illegal to call `drop` directly. Only code inserted by the compiler "
 "may call it."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1910
+#: doc/tutorial.md:1908
 msgid "## Declaring and implementing traits"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1915
+#: doc/tutorial.md:1914
 msgid ""
-"A trait consists of a set of methods, without bodies, or may be empty, as is "
-"the case with `Copy`, `Owned`, and `Const`. For example, we could declare "
-"the trait `Printable` for things that can be printed to the console, with a "
-"single method:"
+"A trait consists of a set of methods without bodies, or may be empty, as is "
+"the case with `Send` and `Freeze`.  For example, we could declare the trait "
+"`Printable` for things that can be printed to the console, with a single "
+"method:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1921
+#: doc/tutorial.md:1920
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3390,7 +3366,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1926
+#: doc/tutorial.md:1925
 msgid ""
 "Traits may be implemented for specific types with [impls]. An impl that "
 "implements a trait includes the name of the trait at the start of the "
@@ -3398,12 +3374,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1928
-msgid "[impls]: #functions-and-methods"
+#: doc/tutorial.md:1927
+msgid "[impls]: #methods"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1934
+#: doc/tutorial.md:1933
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3414,7 +3390,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1938
+#: doc/tutorial.md:1937
 #, no-wrap
 msgid ""
 "impl Printable for ~str {\n"
@@ -3423,12 +3399,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1942
+#: doc/tutorial.md:1941
 msgid "# 1.print(); # (~\"foo\").print(); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1947
+#: doc/tutorial.md:1946
 msgid ""
 "Methods defined in an implementation of a trait may be called just like any "
 "other method, using dot notation, as in `1.print()`. Traits may themselves "
@@ -3437,7 +3413,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1952
+#: doc/tutorial.md:1951
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3447,7 +3423,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1957
+#: doc/tutorial.md:1956
 #, no-wrap
 msgid ""
 "impl<T> Seq<T> for ~[T] {\n"
@@ -3457,7 +3433,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1964
+#: doc/tutorial.md:1963
 msgid ""
 "The implementation has to explicitly declare the type parameter that it "
 "binds, `T`, before using it to specify its trait type. Rust requires this "
@@ -3467,7 +3443,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1969
+#: doc/tutorial.md:1968
 msgid ""
 "The type parameters bound by a trait are in scope in each of the method "
 "declarations. So, re-declaring the type parameter `T` as an explicit type "
@@ -3476,7 +3452,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1974
+#: doc/tutorial.md:1973
 msgid ""
 "Within a trait definition, `Self` is a special type that you can think of as "
 "a type parameter. An implementation of the trait for any given type `T` "
@@ -3485,7 +3461,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1981
+#: doc/tutorial.md:1980
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3497,7 +3473,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1987
+#: doc/tutorial.md:1986
 #, no-wrap
 msgid ""
 "// In an impl, `self` refers just to the value of the receiver\n"
@@ -3508,7 +3484,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1992
+#: doc/tutorial.md:1991
 msgid ""
 "Notice that in the trait definition, `equals` takes a second parameter of "
 "type `Self`.  In contrast, in the `impl`, `equals` takes a second parameter "
@@ -3516,7 +3492,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:1997
+#: doc/tutorial.md:1996
 msgid ""
 "Just as in type implementations, traits can define standalone (static)  "
 "methods.  These methods are called by prefixing the method name with the "
@@ -3525,14 +3501,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2003
+#: doc/tutorial.md:2002
 msgid ""
-"~~~~ use std::float::consts::pi; trait Shape { fn new(area: 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:2010
+#: doc/tutorial.md:2009
 #, no-wrap
 msgid ""
 "impl Shape for Circle {\n"
@@ -3544,19 +3520,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2015
+#: doc/tutorial.md:2014
 msgid ""
 "let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::"
 "new(area); ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2017
+#: doc/tutorial.md:2016
 msgid "## Bounded type parameters and static method dispatch"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2022
+#: doc/tutorial.md:2021
 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_ "
@@ -3564,7 +3540,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2031
+#: doc/tutorial.md:2030
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3578,32 +3554,32 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2037
+#: doc/tutorial.md:2036
 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 "
+"`Clone`) makes it possible to call methods from that trait on values of type "
 "`T` inside the function. It will also cause a compile-time error when anyone "
 "tries to call `print_all` on an array whose element type does not have a "
 "`Printable` implementation."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2040
+#: doc/tutorial.md:2039
 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:2052
+#: doc/tutorial.md:2051
 #, no-wrap
 msgid ""
 "~~~\n"
 "# trait Printable { fn print(&self); }\n"
-"fn print_all<T: Printable + Copy>(printable_things: ~[T]) {\n"
+"fn print_all<T: Printable + Clone>(printable_things: ~[T]) {\n"
 "    let mut i = 0;\n"
 "    while i < printable_things.len() {\n"
-"        let copy_of_thing = copy printable_things[i];\n"
+"        let copy_of_thing = printable_things[i].clone();\n"
 "        copy_of_thing.print();\n"
 "        i += 1;\n"
 "    }\n"
@@ -3612,7 +3588,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2056
+#: doc/tutorial.md:2055
 msgid ""
 "Method calls to bounded type parameters are _statically dispatched_, "
 "imposing no more overhead than normal function invocation, so are the "
@@ -3620,17 +3596,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2058
+#: doc/tutorial.md:2057
 msgid "This usage of traits is similar to Haskell type classes."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2060
+#: doc/tutorial.md:2059
 msgid "## Trait objects and dynamic method dispatch"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2064
+#: doc/tutorial.md:2063
 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 "
@@ -3638,7 +3614,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2070
+#: doc/tutorial.md:2069
 msgid ""
 "~~~~ # type Circle = int; type Rectangle = int; # impl Drawable for int { fn "
 "draw(&self) {} } # fn new_circle() -> int { 1 } trait Drawable { fn "
@@ -3646,7 +3622,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2077
+#: doc/tutorial.md:2076
 #, no-wrap
 msgid ""
 "fn draw_all<T: Drawable>(shapes: ~[T]) {\n"
@@ -3658,7 +3634,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2083
+#: doc/tutorial.md:2082
 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 "
@@ -3667,7 +3643,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2090
+#: doc/tutorial.md:2089
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3679,7 +3655,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2095
+#: doc/tutorial.md:2094
 msgid ""
 "In this example, there is no type parameter. Instead, the `@Drawable` type "
 "denotes any managed box value that implements the `Drawable` trait. To "
@@ -3688,7 +3664,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2102
+#: doc/tutorial.md:2101
 msgid ""
 "~~~~ # type Circle = int; type Rectangle = bool; # trait Drawable { fn "
 "draw(&self); } # fn new_circle() -> Circle { 1 } # fn new_rectangle() -> "
@@ -3696,21 +3672,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2105
+#: doc/tutorial.md:2104
 msgid ""
 "impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for "
 "Rectangle { fn draw(&self) { ... } }"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2110
+#: doc/tutorial.md:2109
 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:2118
+#: doc/tutorial.md:2117
 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 "
@@ -3721,7 +3697,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2132
+#: doc/tutorial.md:2131
 msgid ""
 "~~~ # type Circle = int; type Rectangle = int; # trait Drawable { fn "
 "draw(&self); } # impl Drawable for int { fn draw(&self) {} } # fn "
@@ -3732,7 +3708,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2137
+#: doc/tutorial.md:2136
 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 "
@@ -3741,17 +3717,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2139
+#: doc/tutorial.md:2138
 msgid "This usage of traits is similar to Java interfaces."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2141
+#: doc/tutorial.md:2140
 msgid "## Trait inheritance"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2146
+#: doc/tutorial.md:2145
 msgid ""
 "We can write a trait declaration that _inherits_ from other traits, called "
 "_supertraits_.  Types that implement a trait must also implement its "
@@ -3760,24 +3736,24 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2151
+#: doc/tutorial.md:2150
 msgid ""
 "~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn "
 "radius(&self) -> float; } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2153
+#: doc/tutorial.md:2152
 msgid ""
 "Now, we can implement `Circle` on a type only if we also implement `Shape`."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2168
+#: doc/tutorial.md:2167
 #, no-wrap
 msgid ""
 "~~~~\n"
-"use std::float::consts::pi;\n"
+"use std::float::consts::pi;\n"
 "# trait Shape { fn area(&self) -> float; }\n"
 "# trait Circle : Shape { fn radius(&self) -> float; }\n"
 "# struct Point { x: float, y: float }\n"
@@ -3793,7 +3769,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2173
+#: doc/tutorial.md:2172
 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 "
@@ -3802,36 +3778,36 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2197
+#: doc/tutorial.md:2196
 msgid ""
-"~~~ {.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) } }"
+"~~~ {.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:2202
+#: doc/tutorial.md:2201
 msgid ""
 "let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; let "
-"mycircle: Circle = concrete as @Circle; let nonsense = mycircle.radius() * "
+"mycircle: @Circle = concrete as @Circle; let nonsense = mycircle.radius() * "
 "mycircle.area(); ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2204
+#: doc/tutorial.md:2203
 msgid "> ***Note:*** Trait inheritance does not actually work with objects yet"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2206
+#: doc/tutorial.md:2205
 msgid "## Deriving implementations for traits"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2213
+#: doc/tutorial.md:2212
 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 "
@@ -3842,17 +3818,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2217
+#: doc/tutorial.md:2216
 msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2221
+#: doc/tutorial.md:2220
 msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2225
+#: doc/tutorial.md:2224
 msgid ""
 "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
 "`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, "
@@ -3860,19 +3836,19 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2227
+#: doc/tutorial.md:2226
 msgid "# Modules and crates"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2231
+#: doc/tutorial.md:2230
 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:2237
+#: doc/tutorial.md:2236
 #, no-wrap
 msgid ""
 "~~~~\n"
@@ -3883,7 +3859,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2242
+#: doc/tutorial.md:2241
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -3893,7 +3869,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2247
+#: doc/tutorial.md:2246
 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 "
@@ -3901,14 +3877,14 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2253
+#: doc/tutorial.md:2252
 msgid ""
 "~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` "
 "into scope use farm::chicken;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2263
+#: doc/tutorial.md:2262
 #, no-wrap
 msgid ""
 "fn chicken_farmer() {\n"
@@ -3923,7 +3899,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2270
+#: doc/tutorial.md:2269
 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 "
@@ -3933,7 +3909,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2277
+#: doc/tutorial.md:2276
 msgid ""
 "Visibility restrictions in Rust exist only at module boundaries. This is "
 "quite different from most object-oriented languages that also enforce "
@@ -3944,7 +3920,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2290
+#: doc/tutorial.md:2289
 #, no-wrap
 msgid ""
 "~~~\n"
@@ -3962,18 +3938,18 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2296
+#: doc/tutorial.md:2295
 #, no-wrap
 msgid ""
 "    impl Farm {\n"
-"        priv fn feed_chickens(&self) { ... }\n"
-"        priv fn feed_cows(&self) { ... }\n"
+"        fn feed_chickens(&self) { ... }\n"
+"        fn feed_cows(&self) { ... }\n"
 "        pub fn add_chicken(&self, c: Chicken) { ... }\n"
 "    }\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2302
+#: doc/tutorial.md:2301
 #, no-wrap
 msgid ""
 "    pub fn feed_animals(farm: &Farm) {\n"
@@ -3984,7 +3960,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2312
+#: doc/tutorial.md:2311
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -3999,12 +3975,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2314
+#: doc/tutorial.md:2313
 msgid "## Crates"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2318
+#: doc/tutorial.md:2317
 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 "
@@ -4012,7 +3988,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2323
+#: doc/tutorial.md:2322
 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 "
@@ -4021,7 +3997,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2328
+#: doc/tutorial.md:2327
 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 "
@@ -4030,7 +4006,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2337
+#: doc/tutorial.md:2336
 msgid ""
 "A typical crate file declares attributes associated with the crate that may "
 "affect how the compiler processes the source.  Crate attributes specify "
@@ -4041,34 +4017,34 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2341
+#: doc/tutorial.md:2340
 msgid ""
 "~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers "
 "= \"2.5\", author = \"mjh\")];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2344
+#: doc/tutorial.md:2343
 msgid "// Make a library (\"bin\" is the default)  #[crate_type = \"lib\"];"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2347
+#: doc/tutorial.md:2346
 msgid "// Turn on a warning #[warn(non_camel_case_types)]"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2350
+#: doc/tutorial.md:2349
 msgid "// Link to the standard library extern mod std;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2355
+#: doc/tutorial.md:2354
 msgid "// Load some modules from other files mod cow; mod chicken; mod horse;"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2360
+#: doc/tutorial.md:2359
 #, no-wrap
 msgid ""
 "fn main() {\n"
@@ -4078,7 +4054,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2367
+#: doc/tutorial.md:2366
 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, "
@@ -4088,21 +4064,21 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2371
+#: doc/tutorial.md:2370
 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:2374
+#: doc/tutorial.md:2373
 msgid ""
 "To have a nested directory structure for your source files, you can nest "
 "mods:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2381
+#: doc/tutorial.md:2380
 #, no-wrap
 msgid ""
 "~~~~ {.ignore}\n"
@@ -4114,7 +4090,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2386
+#: doc/tutorial.md:2385
 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 "
@@ -4123,12 +4099,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2388
+#: doc/tutorial.md:2387
 msgid "## Using other crates"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2396
+#: doc/tutorial.md:2395
 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 "
@@ -4139,17 +4115,17 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2398
+#: doc/tutorial.md:2397
 msgid "For example, `extern mod std` links the [standard library]."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2400
+#: doc/tutorial.md:2399
 msgid "[standard library]: std/index.html"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2407
+#: doc/tutorial.md:2406
 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 "
@@ -4159,22 +4135,22 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2409
+#: doc/tutorial.md:2408
 msgid "Our example crate declared this set of `link` attributes:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2413
+#: doc/tutorial.md:2412
 msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2415
+#: doc/tutorial.md:2414
 msgid "Which you can then link with any (or all) of the following:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2421
+#: doc/tutorial.md:2420
 msgid ""
 "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", "
 "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = "
@@ -4182,45 +4158,45 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2424
+#: doc/tutorial.md:2423
 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:2426
+#: doc/tutorial.md:2425
 msgid "## A minimal example"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2429
+#: doc/tutorial.md:2428
 msgid ""
 "Now for something that you can actually compile yourself, we have these two "
 "files:"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2435
+#: doc/tutorial.md:2434
 msgid ""
 "~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() "
 "-> &str { \"world\" } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2441
+#: doc/tutorial.md:2440
 msgid ""
 "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello "
 "\" + world::explore()); } ~~~~"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2443
+#: doc/tutorial.md:2442
 msgid "Now compile and run like this (adjust to your platform if necessary):"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2450
+#: doc/tutorial.md:2449
 #, no-wrap
 msgid ""
 "~~~~ {.notrust}\n"
@@ -4232,7 +4208,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2455
+#: doc/tutorial.md:2454
 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 "
@@ -4241,12 +4217,12 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2457
+#: doc/tutorial.md:2456
 msgid "## The standard library"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2462
+#: doc/tutorial.md:2461
 msgid ""
 "The Rust standard library provides runtime features required by the "
 "language, including the task scheduler and memory allocators, as well as "
@@ -4255,7 +4231,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2473
+#: doc/tutorial.md:2472
 msgid ""
 "[`std`] includes modules corresponding to each of the integer types, each of "
 "the floating point types, the [`bool`] type, [tuples], [characters], "
@@ -4269,25 +4245,25 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2475
+#: doc/tutorial.md:2474
 msgid "### Standard Library injection and the Rust prelude"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2478
+#: doc/tutorial.md:2477
 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:2480
+#: doc/tutorial.md:2479
 #, no-wrap
 msgid "    extern mod std;\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2484
+#: doc/tutorial.md:2483
 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`, "
@@ -4295,7 +4271,7 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2489
+#: doc/tutorial.md:2488
 msgid ""
 "Additionally, `std` contains a `prelude` module that reexports many of the "
 "most common standard modules, types and traits. The contents of the prelude "
@@ -4304,13 +4280,13 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2491
+#: doc/tutorial.md:2490
 #, no-wrap
 msgid "    use std::prelude::*;\n"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2517
+#: doc/tutorial.md:2516
 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 "
@@ -4324,66 +4300,55 @@ msgid ""
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2519
+#: doc/tutorial.md:2518
 msgid "# What next?"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2522
+#: doc/tutorial.md:2521
 msgid ""
 "Now that you know the essentials, check out any of the additional tutorials "
 "on individual topics."
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial.md:2528
+#: doc/tutorial.md:2527
 msgid "[Borrowed pointers][borrow]"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial.md:2528
+#: doc/tutorial.md:2527
 msgid "[Tasks and communication][tasks]"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial.md:2528
+#: doc/tutorial.md:2527
 msgid "[Macros][macros]"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial.md:2528
+#: doc/tutorial.md:2527
 msgid "[The foreign function interface][ffi]"
 msgstr ""
 
 #. type: Bullet: '* '
-#: doc/tutorial.md:2528
+#: doc/tutorial.md:2527
 msgid "[Containers and iterators](tutorial-container.html)"
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2530
+#: doc/tutorial.md:2529
 msgid "There is further documentation on the [wiki]."
 msgstr ""
 
 #. type: Plain text
-#: doc/tutorial.md:2535
+#: doc/tutorial.md:2534
 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: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/"
-"mozilla/rust/wiki/Doc-using-rustdoc [cargo]: https://github.com/mozilla/rust/"
-"wiki/Doc-using-cargo-to-manage-packages [attributes]: https://github.com/"
-"mozilla/rust/wiki/Doc-attributes"
-msgstr ""
-
-#. type: Plain text
-#: doc/tutorial.md:2542
-msgid ""
-"[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust"
+#: doc/tutorial.md:2536
+msgid "[wiki]: https://github.com/mozilla/rust/wiki/Docs"
 msgstr ""
index feedafcd391002d2a03e781c1ce2b6abac867d10..80687c1d999d039257815ae00ed1336047869038 100644 (file)
@@ -1,7 +1,7 @@
 # Add here a list of target languages; po4a will automatically
 # generates .po for them and build .md when translated, eg:
 # [po4a_langs] es fr it pt_BR
-[po4a_langs] 
+[po4a_langs] ja
 [po4a_paths] doc/po/$master.pot $lang:doc/po/$lang/$master.po
 
 # Add here below all source documents to be translated
index 19cd58bd3b403e03bf8d7aa46b01f45636ca12cb..1f47c3df14f89b346dd53542334f3d303f51e01f 100644 (file)
@@ -112,10 +112,10 @@ iterator object. For example, vector slices several iterators available:
 
 * `iter()` and `rev_iter()`, for immutable references to the elements
 * `mut_iter()` and `mut_rev_iter()`, for mutable references to the elements
-* `consume_iter()` and `consume_rev_iter`, to move the elements out by-value
+* `move_iter()` and `move_rev_iter`, to move the elements out by-value
 
 A typical mutable container will implement at least `iter()`, `mut_iter()` and
-`consume_iter()` along with the reverse variants if it maintains an order.
+`move_iter()` along with the reverse variants if it maintains an order.
 
 ### Freezing
 
@@ -139,9 +139,9 @@ and `&mut`.
 
 ## Iterator adaptors
 
-The `IteratorUtil` trait implements common algorithms as methods extending
-every `Iterator` implementation. For example, the `fold` method will accumulate
-the items yielded by an `Iterator` into a single value:
+The `Iterator` trait provides many common algorithms as default methods. For
+example, the `fold` method will accumulate the items yielded by an `Iterator`
+into a single value:
 
 ~~~
 let xs = [1, 9, 2, 3, 14, 12];
@@ -154,14 +154,10 @@ Some adaptors return an adaptor object implementing the `Iterator` trait itself:
 ~~~
 let xs = [1, 9, 2, 3, 14, 12];
 let ys = [5, 2, 1, 8];
-let sum = xs.iter().chain_(ys.iter()).fold(0, |a, b| a + *b);
+let sum = xs.iter().chain(ys.iter()).fold(0, |a, b| a + *b);
 assert_eq!(sum, 57);
 ~~~
 
-Note that some adaptors like the `chain_` method above use a trailing
-underscore to work around an issue with method resolve. The underscores will be
-dropped when they become unnecessary.
-
 ## For loops
 
 The `for` keyword can be used as sugar for iterating through any iterator:
@@ -212,7 +208,7 @@ Iterators offer generic conversion to containers with the `collect` adaptor:
 
 ~~~
 let xs = [0, 1, 1, 2, 3, 5, 8];
-let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~[int]>();
+let ys = xs.rev_iter().skip(1).map(|&x| x * 2).collect::<~[int]>();
 assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
 ~~~
 
@@ -224,8 +220,8 @@ implementing the `FromIterator` trait. For example, the implementation for
 vectors is as follows:
 
 ~~~
-impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
-    pub fn from_iterator(iterator: &mut T) -> ~[A] {
+impl<A> FromIterator<A> for ~[A] {
+    pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
         let mut xs = with_capacity(lower);
         for x in iterator {
@@ -307,13 +303,13 @@ for &x in it.invert() {
 The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
 version of the standard immutable and mutable vector iterators.
 
-The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are
+The `chain`, `map`, `filter`, `filter_map` and `inspect` adaptors are
 `DoubleEndedIterator` implementations if the underlying iterators are.
 
 ~~~
 let xs = [1, 2, 3, 4];
 let ys = [5, 6, 7, 8];
-let mut it = xs.iter().chain_(ys.iter()).transform(|&x| x * 2);
+let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2);
 
 printfln!("%?", it.next()); // prints `Some(2)`
 
@@ -329,13 +325,13 @@ The `RandomAccessIterator` trait represents an iterator offering random access
 to the whole range. The `indexable` method retrieves the number of elements
 accessible with the `idx` method.
 
-The `chain_` adaptor is an implementation of `RandomAccessIterator` if the
+The `chain` adaptor is an implementation of `RandomAccessIterator` if the
 underlying iterators are.
 
 ~~~
 let xs = [1, 2, 3, 4, 5];
 let ys = ~[7, 9, 11];
-let mut it = xs.iter().chain_(ys.iter());
+let mut it = xs.iter().chain(ys.iter());
 printfln!("%?", it.idx(0)); // prints `Some(&1)`
 printfln!("%?", it.idx(5)); // prints `Some(&7)`
 printfln!("%?", it.idx(7)); // prints `Some(&11)`
index f4264b0d5afc36d21b4ea116f6a607a9ad933fda..1813356a1f309ed0d1a900a76fac8472005ae15e 100644 (file)
@@ -436,7 +436,7 @@ control reaches the end of the block:
 fn signum(x: int) -> int {
     if x < 0 { -1 }
     else if x > 0 { 1 }
-    else { return 0 }
+    else { 0 }
 }
 ~~~~
 
index cc86111b728d4db37a06debd49a4038af0a690bf..16858628815b32aa24608ba3f97a07cb54cd62b3 100644 (file)
@@ -13,6 +13,7 @@
 ######################################################################
 
 DOCS :=
+DOCS_L10N :=
 
 
 ######################################################################
@@ -88,6 +89,16 @@ doc/tutorial.html: tutorial.md doc/version_info.html doc/rust.css
           --include-before-body=doc/version_info.html \
            --output=$@
 
+DOCS_L10N += doc/l10n/ja/tutorial.html
+doc/l10n/ja/tutorial.html: doc/l10n/ja/tutorial.md doc/version_info.html doc/rust.css
+       @$(call E, pandoc: $@)
+       $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight doc/l10n/ja/tutorial.md | \
+          $(CFG_PANDOC) --standalone --toc \
+           --section-divs --number-sections \
+           --from=markdown --to=html --css=../../rust.css \
+          --include-before-body=doc/version_info.html \
+           --output=$@
+
 DOCS += doc/tutorial-macros.html
 doc/tutorial-macros.html: tutorial-macros.md doc/version_info.html \
                                                  doc/rust.css
@@ -235,10 +246,13 @@ GENERATED += doc/version.md doc/version_info.html
 
 docs: $(DOCS)
 
-docs-l10n:
+docs-l10n: $(DOCS_L10N)
+
+doc/l10n/%.md: doc/po/%.md.po doc/po4a.conf
        po4a --copyright-holder="The Rust Project Developers" \
             --package-name="Rust" \
             --package-version="$(CFG_RELEASE)" \
+            -M UTF-8 -L UTF-8 \
             doc/po4a.conf
 
 .PHONY: docs-l10n
index a5d308007b48a3db5dc8042e5de20b32b06396c7..45e4f756d7a15752a7e3d3e7ed672ac2547c8296 100644 (file)
@@ -49,7 +49,7 @@ pub fn run(lib_path: &str,
 
     let env = env + target_env(lib_path, prog);
     let mut proc = run::Process::new(prog, args, run::ProcessOptions {
-        env: Some(env.slice(0, env.len())),
+        env: Some(env),
         dir: None,
         in_fd: None,
         out_fd: None,
index 788ed726d0fc0329187e434cac8ffe90189dce19..076e86dd5b04095e1988089e1bfcb353437b7e57 100644 (file)
@@ -573,16 +573,16 @@ impl<A> DoubleEndedIterator<A> for MoveIterator<A> {
     fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for DList<A> {
-    fn from_iterator(iterator: &mut T) -> DList<A> {
+impl<A> FromIterator<A> for DList<A> {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> DList<A> {
         let mut ret = DList::new();
         ret.extend(iterator);
         ret
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for DList<A> {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for DList<A> {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         for elt in *iterator { self.push_back(elt); }
     }
 }
@@ -1163,4 +1163,3 @@ fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
         }
     }
 }
-
index 4b94219b30d537237406faad9799e06da2cfefdd..4f0fed5fccf4781245f6eea55c4a72e0ffd66913 100644 (file)
@@ -190,8 +190,8 @@ fn next(&mut self) -> Option<(&'self T)> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<T: Ord, Iter: Iterator<T>> FromIterator<T, Iter> for PriorityQueue<T> {
-    fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
+impl<T: Ord> FromIterator<T> for PriorityQueue<T> {
+    fn from_iterator<Iter: Iterator<T>>(iter: &mut Iter) -> PriorityQueue<T> {
         let mut q = PriorityQueue::new();
         q.extend(iter);
 
@@ -199,8 +199,8 @@ fn from_iterator(iter: &mut Iter) -> PriorityQueue<T> {
     }
 }
 
-impl<T: Ord, Iter: Iterator<T>> Extendable<T, Iter> for PriorityQueue<T> {
-    fn extend(&mut self, iter: &mut Iter) {
+impl<T: Ord> Extendable<T> for PriorityQueue<T> {
+    fn extend<Iter: Iterator<T>>(&mut self, iter: &mut Iter) {
         let (lower, _) = iter.size_hint();
 
         let len = self.capacity();
index bb9ac74bc77ac3d51563e2a6b73ec8b32859e65a..a38cb580c50578aa066e9f4ff6e83d37d335d324 100644 (file)
@@ -322,8 +322,8 @@ fn ne(&self, other: &RingBuf<A>) -> bool {
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
-    fn from_iterator(iterator: &mut T) -> RingBuf<A> {
+impl<A> FromIterator<A> for RingBuf<A> {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> RingBuf<A> {
         let (lower, _) = iterator.size_hint();
         let mut deq = RingBuf::with_capacity(lower);
         deq.extend(iterator);
@@ -331,8 +331,8 @@ fn from_iterator(iterator: &mut T) -> RingBuf<A> {
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for RingBuf<A> {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for RingBuf<A> {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         for elt in *iterator {
             self.push_back(elt);
         }
index 9106d4cd684d916f5c6d58bcbb83dd87962cce90..ead1f276ca701a13c9b3c0fbf08e21bd4685de9c 100644 (file)
@@ -32,7 +32,7 @@ pub mod rustrt {
 
 /// Add a line to history
 pub unsafe fn add_history(line: &str) -> bool {
-    do line.to_c_str().with_ref |buf| {
+    do line.with_c_str |buf| {
         rustrt::linenoiseHistoryAdd(buf) == 1 as c_int
     }
 }
@@ -44,21 +44,21 @@ pub unsafe fn set_history_max_len(len: int) -> bool {
 
 /// Save line history to a file
 pub unsafe fn save_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistorySave(buf) == 1 as c_int
     }
 }
 
 /// Load line history from a file
 pub unsafe fn load_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistoryLoad(buf) == 1 as c_int
     }
 }
 
 /// Print out a prompt and then wait for input and return it
 pub unsafe fn read(prompt: &str) -> Option<~str> {
-    do prompt.to_c_str().with_ref |buf| {
+    do prompt.with_c_str |buf| {
         let line = rustrt::linenoise(buf);
 
         if line.is_null() { None }
@@ -80,7 +80,7 @@ pub unsafe fn complete(cb: CompletionCb) {
 
             unsafe {
                 do cb(str::raw::from_c_str(line)) |suggestion| {
-                    do suggestion.to_c_str().with_ref |buf| {
+                    do suggestion.with_c_str |buf| {
                         rustrt::linenoiseAddCompletion(completions, buf);
                     }
                 }
index c7920e727089059032033c9bb0f0084081d34271..bea7868fd32b7c96d0dbd4196ced81b76d5336fa 100644 (file)
@@ -782,11 +782,8 @@ fn test() {
 
 #[cfg(test)]
 mod test_qsort {
-
     use sort::*;
 
-    use std::vec;
-
     fn check_sort(v1: &mut [int], v2: &mut [int]) {
         let len = v1.len();
         fn leual(a: &int, b: &int) -> bool { *a <= *b }
@@ -835,9 +832,7 @@ fn test_simple() {
 
         let immut_names = names;
 
-        let pairs = vec::zip_slice(expected, immut_names);
-        for p in pairs.iter() {
-            let (a, b) = *p;
+        for (&a, &b) in expected.iter().zip(immut_names.iter()) {
             debug!("%d %d", a, b);
             assert_eq!(a, b);
         }
index 881d931fe0acc21749287991d5826564c8ded3c8..0868c767e168c545a6e1506b47a77ae59e3d1b9f 100644 (file)
@@ -291,10 +291,22 @@ pub fn write_boxplot(w: @io::Writer, s: &Summary, width_hint: uint) {
 
     let (q1,q2,q3) = s.quartiles;
 
-    let lomag = (10.0_f64).pow(&s.min.log10().floor());
-    let himag = (10.0_f64).pow(&(s.max.log10().floor()));
-    let lo = (s.min / lomag).floor() * lomag;
-    let hi = (s.max / himag).ceil() * himag;
+    // the .abs() handles the case where numbers are negative
+    let lomag = (10.0_f64).pow(&(s.min.abs().log10().floor()));
+    let himag = (10.0_f64).pow(&(s.max.abs().log10().floor()));
+
+    // need to consider when the limit is zero
+    let lo = if lomag == 0.0 {
+        0.0
+    } else {
+        (s.min / lomag).floor() * lomag
+    };
+
+    let hi = if himag == 0.0 {
+        0.0
+    } else {
+        (s.max / himag).ceil() * himag
+    };
 
     let range = hi - lo;
 
@@ -920,4 +932,21 @@ fn test_unif25() {
         };
         check(val, summ);
     }
+
+    #[test]
+    fn test_boxplot_nonpositive() {
+        fn t(s: &Summary, expected: ~str) {
+            let out = do io::with_str_writer |w|  {
+                write_boxplot(w, s, 30)
+            };
+
+            assert_eq!(out, expected);
+        }
+
+        t(&Summary::new([-2.0, -1.0]), ~"-2 |[------******#*****---]| -1");
+        t(&Summary::new([0.0, 2.0]), ~"0 |[-------*****#*******---]| 2");
+        t(&Summary::new([-2.0, 0.0]), ~"-2 |[------******#******---]| 0");
+
+    }
+
 }
index a9c3bf98cb6599684c13cfc5bb99bba9abe56e78..9778248f005423468d2f4e1d46ae60d65e3ce687 100644 (file)
@@ -1121,7 +1121,6 @@ mod tests {
 
     use std::either;
     use std::comm::{stream, SharedChan};
-    use std::vec;
     use tempfile;
     use std::os;
 
@@ -1309,14 +1308,8 @@ fn testfn() { }
               ~"test::parse_ignored_flag",
               ~"test::sort_tests"];
 
-        let pairs = vec::zip(expected, filtered);
-
-        for p in pairs.iter() {
-            match *p {
-                (ref a, ref b) => {
-                    assert!(*a == b.desc.name.to_str());
-                }
-            }
+        for (a, b) in expected.iter().zip(filtered.iter()) {
+            assert!(*a == b.desc.name.to_str());
         }
     }
 
index 486a7dab5c1bb105a58c797152254ef2be690c06..118754ec02830a1d5b6a3fee9e7f3e6e99a02125 100644 (file)
@@ -835,34 +835,34 @@ fn heir_swap<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>,
     };
 }
 
-impl<K: TotalOrd, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for TreeMap<K, V> {
-    fn from_iterator(iter: &mut T) -> TreeMap<K, V> {
+impl<K: TotalOrd, V> FromIterator<(K, V)> for TreeMap<K, V> {
+    fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> TreeMap<K, V> {
         let mut map = TreeMap::new();
         map.extend(iter);
         map
     }
 }
 
-impl<K: TotalOrd, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for TreeMap<K, V> {
+impl<K: TotalOrd, V> Extendable<(K, V)> for TreeMap<K, V> {
     #[inline]
-    fn extend(&mut self, iter: &mut T) {
+    fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
     }
 }
 
-impl<T: TotalOrd, Iter: Iterator<T>> FromIterator<T, Iter> for TreeSet<T> {
-    fn from_iterator(iter: &mut Iter) -> TreeSet<T> {
+impl<T: TotalOrd> FromIterator<T> for TreeSet<T> {
+    fn from_iterator<Iter: Iterator<T>>(iter: &mut Iter) -> TreeSet<T> {
         let mut set = TreeSet::new();
         set.extend(iter);
         set
     }
 }
 
-impl<T: TotalOrd, Iter: Iterator<T>> Extendable<T, Iter> for TreeSet<T> {
+impl<T: TotalOrd> Extendable<T> for TreeSet<T> {
     #[inline]
-    fn extend(&mut self, iter: &mut Iter) {
+    fn extend<Iter: Iterator<T>>(&mut self, iter: &mut Iter) {
         for elem in *iter {
             self.insert(elem);
         }
index ed6eab5de193a93f6e700f7c01e6e4d4cddf1099..91b6ee2411091982c3acb9766abd30d1c3a66ee0 100644 (file)
@@ -78,10 +78,10 @@ pub fn WriteOutputFile(sess: Session,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
     unsafe {
-        do Triple.to_c_str().with_ref |Triple| {
-            do Cpu.to_c_str().with_ref |Cpu| {
-                do Feature.to_c_str().with_ref |Feature| {
-                    do Output.to_c_str().with_ref |Output| {
+        do Triple.with_c_str |Triple| {
+            do Cpu.with_c_str |Cpu| {
+                do Feature.with_c_str |Feature| {
+                    do Output.with_c_str |Output| {
                         let result = llvm::LLVMRustWriteOutputFile(
                                 PM,
                                 M,
@@ -152,7 +152,7 @@ pub fn exec(sess: Session,
 
                 debug!("linking: %s", path);
 
-                do path.to_c_str().with_ref |buf_t| {
+                do path.with_c_str |buf_t| {
                     if !llvm::LLVMRustLoadCrate(manager, buf_t) {
                         llvm_err(sess, ~"Could not link");
                     }
@@ -171,7 +171,7 @@ pub fn exec(sess: Session,
             // Next, we need to get a handle on the _rust_main function by
             // looking up it's corresponding ValueRef and then requesting that
             // the execution engine compiles the function.
-            let fun = do "_rust_main".to_c_str().with_ref |entry| {
+            let fun = do "_rust_main".with_c_str |entry| {
                 llvm::LLVMGetNamedFunction(m, entry)
             };
             if fun.is_null() {
@@ -270,14 +270,14 @@ pub fn run_passes(sess: Session,
                   output_type_bitcode => {
                     if opts.optimize != session::No {
                         let filename = output.with_filetype("no-opt.bc");
-                        do filename.to_c_str().with_ref |buf| {
+                        do filename.with_c_str |buf| {
                             llvm::LLVMWriteBitcodeToFile(llmod, buf);
                         }
                     }
                   }
                   _ => {
                     let filename = output.with_filetype("bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf);
                     }
                   }
@@ -340,7 +340,7 @@ pub fn run_passes(sess: Session,
                     // Always output the bitcode file with --save-temps
 
                     let filename = output.with_filetype("opt.bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     };
                     // Save the assembly file if -S is used
@@ -401,13 +401,13 @@ pub fn run_passes(sess: Session,
 
             if output_type == output_type_llvm_assembly {
                 // Given options "-S --emit-llvm": output LLVM assembly
-                do output.to_c_str().with_ref |buf_o| {
+                do output.with_c_str |buf_o| {
                     llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o);
                 }
             } else {
                 // If only a bitcode file is asked for by using the
                 // '--emit-llvm' flag, then output it here
-                do output.to_c_str().with_ref |buf| {
+                do output.with_c_str |buf| {
                     llvm::LLVMWriteBitcodeToFile(llmod, buf);
                 }
             }
index 854d11fd3503599e030e2d33d8f8a9dbd36ceb21..29bc577dff960c844c87756c581062e487719d02 100644 (file)
@@ -173,7 +173,7 @@ pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~s
 }
 
 pub fn create_pass(name:&str) -> Option<PassRef> {
-    do name.to_c_str().with_ref |s| {
+    do name.with_c_str |s| {
         unsafe {
             let p = llvm::LLVMCreatePass(s);
             if p.is_null() {
index ca2e33b6a6dd5a9729a63fecfea75fa7d06edfff..89a8d33955d0e50faa1de34d984a19ff4b2aafd9 100644 (file)
@@ -65,14 +65,14 @@ pub fn source_name(input: &input) -> @str {
     }
 }
 
-pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
+pub fn default_configuration(sess: Session) ->
    ast::CrateConfig {
-    let (libc, tos) = match sess.targ_cfg.os {
-        session::os_win32 =>   (@"msvcrt.dll", @"win32"),
-        session::os_macos =>   (@"libc.dylib", @"macos"),
-        session::os_linux =>   (@"libc.so.6",  @"linux"),
-        session::os_android => (@"libc.so",    @"android"),
-        session::os_freebsd => (@"libc.so.7",  @"freebsd")
+    let tos = match sess.targ_cfg.os {
+        session::os_win32 =>   @"win32",
+        session::os_macos =>   @"macos",
+        session::os_linux =>   @"linux",
+        session::os_android => @"android",
+        session::os_freebsd => @"freebsd"
     };
 
     // ARM is bi-endian, however using NDK seems to default
@@ -92,10 +92,7 @@ pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
          mk(@"target_arch", arch),
          mk(@"target_endian", end),
          mk(@"target_word_size", wordsz),
-         mk(@"target_libc", libc),
-         // Build bindings.
-         mk(@"build_compiler", argv0),
-         mk(@"build_input", source_name(input))];
+    ];
 }
 
 pub fn append_configuration(cfg: &mut ast::CrateConfig, name: @str) {
@@ -104,11 +101,11 @@ pub fn append_configuration(cfg: &mut ast::CrateConfig, name: @str) {
     }
 }
 
-pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
+pub fn build_configuration(sess: Session) ->
    ast::CrateConfig {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items
-    let default_cfg = default_configuration(sess, argv0, input);
+    let default_cfg = default_configuration(sess);
     let mut user_cfg = sess.opts.cfg.clone();
     // If the user wants a test runner, then add the test cfg
     if sess.opts.test { append_configuration(&mut user_cfg, @"test") }
@@ -980,7 +977,7 @@ pub fn list_metadata(sess: Session, path: &Path, out: @io::Writer) {
 mod test {
 
     use driver::driver::{build_configuration, build_session};
-    use driver::driver::{build_session_options, optgroups, str_input};
+    use driver::driver::{build_session_options, optgroups};
 
     use extra::getopts::groups::getopts;
     use extra::getopts;
@@ -998,7 +995,7 @@ fn test_switch_implies_cfg_test() {
         let sessopts = build_session_options(
             @"rustc", matches, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, @"whatever", &str_input(@""));
+        let cfg = build_configuration(sess);
         assert!((attr::contains_name(cfg, "test")));
     }
 
@@ -1016,7 +1013,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
         let sessopts = build_session_options(
             @"rustc", matches, diagnostic::emit);
         let sess = build_session(sessopts, diagnostic::emit);
-        let cfg = build_configuration(sess, @"whatever", &str_input(@""));
+        let cfg = build_configuration(sess);
         let mut test_items = cfg.iter().filter(|m| "test" == m.name());
         assert!(test_items.next().is_some());
         assert!(test_items.next().is_none());
index 156aafacfec628d5b375ab75d7ae30a7268f5f0d..307b691a56e67de588840ade9a7d577ddd346ae7 100644 (file)
@@ -2271,7 +2271,7 @@ pub struct TargetData {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let lltd = do string_rep.to_c_str().with_ref |buf| {
+    let lltd = do string_rep.with_c_str |buf| {
         unsafe { llvm::LLVMCreateTargetData(buf) }
     };
 
index eaf01241c8165d0b9eebc00a591edccb5d233b3e..c8c4a396c87af99c0041f1274fcd3acf92b353c7 100644 (file)
@@ -57,6 +57,7 @@ pub fn read_crates(diag: @mut span_handler,
     warn_if_multiple_versions(e, diag, *e.crate_cache);
 }
 
+#[deriving(Clone)]
 struct cache_entry {
     cnum: int,
     span: span,
@@ -76,22 +77,13 @@ fn dump_crates(crate_cache: &[cache_entry]) {
 fn warn_if_multiple_versions(e: @mut Env,
                              diag: @mut span_handler,
                              crate_cache: &[cache_entry]) {
-    use std::either::*;
-
     if crate_cache.len() != 0u {
         let name = loader::crate_name_from_metas(
             *crate_cache[crate_cache.len() - 1].metas
         );
 
-        let vec: ~[Either<cache_entry, cache_entry>] = crate_cache.iter().map(|&entry| {
-            let othername = loader::crate_name_from_metas(*entry.metas);
-            if name == othername {
-                Left(entry)
-            } else {
-                Right(entry)
-            }
-        }).collect();
-        let (matches, non_matches) = partition(vec);
+        let (matches, non_matches) = crate_cache.partitioned(|entry|
+            name == loader::crate_name_from_metas(*entry.metas));
 
         assert!(!matches.is_empty());
 
index 9366d757dd476befc73bda2253cb9311e929aaa0..4a3704dc3aa4e2a5198849d83b99847c2619b55e 100644 (file)
@@ -39,7 +39,8 @@
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::span_handler;
 use syntax::parse::token::special_idents;
-use syntax::{ast_util, oldvisit};
+use syntax::ast_util;
+use syntax::visit;
 use syntax::parse::token;
 use syntax;
 use writer = extra::ebml::writer;
@@ -1184,6 +1185,74 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
+fn my_visit_expr(_e:@expr) { }
+
+fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
+                 ecx_ptr:*int, index: @mut ~[entry<i64>]) {
+    match items.get_copy(&i.id) {
+        ast_map::node_item(_, pt) => {
+            let mut ebml_w = ebml_w.clone();
+            // See above
+            let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
+            encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
+        }
+        _ => fail!("bad item")
+    }
+}
+
+fn my_visit_foreign_item(ni:@foreign_item, items: ast_map::map, ebml_w:&writer::Encoder,
+                         ecx_ptr:*int, index: @mut ~[entry<i64>]) {
+    match items.get_copy(&ni.id) {
+        ast_map::node_foreign_item(_, abi, _, pt) => {
+            debug!("writing foreign item %s::%s",
+                   ast_map::path_to_str(
+                       *pt,
+                       token::get_ident_interner()),
+                   token::ident_to_str(&ni.ident));
+
+            let mut ebml_w = ebml_w.clone();
+            // See above
+            let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
+            encode_info_for_foreign_item(ecx,
+                                         &mut ebml_w,
+                                         ni,
+                                         index,
+                                         pt,
+                                         abi);
+        }
+        // case for separate item and foreign-item tables
+        _ => fail!("bad foreign item")
+    }
+}
+
+struct EncodeVisitor {
+    ebml_w_for_visit_item: writer::Encoder,
+    ebml_w_for_visit_foreign_item: writer::Encoder,
+    ecx_ptr:*int,
+    items: ast_map::map,
+    index: @mut ~[entry<i64>],
+}
+
+impl visit::Visitor<()> for EncodeVisitor {
+    fn visit_expr(&mut self, ex:@expr, _:()) { my_visit_expr(ex); }
+    fn visit_item(&mut self, i:@item, _:()) {
+        visit::walk_item(self, i, ());
+        my_visit_item(i,
+                      self.items,
+                      &self.ebml_w_for_visit_item,
+                      self.ecx_ptr,
+                      self.index);
+    }
+    fn visit_foreign_item(&mut self, ni:@foreign_item, _:()) {
+        visit::walk_foreign_item(self, ni, ());
+        my_visit_foreign_item(ni,
+                              self.items,
+                              &self.ebml_w_for_visit_foreign_item,
+                              self.ecx_ptr,
+                              self.index);
+    }
+}
+
 fn encode_info_for_items(ecx: &EncodeContext,
                          ebml_w: &mut writer::Encoder,
                          crate: &Crate)
@@ -1201,54 +1270,17 @@ fn encode_info_for_items(ecx: &EncodeContext,
     let items = ecx.tcx.items;
 
     // See comment in `encode_side_tables_for_ii` in astencode
-    let ecx_ptr : *() = unsafe { cast::transmute(ecx) };
-
-    oldvisit::visit_crate(crate, ((), oldvisit::mk_vt(@oldvisit::Visitor {
-        visit_expr: |_e, (_cx, _v)| { },
-        visit_item: {
-            let ebml_w = (*ebml_w).clone();
-            |i, (cx, v)| {
-                oldvisit::visit_item(i, (cx, v));
-                match items.get_copy(&i.id) {
-                    ast_map::node_item(_, pt) => {
-                        let mut ebml_w = ebml_w.clone();
-                        // See above
-                        let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
-                        encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
-                    }
-                    _ => fail!("bad item")
-                }
-            }
-        },
-        visit_foreign_item: {
-            let ebml_w = (*ebml_w).clone();
-            |ni, (cx, v)| {
-                oldvisit::visit_foreign_item(ni, (cx, v));
-                match items.get_copy(&ni.id) {
-                    ast_map::node_foreign_item(_, abi, _, pt) => {
-                        debug!("writing foreign item %s::%s",
-                               ast_map::path_to_str(
-                                *pt,
-                                token::get_ident_interner()),
-                                token::ident_to_str(&ni.ident));
-
-                        let mut ebml_w = ebml_w.clone();
-                        // See above
-                        let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
-                        encode_info_for_foreign_item(ecx,
-                                                     &mut ebml_w,
-                                                     ni,
-                                                     index,
-                                                     pt,
-                                                     abi);
-                    }
-                    // case for separate item and foreign-item tables
-                    _ => fail!("bad foreign item")
-                }
-            }
-        },
-        ..*oldvisit::default_visitor()
-    })));
+    let ecx_ptr : *int = unsafe { cast::transmute(ecx) };
+    let mut visitor = EncodeVisitor {
+        index: index,
+        items: items,
+        ecx_ptr: ecx_ptr,
+        ebml_w_for_visit_item: (*ebml_w).clone(),
+        ebml_w_for_visit_foreign_item: (*ebml_w).clone(),
+    };
+
+    visit::walk_crate(&mut visitor, crate, ());
+
     ebml_w.end_tag();
     return /*bad*/(*index).clone();
 }
index 554cdf4b2b4feb13a9055357ec18cd10316e375f..d0060931a6607eca54c753346ff492fbf8146d20 100644 (file)
@@ -199,7 +199,7 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
 fn get_metadata_section(os: os,
                         filename: &Path) -> Option<@~[u8]> {
     unsafe {
-        let mb = do filename.to_c_str().with_ref |buf| {
+        let mb = do filename.with_c_str |buf| {
             llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
         };
         if mb as int == 0 { return option::None::<@~[u8]>; }
index 6ebc4b49b3779558199d300fe47e302d4534d273..6d2a4fcc9f31a8498afdc4ca9dd59ad1cdf11b87 100644 (file)
@@ -31,7 +31,9 @@
 use syntax::ast_util::id_range;
 use syntax::codemap::span;
 use syntax::print::pprust;
-use syntax::oldvisit;
+use syntax::visit;
+use syntax::visit::Visitor;
+use syntax::ast::{expr, fn_kind, fn_decl, Block, NodeId, stmt, pat, Local};
 
 mod lifetime;
 mod restrictions;
@@ -72,6 +74,30 @@ struct GatherLoanCtxt {
     repeating_ids: ~[ast::NodeId]
 }
 
+struct GatherLoanVisitor;
+
+impl visit::Visitor<@mut GatherLoanCtxt> for GatherLoanVisitor {
+    fn visit_expr(&mut self, ex:@expr, e:@mut GatherLoanCtxt) {
+        gather_loans_in_expr(self, ex, e);
+    }
+    fn visit_block(&mut self, b:&Block, e:@mut GatherLoanCtxt) {
+        gather_loans_in_block(self, b, e);
+    }
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block,
+                s:span, n:NodeId, e:@mut GatherLoanCtxt) {
+        gather_loans_in_fn(self, fk, fd, b, s, n, e);
+    }
+    fn visit_stmt(&mut self, s:@stmt, e:@mut GatherLoanCtxt) {
+        add_stmt_to_map(self, s, e);
+    }
+    fn visit_pat(&mut self, p:@pat, e:@mut GatherLoanCtxt) {
+        add_pat_to_id_range(self, p, e);
+    }
+    fn visit_local(&mut self, l:@Local, e:@mut GatherLoanCtxt) {
+        gather_loans_in_local(self, l, e);
+    }
+}
+
 pub fn gather_loans(bccx: @BorrowckCtxt,
                     decl: &ast::fn_decl,
                     body: &ast::Block)
@@ -85,64 +111,57 @@ pub fn gather_loans(bccx: @BorrowckCtxt,
         move_data: @mut MoveData::new()
     };
     glcx.gather_fn_arg_patterns(decl, body);
-    let v = oldvisit::mk_vt(@oldvisit::Visitor {
-        visit_expr: gather_loans_in_expr,
-        visit_block: gather_loans_in_block,
-        visit_fn: gather_loans_in_fn,
-        visit_stmt: add_stmt_to_map,
-        visit_pat: add_pat_to_id_range,
-        visit_local: gather_loans_in_local,
-        .. *oldvisit::default_visitor()
-    });
-    (v.visit_block)(body, (glcx, v));
+
+    let mut v = GatherLoanVisitor;
+    v.visit_block(body, glcx);
     return (glcx.id_range, glcx.all_loans, glcx.move_data);
 }
 
-fn add_pat_to_id_range(p: @ast::pat,
-                       (this, v): (@mut GatherLoanCtxt,
-                                   oldvisit::vt<@mut GatherLoanCtxt>)) {
+fn add_pat_to_id_range(v: &mut GatherLoanVisitor,
+                       p: @ast::pat,
+                       this: @mut GatherLoanCtxt) {
     // NB: This visitor function just adds the pat ids into the id
     // range. We gather loans that occur in patterns using the
     // `gather_pat()` method below. Eventually these two should be
     // brought together.
     this.id_range.add(p.id);
-    oldvisit::visit_pat(p, (this, v));
+    visit::walk_pat(v, p, this);
 }
 
-fn gather_loans_in_fn(fk: &oldvisit::fn_kind,
+fn gather_loans_in_fn(v: &mut GatherLoanVisitor,
+                      fk: &fn_kind,
                       decl: &ast::fn_decl,
                       body: &ast::Block,
                       sp: span,
                       id: ast::NodeId,
-                      (this, v): (@mut GatherLoanCtxt,
-                                  oldvisit::vt<@mut GatherLoanCtxt>)) {
+                      this: @mut GatherLoanCtxt) {
     match fk {
         // Do not visit items here, the outer loop in borrowck/mod
         // will visit them for us in turn.
-        &oldvisit::fk_item_fn(*) | &oldvisit::fk_method(*) => {
+        &visit::fk_item_fn(*) | &visit::fk_method(*) => {
             return;
         }
 
         // Visit closures as part of the containing item.
-        &oldvisit::fk_anon(*) | &oldvisit::fk_fn_block(*) => {
+        &visit::fk_anon(*) | &visit::fk_fn_block(*) => {
             this.push_repeating_id(body.id);
-            oldvisit::visit_fn(fk, decl, body, sp, id, (this, v));
+            visit::walk_fn(v, fk, decl, body, sp, id, this);
             this.pop_repeating_id(body.id);
             this.gather_fn_arg_patterns(decl, body);
         }
     }
 }
 
-fn gather_loans_in_block(blk: &ast::Block,
-                         (this, vt): (@mut GatherLoanCtxt,
-                                      oldvisit::vt<@mut GatherLoanCtxt>)) {
+fn gather_loans_in_block(v: &mut GatherLoanVisitor,
+                         blk: &ast::Block,
+                         this: @mut GatherLoanCtxt) {
     this.id_range.add(blk.id);
-    oldvisit::visit_block(blk, (this, vt));
+    visit::walk_block(v, blk, this);
 }
 
-fn gather_loans_in_local(local: @ast::Local,
-                         (this, vt): (@mut GatherLoanCtxt,
-                                      oldvisit::vt<@mut GatherLoanCtxt>)) {
+fn gather_loans_in_local(v: &mut GatherLoanVisitor,
+                         local: @ast::Local,
+                         this: @mut GatherLoanCtxt) {
     match local.init {
         None => {
             // Variable declarations without initializers are considered "moves":
@@ -173,12 +192,13 @@ fn gather_loans_in_local(local: @ast::Local,
         }
     }
 
-    oldvisit::visit_local(local, (this, vt));
+    visit::walk_local(v, local, this);
 }
 
-fn gather_loans_in_expr(ex: @ast::expr,
-                        (this, vt): (@mut GatherLoanCtxt,
-                                     oldvisit::vt<@mut GatherLoanCtxt>)) {
+
+fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
+                        ex: @ast::expr,
+                        this: @mut GatherLoanCtxt) {
     let bccx = this.bccx;
     let tcx = bccx.tcx;
 
@@ -218,7 +238,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
         // for the lifetime `scope_r` of the resulting ptr:
         let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex));
         this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
-        oldvisit::visit_expr(ex, (this, vt));
+        visit::walk_expr(v, ex, this);
       }
 
       ast::expr_assign(l, _) | ast::expr_assign_op(_, _, l, _) => {
@@ -235,7 +255,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
                   // with moves etc, just ignore.
               }
           }
-          oldvisit::visit_expr(ex, (this, vt));
+          visit::walk_expr(v, ex, this);
       }
 
       ast::expr_match(ex_v, ref arms) => {
@@ -245,7 +265,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
                 this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id)));
             }
         }
-        oldvisit::visit_expr(ex, (this, vt));
+        visit::walk_expr(v, ex, this);
       }
 
       ast::expr_index(_, _, arg) |
@@ -259,36 +279,36 @@ fn gather_loans_in_expr(ex: @ast::expr,
           let scope_r = ty::re_scope(ex.id);
           let arg_cmt = this.bccx.cat_expr(arg);
           this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
-          oldvisit::visit_expr(ex, (this, vt));
+          visit::walk_expr(v, ex, this);
       }
 
       // see explanation attached to the `root_ub` field:
       ast::expr_while(cond, ref body) => {
           // during the condition, can only root for the condition
           this.push_repeating_id(cond.id);
-          (vt.visit_expr)(cond, (this, vt));
+          v.visit_expr(cond, this);
           this.pop_repeating_id(cond.id);
 
           // during body, can only root for the body
           this.push_repeating_id(body.id);
-          (vt.visit_block)(body, (this, vt));
+          v.visit_block(body, this);
           this.pop_repeating_id(body.id);
       }
 
       // see explanation attached to the `root_ub` field:
       ast::expr_loop(ref body, _) => {
           this.push_repeating_id(body.id);
-          oldvisit::visit_expr(ex, (this, vt));
+          visit::walk_expr(v, ex, this);
           this.pop_repeating_id(body.id);
       }
 
       ast::expr_fn_block(*) => {
           gather_moves::gather_captures(this.bccx, this.move_data, ex);
-          oldvisit::visit_expr(ex, (this, vt));
+          visit::walk_expr(v, ex, this);
       }
 
       _ => {
-        oldvisit::visit_expr(ex, (this, vt));
+          visit::walk_expr(v, ex, this);
       }
     }
 }
@@ -770,14 +790,14 @@ pub fn pat_is_binding(&self, pat: @ast::pat) -> bool {
 
 // Setting up info that preserve needs.
 // This is just the most convenient place to do it.
-fn add_stmt_to_map(stmt: @ast::stmt,
-                   (this, vt): (@mut GatherLoanCtxt,
-                                oldvisit::vt<@mut GatherLoanCtxt>)) {
+fn add_stmt_to_map(v: &mut GatherLoanVisitor,
+                   stmt: @ast::stmt,
+                   this: @mut GatherLoanCtxt) {
     match stmt.node {
         ast::stmt_expr(_, id) | ast::stmt_semi(_, id) => {
             this.bccx.stmt_map.insert(id);
         }
         _ => ()
     }
-    oldvisit::visit_stmt(stmt, (this, vt));
+    visit::walk_stmt(v, stmt, this);
 }
index d410021063c238496b76f4ce94ce296d7468a7b6..95eae32922b7f7afe7a35969aab1a83796aa5004 100644 (file)
 use std::result::{Result};
 use syntax::ast;
 use syntax::ast_map;
-use syntax::oldvisit;
 use syntax::codemap::span;
 use syntax::parse::token;
+use syntax::visit;
+use syntax::visit::{Visitor,fn_kind};
+use syntax::ast::{fn_decl,Block,NodeId};
 
 macro_rules! if_ok(
     ($inp: expr) => (
@@ -59,6 +61,15 @@ fn clone(&self) -> LoanDataFlowOperator {
 
 pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
 
+struct BorrowckVisitor;
+
+impl Visitor<@BorrowckCtxt> for BorrowckVisitor {
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl,
+                b:&Block, s:span, n:NodeId, e:@BorrowckCtxt) {
+        borrowck_fn(self, fk, fd, b, s, n, e);
+    }
+}
+
 pub fn check_crate(
     tcx: ty::ctxt,
     method_map: typeck::method_map,
@@ -86,9 +97,8 @@ pub fn check_crate(
         }
     };
 
-    let v = oldvisit::mk_vt(@oldvisit::Visitor {visit_fn: borrowck_fn,
-                                          ..*oldvisit::default_visitor()});
-    oldvisit::visit_crate(crate, (bccx, v));
+    let mut v = BorrowckVisitor;
+    visit::walk_crate(&mut v, crate, bccx);
 
     if tcx.sess.borrowck_stats() {
         io::println("--- borrowck stats ---");
@@ -113,21 +123,21 @@ fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> ~str {
     }
 }
 
-fn borrowck_fn(fk: &oldvisit::fn_kind,
+fn borrowck_fn(v: &mut BorrowckVisitor,
+               fk: &visit::fn_kind,
                decl: &ast::fn_decl,
                body: &ast::Block,
                sp: span,
                id: ast::NodeId,
-               (this, v): (@BorrowckCtxt,
-                           oldvisit::vt<@BorrowckCtxt>)) {
+               this: @BorrowckCtxt) {
     match fk {
-        &oldvisit::fk_anon(*) |
-        &oldvisit::fk_fn_block(*) => {
+        &visit::fk_anon(*) |
+        &visit::fk_fn_block(*) => {
             // Closures are checked as part of their containing fn item.
         }
 
-        &oldvisit::fk_item_fn(*) |
-        &oldvisit::fk_method(*) => {
+        &visit::fk_item_fn(*) |
+        &visit::fk_method(*) => {
             debug!("borrowck_fn(id=%?)", id);
 
             // Check the body of fn items.
@@ -156,7 +166,7 @@ fn borrowck_fn(fk: &oldvisit::fn_kind,
         }
     }
 
-    oldvisit::visit_fn(fk, decl, body, sp, id, (this, v));
+    visit::walk_fn(v, fk, decl, body, sp, id, this);
 }
 
 // ----------------------------------------------------------------------
index f9ef6dabcd64cfc32eb97d514879a14b6e6342f0..160cc23bd19ff812e046a44e44c4608888652d53 100644 (file)
@@ -160,6 +160,7 @@ pub fn check_expr(sess: Session,
           expr_field(*) |
           expr_index(*) |
           expr_tup(*) |
+          expr_repeat(*) |
           expr_struct(*) => { }
           expr_addr_of(*) => {
                 sess.span_err(
index 37f45142a1107f189c9eb5f897018ab255164ac0..9719460bbd33e14a39c027a032e4817999e0effa 100644 (file)
@@ -879,7 +879,9 @@ pub fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
 
     let check_move: &fn(@pat, Option<@pat>) = |p, sub| {
         // check legality of moving out of the enum
-        if sub.is_some() {
+
+        // x @ Foo(*) is legal, but x @ Foo(y) isn't.
+        if sub.map_move_default(false, |p| pat_contains_bindings(def_map, p)) {
             tcx.sess.span_err(
                 p.span,
                 "cannot bind by-move with sub-bindings");
index 2de94cdbf4ccd03d2c249c1d6cd9f4f8b968b37b..68e3dfd63be9ff392e57c46f6ae07b74f3f2575c 100644 (file)
@@ -153,6 +153,8 @@ pub fn classify(e: &expr,
                 lookup_constness(tcx, e)
               }
 
+              ast::expr_repeat(*) => general_const,
+
               _ => non_const
             };
         tcx.ccache.insert(did, cn);
index 76532b5cd22d6c6c835c71464b8cfff089ee2e1d..55425b647953098d70b2492bd60d3bc90dde8ba1 100644 (file)
@@ -480,6 +480,7 @@ fn process(@mut self, n: AttributedNode) {
                             (orig.visit_item)(it, (self, stopping));
                         }
                         NewVisitor(new_visitor) => {
+                            let mut new_visitor = new_visitor;
                             new_visitor.visit_item(it, ());
                         }
                     }
@@ -492,7 +493,8 @@ fn process(@mut self, n: AttributedNode) {
                             oldvisit::visit_crate(c, (self, stopping))
                         }
                         NewVisitor(new_visitor) => {
-                            visit::visit_crate(new_visitor, c, ())
+                            let mut new_visitor = new_visitor;
+                            visit::walk_crate(&mut new_visitor, c, ())
                         }
                     }
                 }
@@ -518,6 +520,7 @@ fn process(@mut self, n: AttributedNode) {
                             let fk = visit::fk_method(m.ident,
                                                       &m.generics,
                                                       m);
+                            let mut new_visitor = new_visitor;
                             new_visitor.visit_fn(&fk,
                                                  &m.decl,
                                                  &m.body,
index 9bf14697d9ad764b9b9c1d245ed3b98114652eda..a67a488ef30fce2147a9593ba3bda8bd1ffe875c 100644 (file)
@@ -88,3 +88,18 @@ pub fn pat_binding_ids(dm: resolve::DefMap, pat: @pat) -> ~[NodeId] {
     pat_bindings(dm, pat, |_bm, b_id, _sp, _pt| found.push(b_id) );
     return found;
 }
+
+/// Checks if the pattern contains any patterns that bind something to
+/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(*)`.
+pub fn pat_contains_bindings(dm: resolve::DefMap, pat: @pat) -> bool {
+    let mut contains_bindings = false;
+    do walk_pat(pat) |p| {
+        if pat_is_binding(dm, p) {
+            contains_bindings = true;
+            false // there's at least one binding, can short circuit now.
+        } else {
+            true
+        }
+    };
+    contains_bindings
+}
index c98d859337c3e4a2bf116a3c951b137030595cda..bb1e3fa1718dc3d83854420507bb31eab6c414e9 100644 (file)
 use middle::trans::glue;
 use middle::trans::tvec;
 use middle::trans::type_of;
+use middle::trans::debuginfo;
 use middle::ty;
 use util::common::indenter;
 use util::ppaux::{Repr, vec_map_to_str};
@@ -385,6 +386,7 @@ struct BindingInfo {
     llmatch: ValueRef,
     trmode: TransBindingMode,
     id: ast::NodeId,
+    span: span,
     ty: ty::t,
 }
 
@@ -1305,7 +1307,7 @@ fn insert_lllocals(bcx: @mut Block,
         BindArgument => bcx.fcx.llargs
     };
 
-    for (_, &binding_info) in bindings_map.iter() {
+    for (&ident, &binding_info) in bindings_map.iter() {
         let llval = match binding_info.trmode {
             // By value bindings: use the stack slot that we
             // copied/moved the value into
@@ -1325,6 +1327,14 @@ fn insert_lllocals(bcx: @mut Block,
 
         debug!("binding %? to %s", binding_info.id, bcx.val_to_str(llval));
         llmap.insert(binding_info.id, llval);
+
+        if bcx.sess().opts.extra_debuginfo {
+            debuginfo::create_match_binding_metadata(bcx,
+                                                     ident,
+                                                     binding_info.id,
+                                                     binding_info.ty,
+                                                     binding_info.span);
+        }
     }
     return bcx;
 }
@@ -1771,7 +1781,7 @@ fn create_bindings_map(bcx: @mut Block, pat: @ast::pat) -> BindingsMap {
     let ccx = bcx.ccx();
     let tcx = bcx.tcx();
     let mut bindings_map = HashMap::new();
-    do pat_bindings(tcx.def_map, pat) |bm, p_id, _s, path| {
+    do pat_bindings(tcx.def_map, pat) |bm, p_id, span, path| {
         let ident = path_to_ident(path);
         let variable_ty = node_id_type(bcx, p_id);
         let llvariable_ty = type_of::type_of(ccx, variable_ty);
@@ -1793,8 +1803,11 @@ fn create_bindings_map(bcx: @mut Block, pat: @ast::pat) -> BindingsMap {
             }
         };
         bindings_map.insert(ident, BindingInfo {
-            llmatch: llmatch, trmode: trmode,
-            id: p_id, ty: variable_ty
+            llmatch: llmatch,
+            trmode: trmode,
+            id: p_id,
+            span: span,
+            ty: variable_ty
         });
     }
     return bindings_map;
index b6057199a280fbccddba02aefe60d7b20f42c5f7..3400da75b9e5e880d237ea3192ce50b7b6659e8c 100644 (file)
@@ -120,8 +120,8 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
         ast::asm_intel => lib::llvm::AD_Intel
     };
 
-    let r = do ia.asm.to_c_str().with_ref |a| {
-        do constraints.to_c_str().with_ref |c| {
+    let r = do ia.asm.with_c_str |a| {
+        do constraints.with_c_str |c| {
             InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect)
         }
     };
index 7331b50dd107c95a5743829aa46fce6167cfdf7d..84b3ab2040722d15f59f1a65754ca8282c7fdd63 100644 (file)
@@ -181,7 +181,7 @@ fn drop(&self) {
 }
 
 pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
-    let llfn: ValueRef = do name.to_c_str().with_ref |buf| {
+    let llfn: ValueRef = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
         }
@@ -221,7 +221,7 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
         None => ()
     }
     unsafe {
-        let c = do name.to_c_str().with_ref |buf| {
+        let c = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
         };
         externs.insert(name, c);
@@ -523,7 +523,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
 // Structural comparison: a rather involved form of glue.
 pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
     if cx.sess.opts.save_temps {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             unsafe {
                 llvm::LLVMSetValueName(v, buf)
             }
@@ -1103,7 +1103,6 @@ pub fn trans_stmt(cx: @mut Block, s: &ast::stmt) -> @mut Block {
     }
 
     let mut bcx = cx;
-    debuginfo::update_source_pos(cx, s.span);
 
     match s.node {
         ast::stmt_expr(e, _) | ast::stmt_semi(e, _) => {
@@ -1137,7 +1136,7 @@ pub fn new_block(cx: @mut FunctionContext,
                  opt_node_info: Option<NodeInfo>)
               -> @mut Block {
     unsafe {
-        let llbb = do name.to_c_str().with_ref |buf| {
+        let llbb = do name.with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
         };
         let bcx = @mut Block::new(llbb,
@@ -1554,7 +1553,7 @@ pub struct BasicBlocks {
 pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "static_allocas".to_c_str().with_ref | buf| {
+        do "static_allocas".with_c_str | buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1563,7 +1562,7 @@ pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
 pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "return".to_c_str().with_ref |buf| {
+        do "return".with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1625,7 +1624,6 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
           llreturn: None,
           llself: None,
           personality: None,
-          loop_ret: None,
           has_immediate_return_value: is_immediate,
           llargs: @mut HashMap::new(),
           lllocals: @mut HashMap::new(),
@@ -1634,7 +1632,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
           param_substs: param_substs,
           span: sp,
           path: path,
-          ccx: ccx
+          ccx: ccx,
+          debug_context: None,
     };
     fcx.llenv = unsafe {
           llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
@@ -1834,8 +1833,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
                      id: ast::NodeId,
                      attributes: &[ast::Attribute],
                      output_type: ty::t,
-                     maybe_load_env: &fn(@mut FunctionContext),
-                     finish: &fn(@mut Block)) {
+                     maybe_load_env: &fn(@mut FunctionContext)) {
     ccx.stats.n_closures += 1;
     let _icx = push_ctxt("trans_closure");
     set_uwtable(llfndecl);
@@ -1885,7 +1883,6 @@ pub fn trans_closure(ccx: @mut CrateContext,
         bcx = controlflow::trans_block(bcx, body, dest);
     }
 
-    finish(bcx);
     match fcx.llreturn {
         Some(llreturn) => cleanup_and_Br(bcx, bcx_top, llreturn),
         None => bcx = cleanup_block(bcx, Some(bcx_top.llbb))
@@ -1933,12 +1930,11 @@ pub fn trans_fn(ccx: @mut CrateContext,
                   attrs,
                   output_type,
                   |fcx| {
-                      if ccx.sess.opts.extra_debuginfo
+                      if ccx.sess.opts.debuginfo
                           && fcx_has_nonzero_span(fcx) {
                           debuginfo::create_function_metadata(fcx);
                       }
-                  },
-                  |_bcx| { });
+                  });
 }
 
 fn insert_synthetic_type_entries(bcx: @mut Block,
@@ -2332,7 +2328,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
         };
-        let llbb = do "top".to_c_str().with_ref |buf| {
+        let llbb = do "top".with_c_str |buf| {
             unsafe {
                 llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
             }
@@ -2342,7 +2338,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
             let crate_map = ccx.crate_map;
-            let opaque_crate_map = do "crate_map".to_c_str().with_ref |buf| {
+            let opaque_crate_map = do "crate_map".with_c_str |buf| {
                 llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
             };
 
@@ -2360,7 +2356,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                 };
 
                 let args = {
-                    let opaque_rust_main = do "rust_main".to_c_str().with_ref |buf| {
+                    let opaque_rust_main = do "rust_main".with_c_str |buf| {
                         llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf)
                     };
 
@@ -2442,7 +2438,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                             unsafe {
                                 let llty = llvm::LLVMTypeOf(v);
-                                let g = do sym.to_c_str().with_ref |buf| {
+                                let g = do sym.with_c_str |buf| {
                                     llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
                                 };
 
@@ -2475,7 +2471,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                     match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
                         Some(sect) => unsafe {
-                            do sect.to_c_str().with_ref |buf| {
+                            do sect.with_c_str |buf| {
                                 llvm::LLVMSetSection(v, buf);
                             }
                         },
@@ -2516,7 +2512,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                         }
                         ast::foreign_item_static(*) => {
                             let ident = token::ident_to_str(&ni.ident);
-                            let g = do ident.to_c_str().with_ref |buf| {
+                            let g = do ident.with_c_str |buf| {
                                 unsafe {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
@@ -2623,7 +2619,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
             let s = mangle_exported_name(ccx, p, ty::mk_int()).to_managed();
             let disr_val = vi[i].disr_val;
             note_unique_llvm_symbol(ccx, s);
-            let discrim_gvar = do s.to_c_str().with_ref |buf| {
+            let discrim_gvar = do s.with_c_str |buf| {
                 unsafe {
                     llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
                 }
@@ -2818,7 +2814,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
     }
 
     let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
-    let gc_metadata = do gc_metadata_name.to_c_str().with_ref |buf| {
+    let gc_metadata = do gc_metadata_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
         }
@@ -2833,7 +2829,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
 pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
     let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
     let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
-    let map = do "_rust_mod_map".to_c_str().with_ref |buf| {
+    let map = do "_rust_mod_map".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
         }
@@ -2881,7 +2877,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     let sym_name = ~"_rust_crate_map_" + mapname;
     let arrtype = Type::array(&int_type, n_subcrates as u64);
     let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false);
-    let map = do sym_name.to_c_str().with_ref |buf| {
+    let map = do sym_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
@@ -2900,7 +2896,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
                       cdata.name,
                       cstore::get_crate_vers(cstore, i),
                       cstore::get_crate_hash(cstore, i));
-        let cr = do nm.to_c_str().with_ref |buf| {
+        let cr = do nm.with_c_str |buf| {
             unsafe {
                 llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
             }
@@ -2963,21 +2959,21 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::Crate) {
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
     let llconst = C_struct([llmeta]);
-    let mut llglobal = do "rust_metadata".to_c_str().with_ref |buf| {
+    let mut llglobal = do "rust_metadata".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
         }
     };
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
-        do cx.sess.targ_cfg.target_strs.meta_sect_name.to_c_str().with_ref |buf| {
+        do cx.sess.targ_cfg.target_strs.meta_sect_name.with_c_str |buf| {
             llvm::LLVMSetSection(llglobal, buf)
         };
         lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
 
         let t_ptr_i8 = Type::i8p();
         llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref());
-        let llvm_used = do "llvm.used".to_c_str().with_ref |buf| {
+        let llvm_used = do "llvm.used".with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
         };
         lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
@@ -2991,7 +2987,7 @@ fn mk_global(ccx: &CrateContext,
              internal: bool)
           -> ValueRef {
     unsafe {
-        let llglobal = do name.to_c_str().with_ref |buf| {
+        let llglobal = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(llglobal, llval);
index 5c216b2e14346684620185f0213be2666003b9b0..cba7a2253952ff55989de9d882914dbfbd7d4510 100644 (file)
@@ -423,7 +423,7 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                do name.to_c_str().with_ref |c| {
+                do name.with_c_str |c| {
                     llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c)
                 }
             }
@@ -739,7 +739,7 @@ pub fn add_comment(&self, text: &str) {
             let sanitized = text.replace("$", "");
             let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let asm = do comment_text.to_c_str().with_ref |c| {
+            let asm = do comment_text.with_c_str |c| {
                 unsafe {
                     llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
                                              c, noname(), False, False)
@@ -895,7 +895,7 @@ pub fn trap(&self) {
             let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
             let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
             let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
-            let T: ValueRef = do "llvm.trap".to_c_str().with_ref |buf| {
+            let T: ValueRef = do "llvm.trap".with_c_str |buf| {
                 llvm::LLVMGetNamedFunction(M, buf)
             };
             assert!((T as int != 0));
index 602d33a197e29bfc536639d370372d07185a52a1..422394716b479f2727835a4e603a150b553e7a68 100644 (file)
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
-use middle::trans::datum::{Datum, INIT, ByRef, ZeroMem};
+use middle::trans::datum::{Datum, INIT};
 use middle::trans::expr;
 use middle::trans::glue;
 use middle::trans::type_of::*;
 use middle::ty;
 use util::ppaux::ty_to_str;
 
-use middle::trans::type_::Type;
-
 use std::vec;
 use syntax::ast;
 use syntax::ast_map::path_name;
@@ -259,8 +257,7 @@ pub fn store_environment(bcx: @mut Block,
 // collects the upvars and packages them up for store_environment.
 pub fn build_closure(bcx0: @mut Block,
                      cap_vars: &[moves::CaptureVar],
-                     sigil: ast::Sigil,
-                     include_ret_handle: Option<ValueRef>) -> ClosureResult {
+                     sigil: ast::Sigil) -> ClosureResult {
     let _icx = push_ctxt("closure::build_closure");
 
     // If we need to, package up the iterator body to call
@@ -288,30 +285,6 @@ pub fn build_closure(bcx0: @mut Block,
         }
     }
 
-    // If this is a `for` loop body, add two special environment
-    // variables:
-    for flagptr in include_ret_handle.iter() {
-        // Flag indicating we have returned (a by-ref bool):
-        let flag_datum = Datum {val: *flagptr, ty: ty::mk_bool(),
-                                mode: ByRef(ZeroMem)};
-        env_vals.push(EnvValue {action: EnvRef,
-                                datum: flag_datum});
-
-        // Return value (we just pass a by-ref () and cast it later to
-        // the right thing):
-        let ret_true = match bcx.fcx.loop_ret {
-            Some((_, retptr)) => retptr,
-            None => match bcx.fcx.llretptr {
-                None => C_null(Type::nil().ptr_to()),
-                Some(retptr) => PointerCast(bcx, retptr, Type::nil().ptr_to()),
-            }
-        };
-        let ret_datum = Datum {val: ret_true, ty: ty::mk_nil(),
-                               mode: ByRef(ZeroMem)};
-        env_vals.push(EnvValue {action: EnvRef,
-                                datum: ret_datum});
-    }
-
     return store_environment(bcx, env_vals, sigil);
 }
 
@@ -321,12 +294,11 @@ pub fn build_closure(bcx0: @mut Block,
 pub fn load_environment(fcx: @mut FunctionContext,
                         cdata_ty: ty::t,
                         cap_vars: &[moves::CaptureVar],
-                        load_ret_handle: bool,
                         sigil: ast::Sigil) {
     let _icx = push_ctxt("closure::load_environment");
 
     // Don't bother to create the block if there's nothing to load
-    if cap_vars.len() == 0 && !load_ret_handle {
+    if cap_vars.len() == 0 {
         return;
     }
 
@@ -347,12 +319,6 @@ pub fn load_environment(fcx: @mut FunctionContext,
         fcx.llupvars.insert(def_id.node, upvarptr);
         i += 1u;
     }
-    if load_ret_handle {
-        let flagptr = Load(bcx, GEPi(bcx, llcdata, [0u, i]));
-        let retptr = Load(bcx,
-                          GEPi(bcx, llcdata, [0u, i+1u]));
-        fcx.loop_ret = Some((flagptr, retptr));
-    }
 }
 
 pub fn trans_expr_fn(bcx: @mut Block,
@@ -361,7 +327,6 @@ pub fn trans_expr_fn(bcx: @mut Block,
                      body: &ast::Block,
                      outer_id: ast::NodeId,
                      user_id: ast::NodeId,
-                     is_loop_body: Option<Option<ValueRef>>,
                      dest: expr::Dest) -> @mut Block {
     /*!
      *
@@ -378,7 +343,6 @@ pub fn trans_expr_fn(bcx: @mut Block,
      * - `user_id`: The id of the closure as the user expressed it.
          Generally the same as `outer_id`
      * - `cap_clause`: information about captured variables, if any.
-     * - `is_loop_body`: `Some()` if this is part of a `for` loop.
      * - `dest`: where to write the closure value, which must be a
          (fn ptr, env) pair
      */
@@ -405,28 +369,14 @@ pub fn trans_expr_fn(bcx: @mut Block,
                                                  "expr_fn");
     let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
 
-    // Always mark inline if this is a loop body. This is important for
-    // performance on many programs with tight loops.
-    if is_loop_body.is_some() {
-        set_always_inline(llfn);
-    } else {
-        // Can't hurt.
-        set_inline_hint(llfn);
-    }
-
-    let real_return_type = if is_loop_body.is_some() {
-        ty::mk_bool()
-    } else {
-        ty::ty_fn_ret(fty)
-    };
+    // set an inline hint for all closures
+    set_inline_hint(llfn);
 
     let Result {bcx: bcx, val: closure} = match sigil {
         ast::BorrowedSigil | ast::ManagedSigil | ast::OwnedSigil => {
             let cap_vars = ccx.maps.capture_map.get_copy(&user_id);
-            let ret_handle = match is_loop_body {Some(x) => x,
-                                                 None => None};
             let ClosureResult {llbox, cdata_ty, bcx}
-                = build_closure(bcx, cap_vars, sigil, ret_handle);
+                = build_closure(bcx, cap_vars, sigil);
             trans_closure(ccx,
                           sub_path,
                           decl,
@@ -436,16 +386,8 @@ pub fn trans_expr_fn(bcx: @mut Block,
                           bcx.fcx.param_substs,
                           user_id,
                           [],
-                          real_return_type,
-                          |fcx| load_environment(fcx, cdata_ty, cap_vars,
-                                                 ret_handle.is_some(), sigil),
-                          |bcx| {
-                              if is_loop_body.is_some() {
-                                  Store(bcx,
-                                        C_bool(true),
-                                        bcx.fcx.llretptr.unwrap());
-                              }
-                          });
+                          ty::ty_fn_ret(fty),
+                          |fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
             rslt(bcx, llbox)
         }
     };
index 3253e24ae8898a6045131d8c7e98727c960da635..4ca4a9a12fc4c96ba7355e2e90cb647139169c65 100644 (file)
@@ -23,6 +23,7 @@
 use middle::trans::datum;
 use middle::trans::glue;
 use middle::trans::write_guard;
+use middle::trans::debuginfo;
 use middle::ty::substs;
 use middle::ty;
 use middle::typeck;
@@ -35,7 +36,7 @@
 use std::cast::transmute;
 use std::cast;
 use std::hashmap::{HashMap};
-use std::libc::{c_uint, c_longlong, c_ulonglong};
+use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
 use std::vec;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt};
@@ -195,9 +196,6 @@ pub struct FunctionContext {
     // The a value alloca'd for calls to upcalls.rust_personality. Used when
     // outputting the resume instruction.
     personality: Option<ValueRef>,
-    // If this is a for-loop body that returns, this holds the pointers needed
-    // for that (flagptr, retptr)
-    loop_ret: Option<(ValueRef, ValueRef)>,
 
     // True if this function has an immediate return value, false otherwise.
     // If this is false, the llretptr will alias the first argument of the
@@ -226,7 +224,10 @@ pub struct FunctionContext {
     path: path,
 
     // This function's enclosing crate context.
-    ccx: @mut CrateContext
+    ccx: @mut CrateContext,
+
+    // Used and maintained by the debuginfo module.
+    debug_context: Option<~debuginfo::FunctionDebugContext>
 }
 
 impl FunctionContext {
@@ -708,7 +709,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             llvm::LLVMConstRealOfString(t.to_ref(), buf)
         }
     }
@@ -756,12 +757,12 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
             None => ()
         }
 
-        let sc = do s.to_c_str().with_ref |buf| {
-            llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False)
+        let sc = do s.as_imm_buf |buf, buflen| {
+            llvm::LLVMConstStringInContext(cx.llcx, buf as *c_char, buflen as c_uint, False)
         };
 
         let gsym = token::gensym("str");
-        let g = do fmt!("str%u", gsym).to_c_str().with_ref |buf| {
+        let g = do fmt!("str%u", gsym).with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(g, sc);
index 1992d71427f2053baacc7413c310324c9602202e..87d26fa5ba07c6f7b4be346e0a25166583f08159 100644 (file)
@@ -32,6 +32,7 @@
 
 use std::c_str::ToCStr;
 use std::libc::c_uint;
+use std::vec;
 use syntax::{ast, ast_util, ast_map};
 
 pub fn const_lit(cx: &mut CrateContext, e: &ast::expr, lit: ast::lit)
@@ -102,7 +103,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr])
 
 fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
     unsafe {
-        let gv = do "const".to_c_str().with_ref |name| {
+        let gv = do "const".with_c_str |name| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
         };
         llvm::LLVMSetInitializer(gv, cv);
@@ -528,7 +529,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               ast::expr_vec(ref es, ast::m_imm) => {
                 let (cv, sz, llunitty) = const_vec(cx, e, *es);
                 let llty = val_ty(cv);
-                let gv = do "const".to_c_str().with_ref |name| {
+                let gv = do "const".with_c_str |name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
                 };
                 llvm::LLVMSetInitializer(gv, cv);
@@ -540,6 +541,23 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               _ => cx.sess.span_bug(e.span, "bad const-slice expr")
             }
           }
+          ast::expr_repeat(elem, count, _) => {
+            let vec_ty = ty::expr_ty(cx.tcx, e);
+            let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
+            let llunitty = type_of::type_of(cx, unit_ty);
+            let n = match const_eval::eval_const_expr(cx.tcx, count) {
+                const_eval::const_int(i)  => i as uint,
+                const_eval::const_uint(i) => i as uint,
+                _ => cx.sess.span_bug(count.span, "count must be integral const expression.")
+            };
+            let vs = vec::from_elem(n, const_expr(cx, elem));
+            let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
+                C_struct(vs)
+            } else {
+                C_array(llunitty, vs)
+            };
+            v
+          }
           ast::expr_path(ref pth) => {
             assert_eq!(pth.types.len(), 0);
             let tcx = cx.tcx;
index 187c121bbd33799b642c70304244213272a7f5f0..5d0849ef12c9ab2ba2bcca0e845b013959ed84fc 100644 (file)
@@ -13,7 +13,7 @@
 use driver::session;
 use lib::llvm::{ContextRef, ModuleRef, ValueRef};
 use lib::llvm::{llvm, TargetData, TypeNames};
-use lib::llvm::{mk_target_data, False};
+use lib::llvm::mk_target_data;
 use metadata::common::LinkMeta;
 use middle::astencode;
 use middle::resolve;
@@ -128,15 +128,15 @@ pub fn new(sess: session::Session,
         unsafe {
             let llcx = llvm::LLVMContextCreate();
             set_task_llcx(llcx);
-            let llmod = do name.to_c_str().with_ref |buf| {
+            let llmod = do name.with_c_str |buf| {
                 llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
             };
             let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
             let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
-            do data_layout.to_c_str().with_ref |buf| {
+            do data_layout.with_c_str |buf| {
                 llvm::LLVMSetDataLayout(llmod, buf)
             };
-            do targ_triple.to_c_str().with_ref |buf| {
+            do targ_triple.with_c_str |buf| {
                 llvm::LLVMSetTarget(llmod, buf)
             };
             let targ_cfg = sess.targ_cfg;
index 46eb3928d595eb956d7998ebb09f762b5e2abe34..04d401f82970ceb567c12dd1f24f4554b26374e4 100644 (file)
@@ -19,9 +19,7 @@
 use middle::trans::build::*;
 use middle::trans::callee;
 use middle::trans::common::*;
-use middle::trans::debuginfo;
 use middle::trans::expr;
-use middle::trans::type_of::*;
 use middle::ty;
 use util::common::indenter;
 use util::ppaux;
@@ -38,12 +36,10 @@ pub fn trans_block(bcx: @mut Block, b: &ast::Block, dest: expr::Dest) -> @mut Bl
     let _icx = push_ctxt("trans_block");
     let mut bcx = bcx;
     for s in b.stmts.iter() {
-        debuginfo::update_source_pos(bcx, b.span);
         bcx = trans_stmt(bcx, *s);
     }
     match b.expr {
         Some(e) => {
-            debuginfo::update_source_pos(bcx, e.span);
             bcx = expr::trans_into(bcx, e, dest);
         }
         None => {
@@ -241,7 +237,7 @@ pub fn trans_log(log_ex: &ast::expr,
             ccx, modpath, "loglevel");
         let global;
         unsafe {
-            global = do s.to_c_str().with_ref |buf| {
+            global = do s.with_c_str |buf| {
                 llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
             };
             llvm::LLVMSetGlobalConstant(global, False);
@@ -341,29 +337,15 @@ pub fn trans_cont(bcx: @mut Block, label_opt: Option<ident>) -> @mut Block {
 pub fn trans_ret(bcx: @mut Block, e: Option<@ast::expr>) -> @mut Block {
     let _icx = push_ctxt("trans_ret");
     let mut bcx = bcx;
-    let dest = match bcx.fcx.loop_ret {
-      Some((flagptr, retptr)) => {
-        // This is a loop body return. Must set continue flag (our retptr)
-        // to false, return flag to true, and then store the value in the
-        // parent's retptr.
-        Store(bcx, C_bool(true), flagptr);
-        Store(bcx, C_bool(false), bcx.fcx.llretptr.unwrap());
-        expr::SaveIn(match e {
-          Some(x) => PointerCast(bcx, retptr,
-                                 type_of(bcx.ccx(), expr_ty(bcx, x)).ptr_to()),
-          None => retptr
-        })
-      }
-      None => match bcx.fcx.llretptr {
+    let dest = match bcx.fcx.llretptr {
         None => expr::Ignore,
         Some(retptr) => expr::SaveIn(retptr),
-      }
     };
     match e {
-      Some(x) => {
-        bcx = expr::trans_into(bcx, x, dest);
-      }
-      _ => ()
+        Some(x) => {
+            bcx = expr::trans_into(bcx, x, dest);
+        }
+        _ => ()
     }
     cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
     Unreachable(bcx);
index 1fb64d9c67130066722789673447d9139fd1b3ca..d23c009ac1599c87bc2ea57057f0a864510c2adb 100644 (file)
@@ -99,9 +99,7 @@ pub struct DebugContext {
     priv created_files: HashMap<~str, DIFile>,
     priv created_functions: HashMap<ast::NodeId, DISubprogram>,
     priv created_blocks: HashMap<ast::NodeId, DILexicalBlock>,
-    priv created_types: HashMap<uint, DIType>,
-    priv last_function_context_id: ast::NodeId,
-    priv argument_counter: uint,
+    priv created_types: HashMap<uint, DIType>
 }
 
 impl DebugContext {
@@ -118,8 +116,21 @@ pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext {
             created_files: HashMap::new(),
             created_functions: HashMap::new(),
             created_blocks: HashMap::new(),
-            created_types: HashMap::new(),
-            last_function_context_id: -1, // magic value :(
+            created_types: HashMap::new()
+        };
+    }
+}
+
+
+pub struct FunctionDebugContext {
+    priv scope_map: HashMap<ast::NodeId, DIScope>,
+    priv argument_counter: uint,
+}
+
+impl FunctionDebugContext {
+    fn new() -> FunctionDebugContext {
+        return FunctionDebugContext {
+            scope_map: HashMap::new(),
             argument_counter: 1,
         };
     }
@@ -141,61 +152,24 @@ pub fn finalize(cx: @mut CrateContext) {
 pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
     let cx = bcx.ccx();
     let def_map = cx.tcx.def_map;
-    let pattern = local.pat;
-
-    let scope = match bcx.parent {
-        None => create_function_metadata(bcx.fcx),
-        Some(_) => lexical_block_metadata(bcx)
-    };
-
-    let filename = span_start(cx, local.span).file.name;
-    let file_metadata = file_metadata(cx, filename);
-
-    do pat_util::pat_bindings(def_map, pattern) |_, node_id, span, path_ref| {
-
-        let ident = ast_util::path_to_ident(path_ref);
-        let name: &str = cx.sess.str_of(ident);
-        debug!("create_local_var_metadata: %s", name);
-        let loc = span_start(cx, span);
-        let ty = node_id_type(bcx, node_id);
-        let type_metadata = type_metadata(cx, ty, span);
-
-        let var_metadata = do name.to_c_str().with_ref |name| {
-            unsafe {
-                llvm::LLVMDIBuilderCreateLocalVariable(
-                    DIB(cx),
-                    DW_TAG_auto_variable,
-                    scope,
-                    name,
-                    file_metadata,
-                    loc.line as c_uint,
-                    type_metadata,
-                    false,
-                    0,
-                    0)
-            }
-        };
 
-        let llptr = match bcx.fcx.lllocals.find_copy(&node_id) {
-            Some(v) => v,
-            None => {
-                bcx.tcx().sess.span_bug(span, fmt!("No entry in lllocals table for %?", node_id));
-            }
-        };
+    do pat_util::pat_bindings(def_map, local.pat) |_, node_id, span, path_ref| {
 
-        set_debug_location(cx, lexical_block_metadata(bcx), loc.line, loc.col.to_uint());
-        unsafe {
-            let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
-                DIB(cx),
-                llptr,
-                var_metadata,
-                bcx.llbb);
+        let var_ident = ast_util::path_to_ident(path_ref);
+        let var_type = node_id_type(bcx, node_id);
 
-            llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
-        }
+        declare_local(bcx, var_ident, node_id, var_type, span);
     }
 }
 
+pub fn create_match_binding_metadata(bcx: @mut Block,
+                                     variable_ident: ast::ident,
+                                     node_id: ast::NodeId,
+                                     variable_type: ty::t,
+                                     span: span) {
+    declare_local(bcx, variable_ident, node_id, variable_type, span);
+}
+
 /// Creates debug information for the given function argument.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
@@ -213,20 +187,6 @@ pub fn create_argument_metadata(bcx: @mut Block,
         return;
     }
 
-    // Limited the scope within which `debug_context` is live,
-    // otherwise => borrowing errors
-    {
-        let debug_context = dbg_cx(cx);
-
-        // If this is a new function, reset the counter. llvm::DIBuilder
-        // wants arguments to be indexed starting from 1.
-        if fcx.id != debug_context.last_function_context_id {
-                    debug_context.argument_counter = 1;
-        }
-        // Keep track of the function we are in
-        debug_context.last_function_context_id = fcx.id;
-    }
-
     let def_map = cx.tcx.def_map;
     let file_metadata = file_metadata(cx, filename);
     let scope = create_function_metadata(fcx);
@@ -241,13 +201,13 @@ pub fn create_argument_metadata(bcx: @mut Block,
         debug!("create_argument_metadata: %s", name);
 
         let argument_index = {
-            let debug_context = dbg_cx(cx);
-            let argument_index = debug_context.argument_counter;
-            debug_context.argument_counter += 1;
+            let counter = &mut fcx.debug_context.get_mut_ref().argument_counter;
+            let argument_index = *counter;
+            *counter += 1;
             argument_index as c_uint
         };
 
-        let arg_metadata = do name.to_c_str().with_ref |name| {
+        let arg_metadata = do name.with_c_str |name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateLocalVariable(
                     DIB(cx),
@@ -270,7 +230,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
             }
         };
 
-        set_debug_location(cx, lexical_block_metadata(bcx), loc.line, loc.col.to_uint());
+        set_debug_location(cx, scope, loc.line, loc.col.to_uint());
         unsafe {
             let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
                 DIB(cx),
@@ -286,28 +246,36 @@ pub fn create_argument_metadata(bcx: @mut Block,
 /// Sets the current debug location at the beginning of the span
 ///
 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...)
-pub fn update_source_pos(bcx: @mut Block, span: span) {
-    if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) {
+pub fn update_source_pos(fcx: &FunctionContext,
+                         node_id: ast::NodeId,
+                         span: span) {
+    let cx: &mut CrateContext = fcx.ccx;
+
+    if !cx.sess.opts.debuginfo || (*span.lo == 0 && *span.hi == 0) {
         return;
     }
-    debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span));
-    let loc = span_start(bcx.ccx(), span);
-    set_debug_location(bcx.ccx(), lexical_block_metadata(bcx), loc.line, loc.col.to_uint())
+
+    debug!("update_source_pos: %s", cx.sess.codemap.span_to_str(span));
+
+    let loc = span_start(cx, span);
+    let scope = scope_metadata(fcx, node_id, span);
+
+    set_debug_location(cx, scope, loc.line, loc.col.to_uint());
 }
 
 /// Creates debug information for the given function.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
 /// The return value should be ignored if called from outside of the debuginfo module.
-pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
+pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
     let cx = fcx.ccx;
 
     let fnitem = cx.tcx.items.get_copy(&fcx.id);
-    let (ident, ret_ty, id) = match fnitem {
+    let (ident, fn_decl, id) = match fnitem {
         ast_map::node_item(ref item, _) => {
             match item.node {
-                ast::item_fn(ast::fn_decl { output: ref ty, _}, _, _, _, _) => {
-                    (item.ident, ty, item.id)
+                ast::item_fn(ref fn_decl, _, _, _, _) => {
+                    (item.ident, fn_decl, item.id)
                 }
                 _ => fcx.ccx.sess.span_bug(item.span,
                                            "create_function_metadata: item bound to non-function")
@@ -315,20 +283,20 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
         }
         ast_map::node_method(
             @ast::method {
-                decl: ast::fn_decl { output: ref ty, _ },
+                decl: ref fn_decl,
                 id: id,
                 ident: ident,
                 _
             },
             _,
             _) => {
-            (ident, ty, id)
+            (ident, fn_decl, id)
         }
         ast_map::node_expr(ref expr) => {
             match expr.node {
-                ast::expr_fn_block(ref decl, _) => {
+                ast::expr_fn_block(ref fn_decl, _) => {
                     let name = gensym_name("fn");
-                    (name, &decl.output, expr.id)
+                    (name, fn_decl, expr.id)
                 }
                 _ => fcx.ccx.sess.span_bug(expr.span,
                         "create_function_metadata: expected an expr_fn_block here")
@@ -337,20 +305,20 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
         ast_map::node_trait_method(
             @ast::provided(
                 @ast::method {
-                    decl: ast::fn_decl { output: ref ty, _ },
+                    decl: ref fn_decl,
                     id: id,
                     ident: ident,
                     _
                 }),
             _,
             _) => {
-            (ident, ty, id)
+            (ident, fn_decl, id)
         }
         _ => fcx.ccx.sess.bug(fmt!("create_function_metadata: unexpected sort of node: %?", fnitem))
     };
 
-    match dbg_cx(cx).created_functions.find(&id) {
-        Some(fn_metadata) => return *fn_metadata,
+    match dbg_cx(cx).created_functions.find_copy(&id) {
+        Some(fn_metadata) => return fn_metadata,
         None => ()
     }
 
@@ -367,9 +335,9 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
     let file_metadata = file_metadata(cx, loc.file.name);
 
     let return_type_metadata = if cx.sess.opts.extra_debuginfo {
-        match ret_ty.node {
+        match fn_decl.output.node {
           ast::ty_nil => ptr::null(),
-          _ => type_metadata(cx, ty::node_id_to_type(cx.tcx, id), ret_ty.span)
+          _ => type_metadata(cx, ty::node_id_to_type(cx.tcx, id), fn_decl.output.span)
         }
     } else {
         ptr::null()
@@ -383,8 +351,8 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
     };
 
     let fn_metadata =
-        do cx.sess.str_of(ident).to_c_str().with_ref |name| {
-        do cx.sess.str_of(ident).to_c_str().with_ref |linkage| {
+        do cx.sess.str_of(ident).with_c_str |name| {
+        do cx.sess.str_of(ident).with_c_str |linkage| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFunction(
                     DIB(cx),
@@ -405,6 +373,27 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
             }
         }};
 
+    assert!(fcx.debug_context.is_none());
+
+    let mut fn_debug_context = ~FunctionDebugContext::new();
+    let entry_block_id = fcx.entry_bcx.get_ref().node_info.get_ref().id;
+    let entry_block = cx.tcx.items.get(&entry_block_id);
+
+    match *entry_block {
+        ast_map::node_block(ref block) => {
+            let scope_map = &mut fn_debug_context.scope_map;
+            let arg_pats = do fn_decl.inputs.map |arg_ref| { arg_ref.pat };
+
+            populate_scope_map(cx, arg_pats, block, fn_metadata, scope_map);
+        }
+        _ => cx.sess.span_bug(span,
+                fmt!("debuginfo::create_function_metadata() - \
+                     FunctionContext::entry_bcx::node_info points to wrong type of ast_map entry. \
+                     Expected: ast_map::node_block, actual: %?", *entry_block))
+    }
+
+    fcx.debug_context = Some(fn_debug_context);
+
     dbg_cx(cx).created_functions.insert(id, fn_metadata);
     return fn_metadata;
 }
@@ -431,11 +420,11 @@ fn compile_unit_metadata(cx: @mut CrateContext) {
     let work_dir = cx.sess.working_dir.to_str();
     let producer = fmt!("rustc version %s", env!("CFG_VERSION"));
 
-    do crate_name.to_c_str().with_ref |crate_name| {
-    do work_dir.to_c_str().with_ref |work_dir| {
-    do producer.to_c_str().with_ref |producer| {
-    do "".to_c_str().with_ref |flags| {
-    do "".to_c_str().with_ref |split_name| {
+    do crate_name.with_c_str |crate_name| {
+    do work_dir.with_c_str |work_dir| {
+    do producer.with_c_str |producer| {
+    do "".with_c_str |flags| {
+    do "".with_c_str |split_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
                 DW_LANG_RUST as c_uint, crate_name, work_dir, producer,
@@ -445,6 +434,56 @@ fn compile_unit_metadata(cx: @mut CrateContext) {
     }}}}};
 }
 
+fn declare_local(bcx: @mut Block,
+                 variable_ident: ast::ident,
+                 node_id: ast::NodeId,
+                 variable_type: ty::t,
+                 span: span) {
+    let cx: &mut CrateContext = bcx.ccx();
+
+    let filename = span_start(cx, span).file.name;
+    let file_metadata = file_metadata(cx, filename);
+
+    let name: &str = cx.sess.str_of(variable_ident);
+    let loc = span_start(cx, span);
+    let type_metadata = type_metadata(cx, variable_type, span);
+    let scope = scope_metadata(bcx.fcx, node_id, span);
+
+    let var_metadata = do name.with_c_str |name| {
+        unsafe {
+            llvm::LLVMDIBuilderCreateLocalVariable(
+                DIB(cx),
+                DW_TAG_auto_variable,
+                scope,
+                name,
+                file_metadata,
+                loc.line as c_uint,
+                type_metadata,
+                false,
+                0,
+                0)
+        }
+    };
+
+    let llptr = match bcx.fcx.lllocals.find_copy(&node_id) {
+        Some(v) => v,
+        None => {
+            bcx.tcx().sess.span_bug(span, fmt!("No entry in lllocals table for %?", node_id));
+        }
+    };
+
+    set_debug_location(cx, scope, loc.line, loc.col.to_uint());
+    unsafe {
+        let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
+            DIB(cx),
+            llptr,
+            var_metadata,
+            bcx.llbb);
+
+        llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
+    }
+}
+
 fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
     match dbg_cx(cx).created_files.find_equiv(&full_path) {
         Some(file_metadata) => return *file_metadata,
@@ -462,8 +501,8 @@ fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
         };
 
     let file_metadata =
-        do file_name.to_c_str().with_ref |file_name| {
-        do work_dir.to_c_str().with_ref |work_dir| {
+        do file_name.with_c_str |file_name| {
+        do work_dir.with_c_str |work_dir| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
             }
@@ -473,50 +512,26 @@ fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
     return file_metadata;
 }
 
-/// Get or create the lexical block metadata node for the given LLVM basic block.
-fn lexical_block_metadata(bcx: @mut Block) -> DILexicalBlock {
-    let cx = bcx.ccx();
-    let mut bcx = bcx;
-
-    // Search up the tree of basic blocks until we find one that knows the containing lexical block.
-    while bcx.node_info.is_none() {
-        match bcx.parent {
-            Some(b) => bcx = b,
-            None => cx.sess.bug("debuginfo: Could not find lexical block for LLVM basic block.")
-        }
-    }
-
-    let span = bcx.node_info.unwrap().span;
-    let id = bcx.node_info.unwrap().id;
-
-    // Check whether we already have a cache entry for this node id
-    match dbg_cx(cx).created_blocks.find(&id) {
-        Some(block) => return *block,
-        None => ()
+/// Finds the scope metadata node for the given AST node.
+fn scope_metadata(fcx: &FunctionContext,
+                  node_id: ast::NodeId,
+                  span: span) -> DIScope {
+    if fcx.debug_context.is_none() {
+        fcx.ccx.sess.span_bug(span, "debuginfo: FunctionDebugContext should be initialized \
+                                     but is not!");
     }
 
-    debug!("lexical_block_metadata: %s", bcx.sess().codemap.span_to_str(span));
+    let scope_map = &fcx.debug_context.get_ref().scope_map;
 
-    let parent = match bcx.parent {
-        None => create_function_metadata(bcx.fcx),
-        Some(b) => lexical_block_metadata(b)
-    };
+    match scope_map.find_copy(&node_id) {
+        Some(scope_metadata) => scope_metadata,
+        None => {
+            let node = fcx.ccx.tcx.items.get_copy(&node_id);
 
-    let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, loc.file.name);
-
-    let lexical_block_metadata = unsafe {
-        llvm::LLVMDIBuilderCreateLexicalBlock(
-            DIB(cx),
-            parent,
-            file_metadata,
-            loc.line as c_uint,
-            loc.col.to_uint() as c_uint)
-    };
-
-    dbg_cx(cx).created_blocks.insert(id, lexical_block_metadata);
-
-    return lexical_block_metadata;
+            fcx.ccx.sess.span_bug(span,
+                fmt!("debuginfo: Could not find scope info for node %?", node));
+        }
+    }
 }
 
 fn basic_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
@@ -551,7 +566,7 @@ fn basic_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let ty_metadata = do name.to_c_str().with_ref |name| {
+    let ty_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -572,7 +587,7 @@ fn pointer_type_metadata(cx: &mut CrateContext,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = ty_to_str(cx.tcx, pointer_type);
-    let ptr_metadata = do name.to_c_str().with_ref |name| {
+    let ptr_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreatePointerType(
                 DIB(cx),
@@ -666,7 +681,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let name: &str = cx.sess.str_of(v.name);
             let discriminant_value = v.disr_val as c_ulonglong;
 
-            do name.to_c_str().with_ref |name| {
+            do name.with_c_str |name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateEnumerator(
                         DIB(cx),
@@ -680,7 +695,7 @@ fn enum_metadata(cx: &mut CrateContext,
     let loc = span_start(cx, span);
     let file_metadata = file_metadata(cx, loc.file.name);
 
-    let discriminant_type_metadata = do enum_name.to_c_str().with_ref |enum_name| {
+    let discriminant_type_metadata = do enum_name.with_c_str |enum_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateEnumerationType(
                 DIB(cx),
@@ -717,7 +732,7 @@ fn enum_metadata(cx: &mut CrateContext,
                         Some(discriminant_type_metadata),
                         span);
 
-                    do "".to_c_str().with_ref |name| {
+                    do "".with_c_str |name| {
                         unsafe {
                             llvm::LLVMDIBuilderCreateMemberType(
                                 DIB(cx),
@@ -737,7 +752,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let enum_llvm_type = type_of::type_of(cx, enum_type);
             let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
 
-            return do enum_name.to_c_str().with_ref |enum_name| {
+            return do enum_name.with_c_str |enum_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateUnionType(
                     DIB(cx),
@@ -821,7 +836,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
             let member_offset = machine::llelement_offset(cx, composite_llvm_type, i);
             let member_name: &str = member_names[i];
 
-            do member_name.to_c_str().with_ref |member_name| {
+            do member_name.with_c_str |member_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateMemberType(
                         DIB(cx),
@@ -839,7 +854,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
         })
         .collect();
 
-    return do composite_type_name.to_c_str().with_ref |name| {
+    return do composite_type_name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateStructType(
                 DIB(cx),
@@ -1065,7 +1080,7 @@ fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
     debug!("unimplemented_type_metadata: %?", ty::get(t));
 
     let name = ty_to_str(cx.tcx, t);
-    let metadata = do fmt!("NYI<%s>", name).to_c_str().with_ref |name| {
+    let metadata = do fmt!("NYI<%s>", name).with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -1206,7 +1221,7 @@ fn create_pointer_to_box_metadata(cx: &mut CrateContext,
     return type_metadata;
 }
 
-fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: uint) {
+fn set_debug_location(cx: &mut CrateContext, scope: DIScope, line: uint, col: uint) {
     if dbg_cx(cx).curr_loc == (line, col) {
         return;
     }
@@ -1224,7 +1239,6 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui
     }
 }
 
-
 //=-------------------------------------------------------------------------------------------------
 //  Utility Functions
 //=-------------------------------------------------------------------------------------------------
@@ -1256,3 +1270,451 @@ fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext {
 fn DIB(cx: &CrateContext) -> DIBuilderRef {
     cx.dbg_cx.get_ref().builder
 }
+
+
+// This procedure builds the *scope map* for a given function, which maps any given ast::NodeId in
+// the function's AST to the correct DIScope metadata instance.
+//
+// This builder procedure walks the AST in execution order and keeps track of what belongs to which
+// scope, creating DIScope DIEs along the way, and introducing *artificial* lexical scope
+// descriptors where necessary. These artificial scopes allow GDB to correctly handle name
+// shadowing.
+fn populate_scope_map(cx: &mut CrateContext,
+                      arg_pats: &[@ast::pat],
+                      fn_entry_block: &ast::Block,
+                      fn_metadata: DISubprogram,
+                      scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+    let def_map = cx.tcx.def_map;
+
+    struct ScopeStackEntry {
+        scope_metadata: DIScope,
+        ident: Option<ast::ident>
+    }
+
+    let mut scope_stack = ~[ScopeStackEntry { scope_metadata: fn_metadata, ident: None }];
+
+    // Push argument identifiers onto the stack so arguments integrate nicely with variable
+    // shadowing.
+    for &arg_pat in arg_pats.iter() {
+        do pat_util::pat_bindings(def_map, arg_pat) |_, _, _, path_ref| {
+            let ident = ast_util::path_to_ident(path_ref);
+            scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, ident: Some(ident) });
+        }
+    }
+
+    walk_block(cx, fn_entry_block, &mut scope_stack, scope_map);
+
+    // local helper functions for walking the AST.
+
+    fn with_new_scope(cx: &mut CrateContext,
+                      scope_span: span,
+                      scope_stack: &mut ~[ScopeStackEntry],
+                      scope_map: &mut HashMap<ast::NodeId, DIScope>,
+                      inner_walk: &fn(&mut CrateContext,
+                                      &mut ~[ScopeStackEntry],
+                                      &mut HashMap<ast::NodeId, DIScope>)) {
+        // Create a new lexical scope and push it onto the stack
+        let loc = cx.sess.codemap.lookup_char_pos(scope_span.lo);
+        let file_metadata = file_metadata(cx, loc.file.name);
+        let parent_scope = scope_stack.last().scope_metadata;
+
+        let scope_metadata = unsafe {
+            llvm::LLVMDIBuilderCreateLexicalBlock(
+                DIB(cx),
+                parent_scope,
+                file_metadata,
+                loc.line as c_uint,
+                loc.col.to_uint() as c_uint)
+        };
+
+        scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, ident: None });
+
+        inner_walk(cx, scope_stack, scope_map);
+
+        // pop artificial scopes
+        while scope_stack.last().ident.is_some() {
+            scope_stack.pop();
+        }
+
+        if scope_stack.last().scope_metadata != scope_metadata {
+            cx.sess.span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
+        }
+
+        scope_stack.pop();
+    }
+
+    fn walk_block(cx: &mut CrateContext,
+                  block: &ast::Block,
+                  scope_stack: &mut ~[ScopeStackEntry],
+                  scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+        scope_map.insert(block.id, scope_stack.last().scope_metadata);
+
+        // The interesting things here are statements and the concluding expression.
+        for &@ ref statement in block.stmts.iter() {
+            scope_map.insert(ast_util::stmt_id(statement), scope_stack.last().scope_metadata);
+
+            match statement.node {
+                ast::stmt_decl(@ref decl, _) => walk_decl(cx, decl, scope_stack, scope_map),
+                ast::stmt_expr(@ref exp, _) |
+                ast::stmt_semi(@ref exp, _) => walk_expr(cx, exp, scope_stack, scope_map),
+                ast::stmt_mac(*) => () // ignore macros (which should be expanded anyway)
+            }
+        }
+
+        for &@ref exp in block.expr.iter() {
+            walk_expr(cx, exp, scope_stack, scope_map);
+        }
+    }
+
+    fn walk_decl(cx: &mut CrateContext,
+                 decl: &ast::decl,
+                 scope_stack: &mut ~[ScopeStackEntry],
+                 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+        match *decl {
+            codemap::spanned { node: ast::decl_local(@ref local), _ } => {
+                scope_map.insert(local.id, scope_stack.last().scope_metadata);
+
+                walk_pattern(cx, local.pat, scope_stack, scope_map);
+
+                for &@ref exp in local.init.iter() {
+                    walk_expr(cx, exp, scope_stack, scope_map);
+                }
+            }
+            _ => ()
+        }
+    }
+
+    fn walk_pattern(cx: &mut CrateContext,
+                    pat: @ast::pat,
+                    scope_stack: &mut ~[ScopeStackEntry],
+                    scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+
+        let def_map = cx.tcx.def_map;
+
+        // Unfortunately, we cannot just use pat_util::pat_bindings() or ast_util::walk_pat() here
+        // because we have to visit *all* nodes in order to put them into the scope map. The above
+        // functions don't do that.
+        match pat.node {
+            ast::pat_ident(_, ref path_ref, ref sub_pat_opt) => {
+
+                // Check if this is a binding. If so we need to put it on the scope stack and maybe
+                // introduce an articial scope
+                if pat_util::pat_is_binding(def_map, pat) {
+
+                    let ident = ast_util::path_to_ident(path_ref);
+
+                    // LLVM does not properly generate 'DW_AT_start_scope' fields for variable DIEs.
+                    // For this reason we have to introduce an artificial scope at bindings whenever
+                    // a variable with the same name is declared in *any* parent scope.
+                    //
+                    // Otherwise the following error occurs:
+                    //
+                    // let x = 10;
+                    //
+                    // do_something(); // 'gdb print x' correctly prints 10
+                    //
+                    // {
+                    //     do_something(); // 'gdb print x' prints 0, because it already reads the
+                    //                     // uninitialized 'x' from the next line...
+                    //     let x = 100;
+                    //     do_something(); // 'gdb print x' correctly prints 100
+                    // }
+
+                    // Is there already a binding with that name?
+                    let need_new_scope = scope_stack
+                        .iter()
+                        .any(|entry| entry.ident.iter().any(|i| *i == ident));
+
+                    if need_new_scope {
+                        // Create a new lexical scope and push it onto the stack
+                        let loc = cx.sess.codemap.lookup_char_pos(pat.span.lo);
+                        let file_metadata = file_metadata(cx, loc.file.name);
+                        let parent_scope = scope_stack.last().scope_metadata;
+
+                        let scope_metadata = unsafe {
+                            llvm::LLVMDIBuilderCreateLexicalBlock(
+                                DIB(cx),
+                                parent_scope,
+                                file_metadata,
+                                loc.line as c_uint,
+                                loc.col.to_uint() as c_uint)
+                        };
+
+                        scope_stack.push(ScopeStackEntry {
+                            scope_metadata: scope_metadata,
+                            ident: Some(ident)
+                        });
+
+                    } else {
+                        // Push a new entry anyway so the name can be found
+                        let prev_metadata = scope_stack.last().scope_metadata;
+                        scope_stack.push(ScopeStackEntry {
+                            scope_metadata: prev_metadata,
+                            ident: Some(ident)
+                        });
+                    }
+                }
+
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+
+                for &sub_pat in sub_pat_opt.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+            }
+
+            ast::pat_wild => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+            }
+
+            ast::pat_enum(_, ref sub_pats_opt) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+
+                for ref sub_pats in sub_pats_opt.iter() {
+                    for &p in sub_pats.iter() {
+                        walk_pattern(cx, p, scope_stack, scope_map);
+                    }
+                }
+            }
+
+            ast::pat_struct(_, ref field_pats, _) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+
+                for &ast::field_pat { pat: sub_pat, _ } in field_pats.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+            }
+
+            ast::pat_tup(ref sub_pats) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+
+                for &sub_pat in sub_pats.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+            }
+
+            ast::pat_box(sub_pat)    |
+            ast::pat_uniq(sub_pat)   |
+            ast::pat_region(sub_pat) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+                walk_pattern(cx, sub_pat, scope_stack, scope_map);
+            }
+
+            ast::pat_lit(@ref exp) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+                walk_expr(cx, exp, scope_stack, scope_map);
+            }
+
+            ast::pat_range(@ref exp1, @ref exp2) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+                walk_expr(cx, exp1, scope_stack, scope_map);
+                walk_expr(cx, exp2, scope_stack, scope_map);
+            }
+
+            ast::pat_vec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
+                scope_map.insert(pat.id, scope_stack.last().scope_metadata);
+
+                for &sub_pat in front_sub_pats.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+
+                for &sub_pat in middle_sub_pats.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+
+                for &sub_pat in back_sub_pats.iter() {
+                    walk_pattern(cx, sub_pat, scope_stack, scope_map);
+                }
+            }
+        }
+    }
+
+    fn walk_expr(cx: &mut CrateContext,
+                 exp: &ast::expr,
+                 scope_stack: &mut ~[ScopeStackEntry],
+                 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+
+        scope_map.insert(exp.id, scope_stack.last().scope_metadata);
+
+        match exp.node {
+            ast::expr_self     |
+            ast::expr_lit(_)   |
+            ast::expr_break(_) |
+            ast::expr_again(_) |
+            ast::expr_path(_)  => (),
+
+            ast::expr_vstore(@ref sub_exp, _)   |
+            ast::expr_cast(@ref sub_exp, _)     |
+            ast::expr_addr_of(_, @ref sub_exp)  |
+            ast::expr_field(@ref sub_exp, _, _) |
+            ast::expr_paren(@ref sub_exp)       => walk_expr(cx, sub_exp, scope_stack, scope_map),
+
+            ast::expr_ret(exp_opt) => match exp_opt {
+                Some(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
+                None => ()
+            },
+
+            ast::expr_unary(node_id, _, @ref sub_exp) => {
+                scope_map.insert(node_id, scope_stack.last().scope_metadata);
+                walk_expr(cx, sub_exp, scope_stack, scope_map);
+            }
+
+            ast::expr_assign_op(node_id, _, @ref lhs, @ref rhs) |
+            ast::expr_index(node_id, @ref lhs, @ref rhs)        |
+            ast::expr_binary(node_id, _, @ref lhs, @ref rhs)    => {
+                scope_map.insert(node_id, scope_stack.last().scope_metadata);
+                walk_expr(cx, lhs, scope_stack, scope_map);
+                walk_expr(cx, rhs, scope_stack, scope_map);
+            }
+
+            ast::expr_vec(ref init_expressions, _) |
+            ast::expr_tup(ref init_expressions)    => {
+                for &@ref ie in init_expressions.iter() {
+                    walk_expr(cx, ie, scope_stack, scope_map);
+                }
+            }
+
+            ast::expr_assign(@ref sub_exp1, @ref sub_exp2)    |
+            ast::expr_log(@ref sub_exp1, @ref sub_exp2)       |
+            ast::expr_repeat(@ref sub_exp1, @ref sub_exp2, _) => {
+                walk_expr(cx, sub_exp1, scope_stack, scope_map);
+                walk_expr(cx, sub_exp2, scope_stack, scope_map);
+            }
+
+            ast::expr_if(@ref cond_exp, ref then_block, ref opt_else_exp) => {
+                walk_expr(cx, cond_exp, scope_stack, scope_map);
+
+                do with_new_scope(cx, then_block.span, scope_stack, scope_map) |cx,
+                                                                                scope_stack,
+                                                                                scope_map| {
+                    walk_block(cx, then_block, scope_stack, scope_map);
+                }
+
+                match *opt_else_exp {
+                    Some(@ref else_exp) => walk_expr(cx, else_exp, scope_stack, scope_map),
+                    _ => ()
+                }
+            }
+
+            ast::expr_while(@ref cond_exp, ref loop_body) => {
+                walk_expr(cx, cond_exp, scope_stack, scope_map);
+
+                do with_new_scope(cx, loop_body.span, scope_stack, scope_map) |cx,
+                                                                               scope_stack,
+                                                                               scope_map| {
+                    walk_block(cx, loop_body, scope_stack, scope_map);
+                }
+            }
+
+            ast::expr_for_loop(_, _, _) => {
+                cx.sess.span_bug(exp.span, "debuginfo::populate_scope_map() - \
+                                            Found unexpanded for-loop.");
+            }
+
+            ast::expr_mac(_) => {
+                cx.sess.span_bug(exp.span, "debuginfo::populate_scope_map() - \
+                                            Found unexpanded macro.");
+            }
+
+            ast::expr_loop(ref block, _) |
+            ast::expr_block(ref block)   => {
+                do with_new_scope(cx, block.span, scope_stack, scope_map) |cx,
+                                                                           scope_stack,
+                                                                           scope_map| {
+                    walk_block(cx, block, scope_stack, scope_map);
+                }
+            }
+
+            ast::expr_fn_block(ast::fn_decl { inputs: ref inputs, _ }, ref block) => {
+                do with_new_scope(cx, block.span, scope_stack, scope_map) |cx,
+                                                                           scope_stack,
+                                                                           scope_map| {
+                    for &ast::arg { pat: pattern, _ } in inputs.iter() {
+                        walk_pattern(cx, pattern, scope_stack, scope_map);
+                    }
+
+                    walk_block(cx, block, scope_stack, scope_map);
+                }
+            }
+
+            // ast::expr_loop_body(@ref inner_exp) |
+            ast::expr_do_body(@ref inner_exp)   => {
+                let inner_expr_is_expr_fn_block = match *inner_exp {
+                    ast::expr { node: ast::expr_fn_block(*), _ } => true,
+                    _ => false
+                };
+
+                if !inner_expr_is_expr_fn_block {
+                    cx.sess.span_bug(inner_exp.span, "debuginfo: Inner expression was expected \
+                                                      to be an ast::expr_fn_block.");
+                }
+
+                walk_expr(cx, inner_exp, scope_stack, scope_map);
+            }
+
+            ast::expr_call(@ref fn_exp, ref args, _) => {
+                walk_expr(cx, fn_exp, scope_stack, scope_map);
+
+                for &@ref arg_exp in args.iter() {
+                    walk_expr(cx, arg_exp, scope_stack, scope_map);
+                }
+            }
+
+            ast::expr_method_call(node_id, @ref receiver_exp, _, _, ref args, _) => {
+                scope_map.insert(node_id, scope_stack.last().scope_metadata);
+                walk_expr(cx, receiver_exp, scope_stack, scope_map);
+
+                for &@ref arg_exp in args.iter() {
+                    walk_expr(cx, arg_exp, scope_stack, scope_map);
+                }
+            }
+
+            ast::expr_match(@ref discriminant_exp, ref arms) => {
+                walk_expr(cx, discriminant_exp, scope_stack, scope_map);
+
+                // for each arm we have to first walk the pattern as these might introduce new
+                // artificial scopes. It should be sufficient to walk only one pattern per arm, as
+                // they all must contain the same binding names
+
+                for arm_ref in arms.iter() {
+                    let arm_span = arm_ref.pats[0].span;
+
+                    do with_new_scope(cx, arm_span, scope_stack, scope_map) |cx,
+                                                                             scope_stack,
+                                                                             scope_map| {
+                        walk_pattern(cx, arm_ref.pats[0], scope_stack, scope_map);
+
+                        for &@ref guard_exp in arm_ref.guard.iter() {
+                            walk_expr(cx, guard_exp, scope_stack, scope_map)
+                        }
+
+                        walk_block(cx, &arm_ref.body, scope_stack, scope_map);
+                    }
+                }
+            }
+
+            ast::expr_struct(_, ref fields, ref base_exp) => {
+                for &ast::Field { expr: @ref exp, _ } in fields.iter() {
+                    walk_expr(cx, exp, scope_stack, scope_map);
+                }
+
+                match *base_exp {
+                    Some(@ref exp) => walk_expr(cx, exp, scope_stack, scope_map),
+                    None => ()
+                }
+            }
+
+            ast::expr_inline_asm(ast::inline_asm { inputs: ref inputs,
+                                                   outputs: ref outputs,
+                                                   _ }) => {
+                // inputs, outputs: ~[(@str, @expr)]
+                for &(_, @ref exp) in inputs.iter() {
+                    walk_expr(cx, exp, scope_stack, scope_map);
+                }
+
+                for &(_, @ref exp) in outputs.iter() {
+                    walk_expr(cx, exp, scope_stack, scope_map);
+                }
+            }
+        }
+    }
+}
index cb4a7f364dac6c39c11a21cb704161abaea696ea..04fd477a317380d2eee4a560eeb9c482e0f24bca 100644 (file)
@@ -413,7 +413,7 @@ pub fn trans_into(bcx: @mut Block, expr: @ast::expr, dest: Dest) -> @mut Block {
            dest.to_str(bcx.ccx()));
     let _indenter = indenter();
 
-    debuginfo::update_source_pos(bcx, expr.span);
+    debuginfo::update_source_pos(bcx.fcx, expr.id, expr.span);
 
     let dest = {
         if ty::type_is_nil(ty) || ty::type_is_bot(ty) {
@@ -485,7 +485,7 @@ fn trans_to_datum_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
     debug!("trans_to_datum_unadjusted(expr=%s)", bcx.expr_to_str(expr));
     let _indenter = indenter();
 
-    debuginfo::update_source_pos(bcx, expr.span);
+    debuginfo::update_source_pos(bcx.fcx, expr.id, expr.span);
 
     match ty::expr_kind(bcx.tcx(), bcx.ccx().maps.method_map, expr) {
         ty::LvalueExpr => {
@@ -697,8 +697,7 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: @ast::expr,
                    expr_to_str(expr, tcx.sess.intr()),
                    expr_ty.repr(tcx));
             return closure::trans_expr_fn(bcx, sigil, decl, body,
-                                          expr.id, expr.id,
-                                          None, dest);
+                                          expr.id, expr.id, dest);
         }
         ast::expr_do_body(blk) => {
             return trans_into(bcx, blk, dest);
@@ -1031,7 +1030,7 @@ fn get_val(bcx: @mut Block, did: ast::def_id, const_ty: ty::t)
                             let symbol = csearch::get_symbol(
                                 bcx.ccx().sess.cstore,
                                 did);
-                            let llval = do symbol.to_c_str().with_ref |buf| {
+                            let llval = do symbol.with_c_str |buf| {
                                 llvm::LLVMAddGlobal(bcx.ccx().llmod,
                                                     llty.to_ref(),
                                                     buf)
index 4f894deb1a1c19eed3d692569ea876997395a246..9acc3018046b3bf324559ed27675ea2ac27668fe 100644 (file)
@@ -673,7 +673,7 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed();
     note_unique_llvm_symbol(ccx, name);
     debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name);
-    let gvar = do name.to_c_str().with_ref |buf| {
+    let gvar = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
         }
index f5b2ff755966e6cf3f29ff2f7b2cb2fe26202d19..9ffbafb706cd4ab8ce68d65c277a622af86e1a8e 100644 (file)
@@ -537,7 +537,7 @@ pub fn make_vtable(ccx: &mut CrateContext,
 
         let tbl = C_struct(components);
         let vtable = ccx.sess.str_of(gensym_name("vtable"));
-        let vt_gvar = do vtable.to_c_str().with_ref |buf| {
+        let vt_gvar = do vtable.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(vt_gvar, tbl);
index 5b0e2fa18f240af3716c6604a6ae391512b18d5e..47d5b7ff3a53f9ae5b72793068a0b84f919b3fd8 100644 (file)
@@ -265,7 +265,7 @@ pub fn trans_lit_str(bcx: @mut Block,
         Ignore => bcx,
         SaveIn(lldest) => {
             unsafe {
-                let bytes = str_lit.len(); // count null-terminator too
+                let bytes = str_lit.len();
                 let llbytes = C_uint(bcx.ccx(), bytes);
                 let llcstr = C_cstr(bcx.ccx(), str_lit);
                 let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p().to_ref());
index 8d94a0d10d6fae3c71e2b5754b157886cd3fb334..f8f6f7b87ec6a9419208f6cf08bd98bde9b55226 100644 (file)
@@ -171,7 +171,7 @@ pub fn struct_(els: &[Type], packed: bool) -> Type {
 
     pub fn named_struct(name: &str) -> Type {
         let ctx = base::task_llcx();
-        ty!(name.to_c_str().with_ref(|s| llvm::LLVMStructCreateNamed(ctx, s)))
+        ty!(name.with_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s)))
     }
 
     pub fn empty_struct() -> Type {
index d8a9350e695d70404f3250bb904ab818d0eebb49..b7114e602830f3aa634dfc7eae180d7dd38c348c 100644 (file)
@@ -156,6 +156,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
                     kind_name = "variant";
                 }
                 None => {
+                    // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
                     fcx.infcx().type_error_message_str_with_expected(pat.span,
                                                        |expected, actual| {
                                                        expected.map_move_default(~"", |e| {
@@ -199,6 +200,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
             kind_name = "structure";
         }
         _ => {
+            // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
             fcx.infcx().type_error_message_str_with_expected(pat.span,
                                                |expected, actual| {
                                                expected.map_move_default(~"", |e| {
@@ -302,10 +304,13 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
             }
             None => {
                 let name = pprust::path_to_str(path, tcx.sess.intr());
+                // Check the pattern anyway, so that attempts to look
+                // up its type won't fail
+                check_pat(pcx, field.pat, ty::mk_err());
                 tcx.sess.span_err(span,
-                                  fmt!("struct `%s` does not have a field
-                                        named `%s`", name,
-                                       tcx.sess.str_of(field.ident)));
+                    fmt!("struct `%s` does not have a field named `%s`",
+                         name,
+                         tcx.sess.str_of(field.ident)));
             }
         }
     }
@@ -326,16 +331,17 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
 pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::NodeId, span: span,
                         expected: ty::t, path: &ast::Path,
                         fields: &[ast::field_pat], etc: bool,
-                        class_id: ast::def_id, substitutions: &ty::substs) {
+                        struct_id: ast::def_id,
+                        substitutions: &ty::substs) {
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let class_fields = ty::lookup_struct_fields(tcx, class_id);
+    let class_fields = ty::lookup_struct_fields(tcx, struct_id);
 
     // Check to ensure that the struct is the one specified.
     match tcx.def_map.find(&pat_id) {
         Some(&ast::def_struct(supplied_def_id))
-                if supplied_def_id == class_id => {
+                if supplied_def_id == struct_id => {
             // OK.
         }
         Some(&ast::def_struct(*)) | Some(&ast::def_variant(*)) => {
@@ -346,11 +352,11 @@ pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::NodeId, span: span,
                                    name));
         }
         _ => {
-            tcx.sess.span_bug(span, "resolve didn't write in class");
+            tcx.sess.span_bug(span, "resolve didn't write in struct ID");
         }
     }
 
-    check_struct_pat_fields(pcx, span, path, fields, class_fields, class_id,
+    check_struct_pat_fields(pcx, span, path, fields, class_fields, struct_id,
                             substitutions, etc);
 }
 
@@ -499,9 +505,22 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
                     substs);
             }
             _ => {
-                tcx.sess.span_err(pat.span,
-                                  fmt!("mismatched types: expected `%s` but found struct",
-                                       fcx.infcx().ty_to_str(expected)));
+               // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
+               fcx.infcx().type_error_message_str_with_expected(pat.span,
+                                                                |expected, actual| {
+                            expected.map_move_default(~"", |e| {
+                                    fmt!("mismatched types: expected `%s` but found %s",
+                                         e, actual)})},
+                                         Some(expected), ~"a structure pattern",
+                                         None);
+                match tcx.def_map.find(&pat.id) {
+                    Some(&ast::def_struct(supplied_def_id)) => {
+                         check_struct_pat(pcx, pat.id, pat.span, ty::mk_err(), path, *fields, etc,
+                         supplied_def_id,
+                         &ty::substs { self_ty: None, tps: ~[], regions: ty::ErasedRegions} );
+                    }
+                    _ => () // Error, but we're already in an error case
+                }
                 error_happened = true;
             }
         }
@@ -534,6 +553,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
                                                            found: e_count}),
                     _ => ty::terr_mismatch
                 };
+                // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
                 fcx.infcx().type_error_message_str_with_expected(pat.span, |expected, actual| {
                 expected.map_move_default(~"", |e| {
                     fmt!("mismatched types: expected `%s` but found %s",
@@ -581,6 +601,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
               for &elt in after.iter() {
                   check_pat(pcx, elt, ty::mk_err());
               }
+              // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
               fcx.infcx().type_error_message_str_with_expected(
                   pat.span,
                   |expected, actual| {
@@ -639,6 +660,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
         }
         _ => {
             check_pat(pcx, inner, ty::mk_err());
+            // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
             fcx.infcx().type_error_message_str_with_expected(
                 span,
                 |expected, actual| {
index d27b7f07a12271253b699360a0a430357ede7a2d..a46ee330a857954aa7d4d909da5400b616164b95 100644 (file)
@@ -3208,10 +3208,19 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
                   ty_param_count, ty_substs_len));
         fcx.infcx().next_ty_vars(ty_param_count)
     } else if ty_substs_len < ty_param_count {
+        let is_static_method = match fcx.ccx.tcx.def_map.find(&node_id) {
+            Some(&ast::def_static_method(*)) => true,
+            _ => false
+        };
         fcx.ccx.tcx.sess.span_err
             (span,
              fmt!("not enough type parameters provided: expected %u, found %u",
                   ty_param_count, ty_substs_len));
+        if is_static_method {
+            fcx.ccx.tcx.sess.span_note
+                (span, "Static methods have an extra implicit type parameter -- \
+                 did you omit the type parameter for the `Self` type?");
+        }
         fcx.infcx().next_ty_vars(ty_param_count)
     } else {
         pth.types.map(|aty| fcx.to_ty(aty))
index d034277d44af82526360f62b0b392d739f105d3c..922b1693094a95372e5bc9bfa0b248c494214ac3 100644 (file)
@@ -391,7 +391,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
             let target_ty = rcx.resolve_node_type(expr.id);
             match ty::get(target_ty).sty {
                 ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _, _) => {
-                    let source_ty = rcx.fcx.expr_ty(source);
+                    let source_ty = rcx.resolve_expr_type_adjusted(source);
                     constrain_regions_in_type(
                         rcx,
                         trait_region,
@@ -427,7 +427,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
         }
 
         ast::expr_fn_block(*) => {
-            check_expr_fn_block(rcx, expr, v, false);
+            check_expr_fn_block(rcx, expr, v);
         }
 
         ast::expr_loop(ref body, _) => {
@@ -454,8 +454,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
 
 fn check_expr_fn_block(rcx: @mut Rcx,
                        expr: @ast::expr,
-                       v: rvt,
-                       is_loop_body: bool) {
+                       v: rvt) {
     let tcx = rcx.fcx.tcx();
     match expr.node {
         ast::expr_fn_block(_, ref body) => {
@@ -464,7 +463,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
                 ty::ty_closure(
                     ty::ClosureTy {
                         sigil: ast::BorrowedSigil, region: region, _}) => {
-                    if get_freevars(tcx, expr.id).is_empty() && !is_loop_body {
+                    if get_freevars(tcx, expr.id).is_empty() {
                         // No free variables means that the environment
                         // will be NULL at runtime and hence the closure
                         // has static lifetime.
@@ -1153,17 +1152,20 @@ fn pointer_categorize(ty: ty::t) -> PointerCategorization {
         match ty::get(ty).sty {
             ty::ty_rptr(r, _) |
             ty::ty_evec(_, ty::vstore_slice(r)) |
+            ty::ty_trait(_, _, ty::RegionTraitStore(r), _, _) |
             ty::ty_estr(ty::vstore_slice(r)) => {
                 BorrowedPointer(r)
             }
             ty::ty_uniq(*) |
             ty::ty_estr(ty::vstore_uniq) |
+            ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
             ty::ty_evec(_, ty::vstore_uniq) => {
                 OwnedPointer
             }
             ty::ty_box(*) |
             ty::ty_ptr(*) |
             ty::ty_evec(_, ty::vstore_box) |
+            ty::ty_trait(_, _, ty::BoxTraitStore, _, _) |
             ty::ty_estr(ty::vstore_box) => {
                 OtherPointer
             }
index f2bde146ea79cf338f7660b06cce266470982131..7736dbbb99d98058251e2bd921e904f4b8188e05 100644 (file)
@@ -121,9 +121,9 @@ pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
                 };
             }
 
-            ty::ty_trait(_, _, ty::RegionTraitStore(*), _, _) => {
+            ty::ty_trait(_, _, ty::RegionTraitStore(*), m, _) => {
                 return do self.unpack_actual_value(a) |sty_a| {
-                    self.coerce_borrowed_object(a, sty_a, b)
+                    self.coerce_borrowed_object(a, sty_a, b, m)
                 };
             }
 
@@ -274,7 +274,8 @@ pub fn coerce_borrowed_vector(&self,
     fn coerce_borrowed_object(&self,
                               a: ty::t,
                               sty_a: &ty::sty,
-                              b: ty::t) -> CoerceResult
+                              b: ty::t,
+                              b_mutbl: ast::mutability) -> CoerceResult
     {
         debug!("coerce_borrowed_object(a=%s, sty_a=%?, b=%s)",
                a.inf_str(self.infcx), sty_a,
@@ -282,26 +283,21 @@ fn coerce_borrowed_object(&self,
 
         let tcx = self.infcx.tcx;
         let r_a = self.infcx.next_region_var(Coercion(self.trace));
-        let trt_mut;
 
         let a_borrowed = match *sty_a {
-            ty::ty_trait(_, _, ty::RegionTraitStore(_), _, _) => {
-                return self.subtype(a, b);
-            }
-            ty::ty_trait(did, ref substs, _, m, b) => {
-                trt_mut = m;
+            ty::ty_trait(did, ref substs, _, _, b) => {
                 ty::mk_trait(tcx, did, substs.clone(),
-                             ty::RegionTraitStore(r_a), m, b)
+                             ty::RegionTraitStore(r_a), b_mutbl, b)
             }
             _ => {
                 return self.subtype(a, b);
             }
         };
 
-        if_ok!(self.tys(a_borrowed, b));
+        if_ok!(self.subtype(a_borrowed, b));
         Ok(Some(@AutoDerefRef(AutoDerefRef {
             autoderefs: 0,
-            autoref: Some(AutoBorrowObj(r_a, trt_mut))
+            autoref: Some(AutoBorrowObj(r_a, b_mutbl))
         })))
     }
 
index b1492cac16e730213de27e1178a3a53e9da0f287..161d96d828b47c8830c1fd0f3406bb76cf7d1b28 100644 (file)
@@ -68,7 +68,7 @@
 use middle::typeck::infer::{TypeTrace};
 use util::common::indent;
 
-use std::result::{iter_vec2, map_vec2};
+use std::result;
 use std::vec;
 use syntax::ast::{Onceness, purity};
 use syntax::ast;
@@ -275,9 +275,9 @@ pub fn super_tps<C:Combine>(
     // variance.
 
     if vec::same_length(as_, bs) {
-        iter_vec2(as_, bs, |a, b| {
-            eq_tys(this, *a, *b)
-        }).then(|| Ok(as_.to_owned()) )
+        result::fold_(as_.iter().zip(bs.iter())
+                      .map(|(a, b)| eq_tys(this, *a, *b)))
+            .then(|| Ok(as_.to_owned()))
     } else {
         Err(ty::terr_ty_param_size(
             expected_found(this, as_.len(), bs.len())))
@@ -427,7 +427,8 @@ pub fn super_fn_sigs<C:Combine>(
 {
     fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<~[ty::t]> {
         if vec::same_length(a_args, b_args) {
-            map_vec2(a_args, b_args, |a, b| this.args(*a, *b))
+            result::collect(a_args.iter().zip(b_args.iter())
+                            .map(|(a, b)| this.args(*a, *b)))
         } else {
             Err(ty::terr_arg_count)
         }
@@ -586,8 +587,9 @@ pub fn super_tys<C:Combine>(
 
       (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => {
         if as_.len() == bs.len() {
-            map_vec2(*as_, *bs, |a, b| this.tys(*a, *b) )
-                .chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
+            result::collect(as_.iter().zip(bs.iter())
+                            .map(|(a, b)| this.tys(*a, *b)))
+                    .chain(|ts| Ok(ty::mk_tup(tcx, ts)) )
         } else {
             Err(ty::terr_tuple_size(
                 expected_found(this, as_.len(), bs.len())))
index 7fa7daf614901006d54b2cc334c962752007d925..a11abda8ec529d78b20baa4b018a642940e605ef 100644 (file)
@@ -698,6 +698,17 @@ pub fn resolve_type_vars_in_trait_ref_if_possible(@mut self,
         }
     }
 
+    // [Note-Type-error-reporting]
+    // An invariant is that anytime the expected or actual type is ty_err (the special
+    // error type, meaning that an error occurred when typechecking this expression),
+    // this is a derived error. The error cascaded from another error (that was already
+    // reported), so it's not useful to display it to the user.
+    // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
+    // type_error_message, and report_mismatched_types -- implement this logic.
+    // They check if either the actual or expected type is ty_err, and don't print the error
+    // in this case. The typechecker should only ever report type errors involving mismatched
+    // types using one of these four methods, and should not call span_err directly for such
+    // errors.
     pub fn type_error_message_str(@mut self,
                                   sp: span,
                                   mk_msg: &fn(Option<~str>, ~str) -> ~str,
index 195ff0dc6b695ed4e5ef5f20c5ced41bf7465bc7..7dbbf81f15dc1d1cdc13552517a4fad0a429573e 100644 (file)
@@ -252,7 +252,7 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
     let sess = build_session(sopts, demitter);
     let odir = getopts::opt_maybe_str(matches, "out-dir").map_move(|o| Path(o));
     let ofile = getopts::opt_maybe_str(matches, "o").map_move(|o| Path(o));
-    let cfg = build_configuration(sess, binary, &input);
+    let cfg = build_configuration(sess);
     let pretty = do getopts::opt_default(matches, "pretty", "normal").map_move |a| {
         parse_pretty(sess, a)
     };
@@ -359,7 +359,7 @@ impl Drop for finally {
                 let xs = [
                     ~"the compiler hit an unexpected failure path. \
                      this is a bug",
-                    ~"try running with RUST_LOG=rustc=1,::rt::backtrace \
+                    ~"try running with RUST_LOG=rustc=1 \
                      to get further details and report the results \
                      to github.com/mozilla/rust/issues"
                 ];
index c0e506774a371c3c787dc24001dfa59a4cbbf0bf..a8321dd95a1594276dbc35195b0af29cb2f855c4 100644 (file)
@@ -10,8 +10,6 @@
 
 //! AST-parsing helpers
 
-
-use rustc::driver::driver::{file_input, str_input};
 use rustc::driver::driver;
 use rustc::driver::session;
 use syntax::ast;
@@ -29,14 +27,15 @@ pub fn from_str(source: @str) -> @ast::Crate {
 
 pub fn from_file_sess(sess: session::Session, file: &Path) -> @ast::Crate {
     parse::parse_crate_from_file(
-        file, cfg(sess, file_input((*file).clone())), sess.parse_sess)
+        file, cfg(sess), sess.parse_sess)
 }
 
 pub fn from_str_sess(sess: session::Session, source: @str) -> @ast::Crate {
     parse::parse_crate_from_source_str(
-        @"-", source, cfg(sess, str_input(source)), sess.parse_sess)
+        @"-", source, cfg(sess), sess.parse_sess)
 }
 
-fn cfg(sess: session::Session, input: driver::input) -> ast::CrateConfig {
-    driver::build_configuration(sess, @"rustdoc", &input)
+fn cfg(sess: session::Session) -> ast::CrateConfig {
+    driver::build_configuration(sess)
 }
+
index 29ad9eb49a3b120526aff145cdd83f9172a50331..10c6832e08714f36cb870c2debdc81b826e3aa80 100644 (file)
@@ -142,7 +142,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     // Stage 1: parse the input and filter it into the program (as necessary)
     //
     debug!("parsing: %s", input);
-    let crate = parse_input(sess, binary, input);
+    let crate = parse_input(sess, binary);
     let mut to_run = ~[];       // statements to run (emitted back into code)
     let new_locals = @mut ~[];  // new locals being defined
     let mut result = None;      // resultant expression (to print via pp)
@@ -222,7 +222,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     let test = program.test_code(input, &result, *new_locals);
     debug!("testing with ^^^^^^ %?", (||{ println(test) })());
     let dinput = driver::str_input(test.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &dinput);
+    let cfg = driver::build_configuration(sess);
 
     let crate = driver::phase_1_parse_input(sess, cfg.clone(), &dinput);
     let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
@@ -241,7 +241,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     let code = program.code(input, &result);
     debug!("actually running ^^^^^^ %?", (||{ println(code) })());
     let input = driver::str_input(code.to_managed());
-    let cfg = driver::build_configuration(sess, binary, &input);
+    let cfg = driver::build_configuration(sess);
     let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
     let sess = driver::build_session(options, diagnostic::emit);
 
@@ -266,11 +266,10 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     //
     return (program, jit::consume_engine());
 
-    fn parse_input(sess: session::Session, binary: @str,
-                   input: &str) -> @ast::Crate {
+    fn parse_input(sess: session::Session, input: &str) -> @ast::Crate {
         let code = fmt!("fn main() {\n %s \n}", input);
         let input = driver::str_input(code.to_managed());
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         driver::phase_1_parse_input(sess, cfg.clone(), &input)
     }
 
@@ -308,7 +307,7 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
         let input = driver::file_input(src_path.clone());
         let sess = driver::build_session(options, diagnostic::emit);
         *sess.building_library = true;
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         let outputs = driver::build_output_filenames(
             &input, &None, &None, [], sess);
         // If the library already exists and is newer than the source
index 3ae2ad3751ffb0ddda5b09c0e128d7c74e3d3744..9ef341e439a97e62b9e56953915046433a6dec71 100644 (file)
@@ -108,7 +108,7 @@ fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
         };
         let input = driver::file_input(script);
         let sess = driver::build_session(options, diagnostic::emit);
-        let cfg = driver::build_configuration(sess, binary, &input);
+        let cfg = driver::build_configuration(sess);
         let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
         let crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
         let work_dir = build_pkg_id_in_workspace(id, workspace);
index 121dcf40150211f56aea9e52f9036b227a5a42df..be3cb644edbaa3f3685ae978376ec3b42aac26de 100644 (file)
@@ -114,7 +114,7 @@ fn mk_temp_workspace(short_name: &Path, version: &Version) -> Path {
 fn run_git(args: &[~str], env: Option<~[(~str, ~str)]>, cwd: &Path, err_msg: &str) {
     let cwd = (*cwd).clone();
     let mut prog = run::Process::new("git", args, run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&cwd),
         in_fd: None,
         out_fd: None,
@@ -222,7 +222,7 @@ fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~s
     assert!(os::path_is_dir(&*cwd));
     let cwd = (*cwd).clone();
     let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&cwd),
         in_fd: None,
         out_fd: None,
@@ -757,7 +757,9 @@ fn rust_path_test() {
                                      // use command_line_test_with_env
     let mut prog = run::Process::new("rustpkg",
                                      [~"install", ~"foo"],
-                                     run::ProcessOptions { env: Some(&[(~"RUST_LOG",
+// This should actually extend the environment; then we can probably
+// un-ignore it
+                                     run::ProcessOptions { env: Some(~[(~"RUST_LOG",
                                                                         ~"rustpkg"),
                                                                        (~"RUST_PATH",
                                                                        dir_for_path.to_str())]),
@@ -1039,7 +1041,7 @@ fn test_extern_mod() {
                                                       ~"--sysroot", test_sysroot().to_str(),
                                                ~"-o", exec_file.to_str()],
                                      run::ProcessOptions {
-        env: env.map(|v| v.slice(0, v.len())),
+        env: env,
         dir: Some(&dir),
         in_fd: None,
         out_fd: None,
index afac9423fba66027da5112787412f681a96f3bb2..82f098b668dc45d1dbd424e6f56816c3496c4427 100644 (file)
@@ -225,7 +225,7 @@ pub fn compile_input(ctxt: &Ctx,
 
     // Infer dependencies that rustpkg needs to build, by scanning for
     // `extern mod` directives.
-    let cfg = driver::build_configuration(sess, binary, &input);
+    let cfg = driver::build_configuration(sess);
     let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
 
@@ -398,8 +398,8 @@ pub fn link_exe(src: &Path, dest: &Path) -> bool {
     use std::libc;
 
     unsafe {
-        do src.to_c_str().with_ref |src_buf| {
-            do dest.to_c_str().with_ref |dest_buf| {
+        do src.with_c_str |src_buf| {
+            do dest.with_c_str |dest_buf| {
                 libc::link(src_buf, dest_buf) == 0 as libc::c_int &&
                     libc::chmod(dest_buf, 755) == 0 as libc::c_int
             }
index c948074990a36824c9c8e9c10b09ff4eeba34cc5..31de7bf82f827adc371193c1431703eae85b6cae 100644 (file)
@@ -308,6 +308,7 @@ pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
 mod test {
     use super::*;
     use prelude::*;
+    use bh = extra::test::BenchHarness;
 
     #[test]
     fn test() {
@@ -347,4 +348,84 @@ fn test_to_managed() {
         assert_eq!(to_managed([@"abc", @"123"]), @[@"abc", @"123"]);
         assert_eq!(to_managed([@[42]]), @[@[42]]);
     }
+
+    #[bench]
+    fn bench_capacity(b: &mut bh) {
+        let x = @[1, 2, 3];
+        do b.iter {
+            capacity(x);
+        }
+    }
+
+    #[bench]
+    fn bench_build_sized(b: &mut bh) {
+        let len = 64;
+        do b.iter {
+            build_sized(len, |push| for i in range(0, 1024) { push(i) });
+        }
+    }
+
+    #[bench]
+    fn bench_build(b: &mut bh) {
+        do b.iter {
+            for i in range(0, 95) {
+                build(|push| push(i));
+            }
+        }
+    }
+
+    #[bench]
+    fn bench_append(b: &mut bh) {
+        let lhs = @[7, ..128];
+        let rhs = range(0, 256).to_owned_vec();
+        do b.iter {
+            append(lhs, rhs);
+        }
+    }
+
+    #[bench]
+    fn bench_map(b: &mut bh) {
+        let elts = range(0, 256).to_owned_vec();
+        do b.iter {
+            map(elts, |x| x*2);
+        }
+    }
+
+    #[bench]
+    fn bench_from_fn(b: &mut bh) {
+        do b.iter {
+            from_fn(1024, |x| x);
+        }
+    }
+
+    #[bench]
+    fn bench_from_elem(b: &mut bh) {
+        do b.iter {
+            from_elem(1024, 0u64);
+        }
+    }
+
+    #[bench]
+    fn bench_to_managed_move(b: &mut bh) {
+        do b.iter {
+            let elts = range(0, 1024).to_owned_vec(); // yikes! can't move out of capture, though
+            to_managed_move(elts);
+        }
+    }
+
+    #[bench]
+    fn bench_to_managed(b: &mut bh) {
+        let elts = range(0, 1024).to_owned_vec();
+        do b.iter {
+            to_managed(elts);
+        }
+    }
+
+    #[bench]
+    fn bench_clone(b: &mut bh) {
+        let elts = to_managed(range(0, 1024).to_owned_vec());
+        do b.iter {
+            elts.clone();
+        }
+    }
 }
index 7e31354366084b061dffef714b178b0263badc03..6fc14439abb24e1a59030c770c5213522677fd23 100644 (file)
@@ -9,14 +9,28 @@
 // except according to those terms.
 
 use cast;
-use iterator::Iterator;
+use iterator::{Iterator,range};
 use libc;
 use ops::Drop;
 use option::{Option, Some, None};
 use ptr::RawPtr;
 use ptr;
 use str::StrSlice;
-use vec::ImmutableVector;
+use vec::{ImmutableVector,CopyableVector};
+use container::Container;
+
+/// Resolution options for the `null_byte` condition
+pub enum NullByteResolution {
+    /// Truncate at the null byte
+    Truncate,
+    /// Use a replacement byte
+    ReplaceWith(libc::c_char)
+}
+
+condition! {
+    // this should be &[u8] but there's a lifetime issue
+    null_byte: (~[u8]) -> super::NullByteResolution;
+}
 
 /// The representation of a C String.
 ///
@@ -34,6 +48,7 @@ pub unsafe fn new(buf: *libc::c_char, owns_buffer: bool) -> CString {
     }
 
     /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
+    /// Any ownership of the buffer by the `CString` wrapper is forgotten.
     pub unsafe fn unwrap(self) -> *libc::c_char {
         let mut c_str = self;
         c_str.owns_buffer_ = false;
@@ -89,7 +104,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     }
 
     /// Return a CString iterator.
-    fn iter<'a>(&'a self) -> CStringIterator<'a> {
+    pub fn iter<'a>(&'a self) -> CStringIterator<'a> {
         CStringIterator {
             ptr: self.buf,
             lifetime: unsafe { cast::transmute(self.buf) },
@@ -109,8 +124,38 @@ fn drop(&self) {
 
 /// A generic trait for converting a value to a CString.
 pub trait ToCStr {
-    /// Create a C String.
+    /// Copy the receiver into a CString.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
     fn to_c_str(&self) -> CString;
+
+    /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
+    unsafe fn to_c_str_unchecked(&self) -> CString;
+
+    /// Work with a temporary CString constructed from the receiver.
+    /// The provided `*libc::c_char` will be freed immediately upon return.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let s = "PATH".with_c_str(|path| libc::getenv(path))
+    /// ~~~
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
+    #[inline]
+    fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str().with_ref(f)
+    }
+
+    /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
+    #[inline]
+    unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str_unchecked().with_ref(f)
+    }
 }
 
 impl<'self> ToCStr for &'self str {
@@ -118,22 +163,43 @@ impl<'self> ToCStr for &'self str {
     fn to_c_str(&self) -> CString {
         self.as_bytes().to_c_str()
     }
+
+    #[inline]
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        self.as_bytes().to_c_str_unchecked()
+    }
 }
 
 impl<'self> ToCStr for &'self [u8] {
     fn to_c_str(&self) -> CString {
-        do self.as_imm_buf |self_buf, self_len| {
-            unsafe {
-                let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
-                if buf.is_null() {
-                    fail!("failed to allocate memory!");
+        let mut cs = unsafe { self.to_c_str_unchecked() };
+        do cs.with_mut_ref |buf| {
+            for i in range(0, self.len()) {
+                unsafe {
+                    let p = buf.offset_inbounds(i as int);
+                    if *p == 0 {
+                        match null_byte::cond.raise(self.to_owned()) {
+                            Truncate => break,
+                            ReplaceWith(c) => *p = c
+                        }
+                    }
                 }
+            }
+        }
+        cs
+    }
 
-                ptr::copy_memory(buf, self_buf, self_len);
-                *ptr::mut_offset(buf, self_len as int) = 0;
-
-                CString::new(buf as *libc::c_char, true)
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        do self.as_imm_buf |self_buf, self_len| {
+            let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
+            if buf.is_null() {
+                fail!("failed to allocate memory!");
             }
+
+            ptr::copy_memory(buf, self_buf, self_len);
+            *ptr::mut_offset(buf, self_len as int) = 0;
+
+            CString::new(buf as *libc::c_char, true)
         }
     }
 }
@@ -230,4 +296,49 @@ fn test_iterator() {
         assert_eq!(iter.next(), Some('o' as libc::c_char));
         assert_eq!(iter.next(), None);
     }
+
+    #[test]
+    #[ignore(cfg(windows))]
+    fn test_to_c_str_fail() {
+        use c_str::null_byte::cond;
+
+        let mut error_happened = false;
+        do cond.trap(|err| {
+            assert_eq!(err, bytes!("he", 0, "llo").to_owned())
+            error_happened = true;
+            Truncate
+        }).inside {
+            "he\x00llo".to_c_str()
+        };
+        assert!(error_happened);
+
+        do cond.trap(|_| {
+            ReplaceWith('?' as libc::c_char)
+        }).inside(|| "he\x00llo".to_c_str()).with_ref |buf| {
+            unsafe {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), '?' as libc::c_char);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
+
+    #[test]
+    fn test_to_c_str_unchecked() {
+        unsafe {
+            do "he\x00llo".to_c_str_unchecked().with_ref |buf| {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), 0);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
 }
index 9c55e22b1f833794a0cd70548de8140c757021d8..a0635f6f12eb29767b1f1faa901dc67dcbfea546 100644 (file)
 #[cfg(not(test))] use cmp::{Eq, Ord};
 #[cfg(not(test))] use num::Zero;
 
+// UTF-8 ranges and tags for encoding characters
+static TAG_CONT: uint = 128u;
+static MAX_ONE_B: uint = 128u;
+static TAG_TWO_B: uint = 192u;
+static MAX_TWO_B: uint = 2048u;
+static TAG_THREE_B: uint = 224u;
+static MAX_THREE_B: uint = 65536u;
+static TAG_FOUR_B: uint = 240u;
+
 /*
     Lu  Uppercase_Letter        an uppercase letter
     Ll  Lowercase_Letter        a lowercase letter
@@ -278,6 +287,12 @@ pub trait Char {
     fn escape_unicode(&self, f: &fn(char));
     fn escape_default(&self, f: &fn(char));
     fn len_utf8_bytes(&self) -> uint;
+
+    /// Encodes this character as utf-8 into the provided byte-buffer. The
+    /// buffer must be at least 4 bytes long or a runtime failure will occur.
+    ///
+    /// This will then return the number of characters written to the slice.
+    fn encode_utf8(&self, dst: &mut [u8]) -> uint;
 }
 
 impl Char for char {
@@ -308,6 +323,29 @@ fn escape_unicode(&self, f: &fn(char)) { escape_unicode(*self, f) }
     fn escape_default(&self, f: &fn(char)) { escape_default(*self, f) }
 
     fn len_utf8_bytes(&self) -> uint { len_utf8_bytes(*self) }
+
+    fn encode_utf8<'a>(&self, dst: &'a mut [u8]) -> uint {
+        let code = *self as uint;
+        if code < MAX_ONE_B {
+            dst[0] = code as u8;
+            return 1;
+        } else if code < MAX_TWO_B {
+            dst[0] = (code >> 6u & 31u | TAG_TWO_B) as u8;
+            dst[1] = (code & 63u | TAG_CONT) as u8;
+            return 2;
+        } else if code < MAX_THREE_B {
+            dst[0] = (code >> 12u & 15u | TAG_THREE_B) as u8;
+            dst[1] = (code >> 6u & 63u | TAG_CONT) as u8;
+            dst[2] = (code & 63u | TAG_CONT) as u8;
+            return 3;
+        } else {
+            dst[0] = (code >> 18u & 7u | TAG_FOUR_B) as u8;
+            dst[1] = (code >> 12u & 63u | TAG_CONT) as u8;
+            dst[2] = (code >> 6u & 63u | TAG_CONT) as u8;
+            dst[3] = (code & 63u | TAG_CONT) as u8;
+            return 4;
+        }
+    }
 }
 
 #[cfg(not(test))]
index 132ebc72960117763498599345c2f41b9d632efe..5d988965e8cccc9ce61eb583530b63225b58caae 100644 (file)
@@ -16,7 +16,7 @@
 use clone::Clone;
 use container::Container;
 use cmp::Eq;
-use iterator::Iterator;
+use iterator::{Iterator, FilterMap};
 use result::Result;
 use result;
 use str::StrSlice;
@@ -116,40 +116,44 @@ pub fn unwrap_right(self) -> R {
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the left values
-pub fn lefts<L: Clone, R>(eithers: &[Either<L, R>]) -> ~[L] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Left(ref l) => { push((*l).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// An iterator yielding the `Left` values of its source
+pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
+
+/// An iterator yielding the `Right` values of its source
+pub type Rights<L, R, Iter> = FilterMap<'static, Either<L, R>, R, Iter>;
+
+/// Extracts all the left values
+pub fn lefts<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Lefts<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Left(x) => Some(x),
+            _ => None,
         }
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Extracts from a vector of either all the right values
-pub fn rights<L, R: Clone>(eithers: &[Either<L, R>]) -> ~[R] {
-    do vec::build_sized(eithers.len()) |push| {
-        for elt in eithers.iter() {
-            match *elt {
-                Right(ref r) => { push((*r).clone()); }
-                _ => { /* fallthrough */ }
-            }
+/// Extracts all the right values
+pub fn rights<L, R, Iter: Iterator<Either<L, R>>>(eithers: Iter)
+    -> Rights<L, R, Iter> {
+    do eithers.filter_map |elt| {
+        match elt {
+            Right(x) => Some(x),
+            _ => None,
         }
     }
 }
 
+
 // FIXME: #8228 Replaceable by an external iterator?
 /// Extracts from a vector of either all the left values and right values
 ///
 /// Returns a structure containing a vector of left values and a vector of
 /// right values.
 pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
-    let mut lefts: ~[L] = ~[];
-    let mut rights: ~[R] = ~[];
+    let n_lefts = eithers.iter().count(|elt| elt.is_left());
+    let mut lefts = vec::with_capacity(n_lefts);
+    let mut rights = vec::with_capacity(eithers.len() - n_lefts);
     for elt in eithers.move_iter() {
         match elt {
             Left(l) => lefts.push(l),
@@ -182,42 +186,42 @@ fn f_right(x: &uint) -> bool { *x == 10u }
     #[test]
     fn test_lefts() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[10, 12, 14]);
     }
 
     #[test]
     fn test_lefts_none() {
         let input: ~[Either<int, int>] = ~[Right(10), Right(10)];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_lefts_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = lefts(input);
+        let result = lefts(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights() {
         let input = ~[Left(10), Right(11), Left(12), Right(13), Left(14)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result, ~[11, 13]);
     }
 
     #[test]
     fn test_rights_none() {
         let input: ~[Either<int, int>] = ~[Left(10), Left(10)];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
     #[test]
     fn test_rights_empty() {
         let input: ~[Either<int, int>] = ~[];
-        let result = rights(input);
+        let result = rights(input.move_iter()).to_owned_vec();
         assert_eq!(result.len(), 0u);
     }
 
index 2b8807b2291724a0d6f3da92671bd8622a2382f3..70ec5d931998430fa865ec6c7dc39869c1e6c4c5 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/**!
+
+# The Formatting Module
+
+This module contains the runtime support for the `ifmt!` syntax extension. This
+macro is implemented in the compiler to emit calls to this module in order to
+format arguments at runtime into strings and streams.
+
+The functions contained in this module should not normally be used in everyday
+use cases of `ifmt!`. The assumptions made by these functions are unsafe for all
+inputs, and the compiler performs a large amount of validation on the arguments
+to `ifmt!` in order to ensure safety at runtime. While it is possible to call
+these functions directly, it is not recommended to do so in the general case.
+
+## Usage
+
+The `ifmt!` macro is intended to be familiar to those coming from C's
+printf/sprintf functions or Python's `str.format` function. In its current
+revision, the `ifmt!` macro returns a `~str` type which is the result of the
+formatting. In the future it will also be able to pass in a stream to format
+arguments directly while performing minimal allocations.
+
+Some examples of the `ifmt!` extension are:
+
+~~~{.rust}
+ifmt!("Hello")                  // => ~"Hello"
+ifmt!("Hello, {:s}!", "world")  // => ~"Hello, world!"
+ifmt!("The number is {:d}", 1)  // => ~"The number is 1"
+ifmt!("{}", ~[3, 4])            // => ~"~[3, 4]"
+ifmt!("{value}", value=4)       // => ~"4"
+ifmt!("{} {}", 1, 2)            // => ~"1 2"
+~~~
+
+From these, you can see that the first argument is a format string. It is
+required by the compiler for this to be a string literal; it cannot be a
+variable passed in (in order to perform validity checking). The compiler will
+then parse the format string and determine if the list of arguments provided is
+suitable to pass to this format string.
+
+### Positional parameters
+
+Each formatting argument is allowed to specify which value argument it's
+referencing, and if omitted it is assumed to be "the next argument". For
+example, the format string `{} {} {}` would take three parameters, and they
+would be formatted in the same order as they're given. The format string
+`{2} {1} {0}`, however, would format arguments in reverse order.
+
+A format string is required to use all of its arguments, otherwise it is a
+compile-time error. You may refer to the same argument more than once in the
+format string, although it must always be referred to with the same type.
+
+### Named parameters
+
+Rust itself does not have a Python-like equivalent of named parameters to a
+function, but the `ifmt!` macro is a syntax extension which allows it to
+leverage named parameters. Named parameters are listed at the end of the
+argument list and have the syntax:
+
+~~~
+identifier '=' expression
+~~~
+
+It is illegal to put positional parameters (those without names) after arguments
+which have names. Like positional parameters, it is illegal to provided named
+parameters that are unused by the format string.
+
+### Argument types
+
+Each argument's type is dictated by the format string. It is a requirement that
+every argument is only ever referred to by one type. When specifying the format
+of an argument, however, a string like `{}` indicates no type. This is allowed,
+and if all references to one argument do not provide a type, then the format `?`
+is used (the type's rust-representation is printed). For example, this is an
+invalid format string:
+
+~~~
+{0:d} {0:s}
+~~~
+
+Because the first argument is both referred to as an integer as well as a
+string.
+
+Because formatting is done via traits, there is no requirement that the
+`d` format actually takes an `int`, but rather it simply requires a type which
+ascribes to the `Signed` formatting trait. There are various parameters which do
+require a particular type, however. Namely if the syntax `{:.*s}` is used, then
+the number of characters to print from the string precedes the actual string and
+must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
+illegal to reference an argument as such. For example, this is another invalid
+format string:
+
+~~~
+{:.*s} {0:u}
+~~~
+
+### Formatting traits
+
+When requesting that an argument be formatted with a particular type, you are
+actually requesting that an argument ascribes to a particular trait. This allows
+multiple actual types to be formatted via `{:d}` (like `i8` as well as `int`).
+The current mapping of types to traits is:
+
+* `?` => Poly
+* `d` => Signed
+* `i` => Signed
+* `u` => Unsigned
+* `b` => Bool
+* `c` => Char
+* `o` => Octal
+* `x` => LowerHex
+* `X` => UpperHex
+* `s` => String
+* `p` => Pointer
+* `t` => Binary
+* `f` => Float
+
+What this means is that any type of argument which implements the
+`std::fmt::Binary` trait can then be formatted with `{:t}`. Implementations are
+provided for these traits for a number of primitive types by the standard
+library as well. Again, the default formatting type (if no other is specified)
+is `?` which is defined for all types by default.
+
+When implementing a format trait for your own time, you will have to implement a
+method of the signature:
+
+~~~
+fn fmt(value: &T, f: &mut std::fmt::Formatter);
+~~~
+
+Your type will be passed by-reference in `value`, and then the function should
+emit output into the `f.buf` stream. It is up to each format trait
+implementation to correctly adhere to the requested formatting parameters. The
+values of these parameters will be listed in the fields of the `Formatter`
+struct. In order to help with this, the `Formatter` struct also provides some
+helper methods.
+
+## Internationalization
+
+The formatting syntax supported by the `ifmt!` extension supports
+internationalization by providing "methods" which execute various differnet
+outputs depending on the input. The syntax and methods provided are similar to
+other internationalization systems, so again nothing should seem alien.
+Currently two methods are supported by this extension: "select" and "plural".
+
+Each method will execute one of a number of clauses, and then the value of the
+clause will become what's the result of the argument's format. Inside of the
+cases, nested argument strings may be provided, but all formatting arguments
+must not be done through implicit positional means. All arguments inside of each
+case of a method must be explicitly selected by their name or their integer
+position.
+
+Furthermore, whenever a case is running, the special character `#` can be used
+to reference the string value of the argument which was selected upon. As an
+example:
+
+~~~
+ifmt!("{0, select, other{#}}", "hello") // => ~"hello"
+~~~
+
+This example is the equivalent of `{0:s}` essentially.
+
+### Select
+
+The select method is a switch over a `&str` parameter, and the parameter *must*
+be of the type `&str`. An example of the syntax is:
+
+~~~
+{0, select, male{...} female{...} other{...}}
+~~~
+
+Breaking this down, the `0`-th argument is selected upon with the `select`
+method, and then a number of cases follow. Each case is preceded by an
+identifier which is the match-clause to execute the given arm. In this case,
+there are two explicit cases, `male` and `female`. The case will be executed if
+the string argument provided is an exact match to the case selected.
+
+The `other` case is also a required case for all `select` methods. This arm will
+be executed if none of the other arms matched the word being selected over.
+
+### Plural
+
+The plural method is a switch statement over a `uint` parameter, and the
+parameter *must* be a `uint`. A plural method in its full glory can be specified
+as:
+
+~~~
+{0, plural, offset=1 =1{...} two{...} many{...} other{...}}
+~~~
+
+To break this down, the first `0` indicates that this method is selecting over
+the value of the first positional parameter to the format string. Next, the
+`plural` method is being executed. An optionally-supplied `offset` is then given
+which indicates a number to subtract from argument `0` when matching. This is
+then followed by a list of cases.
+
+Each case is allowed to supply a specific value to match upon with the syntax
+`=N`. This case is executed if the value at argument `0` matches N exactly,
+without taking the offset into account. A case may also be specified by one of
+five keywords: `zero`, `one`, `two`, `few`, and `many`. These cases are matched
+on after argument `0` has the offset taken into account. Currently the
+definitions of `many` and `few` are hardcoded, but they are in theory defined by
+the current locale.
+
+Finally, all `plural` methods must have an `other` case supplied which will be
+executed if none of the other cases match.
+
+## Syntax
+
+The syntax for the formatting language used is drawn from other languages, so it
+should not be too alien. Arguments are formatted with python-like syntax,
+meaning that arguments are surrounded by `{}` instead of the C-like `%`. The
+actual grammar for the formatting syntax is:
+
+~~~
+format_string := <text> [ format <text> ] *
+format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}'
+argument := integer | identifier
+
+format_spec := [[fill]align][sign]['#'][0][width]['.' precision][type]
+fill := character
+align := '<' | '>'
+sign := '+' | '-'
+width := count
+precision := count | '*'
+type := identifier | ''
+count := parameter | integer
+parameter := integer '$'
+
+function_spec := plural | select
+select := 'select' ',' ( identifier arm ) *
+plural := 'plural' ',' [ 'offset:' integer ] ( selector arm ) *
+selector := '=' integer | keyword
+keyword := 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'
+arm := '{' format_string '}'
+~~~
+
+## Formatting Parameters
+
+Each argument being formatted can be transformed by a number of formatting
+parameters (corresponding to `format_spec` in the syntax above). These
+parameters affect the string representation of what's being formatted. This
+syntax draws heavily from Python's, so it may seem a bit familiar.
+
+### Fill/Alignment
+
+The fill character is provided normally in conjunction with the `width`
+parameter. This indicates that if the value being formatted is smaller than
+`width` some extra characters will be printed around it. The extra characters
+are specified by `fill`, and the alignment can be one of two options:
+
+* `<` - the argument is left-aligned in `width` columns
+* `>` - the argument is right-aligned in `width` columns
+
+### Sign/#/0
+
+These can all be interpreted as flags for a particular formatter.
+
+* '+' - This is intended for numeric types and indicates that the sign should
+        always be printed. Positive signs are never printed by default, and the
+        negative sign is only printed by default for the `Signed` trait. This
+        flag indicates that the correct sign (+ or -) should always be printed.
+* '-' - Currently not used
+* '#' - This flag is indicates that the "alternate" form of printing should be
+        used. By default, this only applies to the integer formatting traits and
+        performs like:
+    * `x` - precedes the argument with a "0x"
+    * `X` - precedes the argument with a "0x"
+    * `t` - precedes the argument with a "0b"
+    * `o` - precedes the argument with a "0o"
+* '0' - This is used to indicate for integer formats that the padding should
+        both be done with a `0` character as well as be sign-aware. A format
+        like `{:08d}` would yield `00000001` for the integer `1`, while the same
+        format would yield `-0000001` for the integer `-1`. Notice that the
+        negative version has one fewer zero than the positive version.
+
+### Width
+
+This is a parameter for the "minimum width" that the format should take up. If
+the value's string does not fill up this many characters, then the padding
+specified by fill/alignment will be used to take up the required space.
+
+The default fill/alignment for non-numerics is a space and left-aligned. The
+defaults for numeric formatters is also a space but with right-alignment. If the
+'0' flag is specified for numerics, then the implicit fill character is '0'.
+
+The value for the width can also be provided as a `uint` in the list of
+parameters by using the `2$` syntax indicating that the second argument is a
+`uint` specifying the width.
+
+### Precision
+
+For non-numeric types, this can be considered a "maximum width". If the
+resulting string is longer than this width, then it is truncated down to this
+many characters and only those are emitted.
+
+For integral types, this has no meaning currently.
+
+For floating-point types, this indicates how many digits after the decimal point
+should be printed.
+
+*/
+
 use prelude::*;
 
 use cast;
-use int;
+use char::Char;
 use rt::io::Decorator;
 use rt::io::mem::MemWriter;
 use rt::io;
 use str;
 use sys;
-use uint;
 use util;
 use vec;
 
@@ -33,7 +334,7 @@ pub struct Formatter<'self> {
     /// Character used as 'fill' whenever there is alignment
     fill: char,
     /// Boolean indication of whether the output should be left-aligned
-    alignleft: bool,
+    align: parse::Alignment,
     /// Optionally specified integer width that the output should be
     width: Option<uint>,
     /// Optionally specified precision for numeric types
@@ -77,6 +378,8 @@ pub struct Argument<'self> {
 pub trait Poly { fn fmt(&Self, &mut Formatter); }
 #[allow(missing_doc)]
 pub trait Pointer { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Float { fn fmt(&Self, &mut Formatter); }
 
 /// The sprintf function takes a precompiled format string and a list of
 /// arguments, to return the resulting formatted string.
@@ -109,7 +412,7 @@ pub unsafe fn sprintf(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
             precision: None,
             // FIXME(#8248): shouldn't need a transmute
             buf: cast::transmute(&output as &io::Writer),
-            alignleft: false,
+            align: parse::AlignUnknown,
             fill: ' ',
             args: args,
             curarg: args.iter(),
@@ -122,6 +425,11 @@ pub unsafe fn sprintf(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
 }
 
 impl<'self> Formatter<'self> {
+
+    // First up is the collection of functions used to execute a format string
+    // at runtime. This consumes all of the compile-time statics generated by
+    // the ifmt! syntax extension.
+
     fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
         let setcount = |slot: &mut Option<uint>, cnt: &parse::Count| {
             match *cnt {
@@ -144,7 +452,7 @@ fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
             rt::Argument(ref arg) => {
                 // Fill in the format parameters into the formatter
                 self.fill = arg.format.fill;
-                self.alignleft = arg.format.alignleft;
+                self.align = arg.format.align;
                 self.flags = arg.format.flags;
                 setcount(&mut self.width, &arg.format.width);
                 setcount(&mut self.precision, &arg.format.precision);
@@ -233,13 +541,154 @@ fn execute(&mut self, method: &rt::Method, arg: Argument) {
     }
 
     fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
-        do uint::to_str_bytes(value, 10) |buf| {
+        do ::uint::to_str_bytes(value, 10) |buf| {
             let valuestr = str::from_bytes_slice(buf);
             for piece in pieces.iter() {
                 self.run(piece, Some(valuestr));
             }
         }
     }
+
+    // Helper methods used for padding and processing formatting arguments that
+    // all formatting traits can use.
+
+    /// Performs the correct padding for an integer which has already been
+    /// emitted into a byte-array. The byte-array should *not* contain the sign
+    /// for the integer, that will be added by this method.
+    ///
+    /// # Arguments
+    ///
+    ///     * s - the byte array that the number has been formatted into
+    ///     * alternate_prefix - if the '#' character (FlagAlternate) is
+    ///       provided, this is the prefix to put in front of the number.
+    ///       Currently this is 0x/0o/0b/etc.
+    ///     * positive - whether the original integer was positive or not.
+    ///
+    /// This function will correctly account for the flags provided as well as
+    /// the minimum width. It will not take precision into account.
+    pub fn pad_integral(&mut self, s: &[u8], alternate_prefix: &str,
+                        positive: bool) {
+        use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
+
+        let mut actual_len = s.len();
+        if self.flags & 1 << (FlagAlternate as uint) != 0 {
+            actual_len += alternate_prefix.len();
+        }
+        if self.flags & 1 << (FlagSignPlus as uint) != 0 {
+            actual_len += 1;
+        } else if !positive {
+            actual_len += 1;
+        }
+
+        let mut signprinted = false;
+        let sign = |this: &mut Formatter| {
+            if !signprinted {
+                if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive {
+                    this.buf.write(['+' as u8]);
+                } else if !positive {
+                    this.buf.write(['-' as u8]);
+                }
+                if this.flags & 1 << (FlagAlternate as uint) != 0 {
+                    this.buf.write(alternate_prefix.as_bytes());
+                }
+                signprinted = true;
+            }
+        };
+
+        let emit = |this: &mut Formatter| {
+            sign(this);
+            this.buf.write(s);
+        };
+
+        match self.width {
+            None => { emit(self) }
+            Some(min) if actual_len >= min => { emit(self) }
+            Some(min) => {
+                if self.flags & 1 << (FlagSignAwareZeroPad as uint) != 0 {
+                    self.fill = '0';
+                    sign(self);
+                }
+                do self.with_padding(min - actual_len, parse::AlignRight) |me| {
+                    emit(me);
+                }
+            }
+        }
+    }
+
+    /// This function takes a string slice and emits it to the internal buffer
+    /// after applying the relevant formatting flags specified. The flags
+    /// recognized for generic strings are:
+    ///
+    /// * width - the minimum width of what to emit
+    /// * fill/align - what to emit and where to emit it if the string
+    ///                provided needs to be padded
+    /// * precision - the maximum length to emit, the string is truncated if it
+    ///               is longer than this length
+    ///
+    /// Notably this function ignored the `flag` parameters
+    pub fn pad(&mut self, s: &str) {
+        // Make sure there's a fast path up front
+        if self.width.is_none() && self.precision.is_none() {
+            self.buf.write(s.as_bytes());
+            return
+        }
+        // The `precision` field can be interpreted as a `max-width` for the
+        // string being formatted
+        match self.precision {
+            Some(max) => {
+                // If there's a maximum width and our string is longer than
+                // that, then we must always have truncation. This is the only
+                // case where the maximum length will matter.
+                let char_len = s.char_len();
+                if char_len >= max {
+                    let nchars = ::uint::min(max, char_len);
+                    self.buf.write(s.slice_chars(0, nchars).as_bytes());
+                    return
+                }
+            }
+            None => {}
+        }
+
+        // The `width` field is more of a `min-width` parameter at this point.
+        match self.width {
+            // If we're under the maximum length, and there's no minimum length
+            // requirements, then we can just emit the string
+            None => { self.buf.write(s.as_bytes()) }
+
+            // If we're under the maximum width, check if we're over the minimum
+            // width, if so it's as easy as just emitting the string.
+            Some(width) if s.char_len() >= width => {
+                self.buf.write(s.as_bytes())
+            }
+
+            // If we're under both the maximum and the minimum width, then fill
+            // up the minimum width with the specified string + some alignment.
+            Some(width) => {
+                do self.with_padding(width - s.len(), parse::AlignLeft) |me| {
+                    me.buf.write(s.as_bytes());
+                }
+            }
+        }
+    }
+
+    fn with_padding(&mut self, padding: uint,
+                    default: parse::Alignment, f: &fn(&mut Formatter)) {
+        let align = match self.align {
+            parse::AlignUnknown => default,
+            parse::AlignLeft | parse::AlignRight => self.align
+        };
+        if align == parse::AlignLeft {
+            f(self);
+        }
+        let mut fill = [0u8, ..4];
+        let len = self.fill.encode_utf8(fill);
+        for _ in range(0, padding) {
+            self.buf.write(fill.slice_to(len));
+        }
+        if align == parse::AlignRight {
+            f(self);
+        }
+    }
 }
 
 /// This is a function which calls are emitted to by the compiler itself to
@@ -279,78 +728,119 @@ fn fmt(b: &bool, f: &mut Formatter) {
 
 impl<'self> String for &'self str {
     fn fmt(s: & &'self str, f: &mut Formatter) {
-        // XXX: formatting args
-        f.buf.write(s.as_bytes())
+        f.pad(*s);
     }
 }
 
 impl Char for char {
     fn fmt(c: &char, f: &mut Formatter) {
-        // XXX: formatting args
-        // XXX: shouldn't require an allocation
-        let mut s = ~"";
-        s.push_char(*c);
-        f.buf.write(s.as_bytes());
+        let mut utf8 = [0u8, ..4];
+        let amt = c.encode_utf8(utf8);
+        let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) };
+        String::fmt(&s, f);
     }
 }
 
-impl Signed for int {
-    fn fmt(c: &int, f: &mut Formatter) {
-        // XXX: formatting args
-        do int::to_str_bytes(*c, 10) |buf| {
-            f.buf.write(buf);
+macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
+                       $name:ident, $prefix:expr) => {
+    impl $name for $ty {
+        fn fmt(c: &$ty, f: &mut Formatter) {
+            do ::$into::to_str_bytes(*c as $into, $base) |buf| {
+                f.pad_integral(buf, $prefix, true);
+            }
         }
     }
-}
-
-impl Unsigned for uint {
-    fn fmt(c: &uint, f: &mut Formatter) {
-        // XXX: formatting args
-        do uint::to_str_bytes(*c, 10) |buf| {
-            f.buf.write(buf);
+})
+macro_rules! upper_hex(($ty:ident, $into:ident) => {
+    impl UpperHex for $ty {
+        fn fmt(c: &$ty, f: &mut Formatter) {
+            do ::$into::to_str_bytes(*c as $into, 16) |buf| {
+                upperhex(buf, f);
+            }
         }
     }
-}
-
-impl Octal for uint {
-    fn fmt(c: &uint, f: &mut Formatter) {
-        // XXX: formatting args
-        do uint::to_str_bytes(*c, 8) |buf| {
-            f.buf.write(buf);
+})
+// Not sure why, but this causes an "unresolved enum variant, struct or const"
+// when inlined into the above macro...
+#[doc(hidden)]
+pub fn upperhex(buf: &[u8], f: &mut Formatter) {
+    let mut local = [0u8, ..16];
+    for i in ::iterator::range(0, buf.len()) {
+        local[i] = match buf[i] as char {
+            'a' .. 'f' => (buf[i] - 'a' as u8) + 'A' as u8,
+            c => c as u8,
         }
     }
+    f.pad_integral(local.slice_to(buf.len()), "0x", true);
 }
 
-impl LowerHex for uint {
-    fn fmt(c: &uint, f: &mut Formatter) {
-        // XXX: formatting args
-        do uint::to_str_bytes(*c, 16) |buf| {
-            f.buf.write(buf);
+// FIXME(#4375) shouldn't need an inner module
+macro_rules! integer(($signed:ident, $unsigned:ident) => {
+    mod $signed {
+        use super::*;
+
+        // Signed is special because it actuall emits the negative sign,
+        // nothing else should do that, however.
+        impl Signed for $signed {
+            fn fmt(c: &$signed, f: &mut Formatter) {
+                do ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10) |buf| {
+                    f.pad_integral(buf, "", *c >= 0);
+                }
+            }
         }
+        int_base!($signed, $unsigned, 2, Binary, "0b")
+        int_base!($signed, $unsigned, 8, Octal, "0o")
+        int_base!($signed, $unsigned, 16, LowerHex, "0x")
+        upper_hex!($signed, $unsigned)
+
+        int_base!($unsigned, $unsigned, 2, Binary, "0b")
+        int_base!($unsigned, $unsigned, 8, Octal, "0o")
+        int_base!($unsigned, $unsigned, 10, Unsigned, "")
+        int_base!($unsigned, $unsigned, 16, LowerHex, "0x")
+        upper_hex!($unsigned, $unsigned)
     }
-}
-
-impl UpperHex for uint {
-    fn fmt(c: &uint, f: &mut Formatter) {
-        // XXX: formatting args
-        do uint::to_str_bytes(*c, 16) |buf| {
-            let mut local = [0u8, ..16];
-            for (l, &b) in local.mut_iter().zip(buf.iter()) {
-                *l = match b as char {
-                    'a' .. 'f' => (b - 'a' as u8) + 'A' as u8,
-                    _ => b,
-                };
-            }
-            f.buf.write(local.slice_to(buf.len()));
+})
+
+integer!(int, uint)
+integer!(i8, u8)
+integer!(i16, u16)
+integer!(i32, u32)
+integer!(i64, u64)
+
+macro_rules! floating(($ty:ident) => {
+    impl Float for $ty {
+        fn fmt(f: &$ty, fmt: &mut Formatter) {
+            // XXX: this shouldn't perform an allocation
+            let s = match fmt.precision {
+                Some(i) => ::$ty::to_str_exact(f.abs(), i),
+                None => ::$ty::to_str_digits(f.abs(), 6)
+            };
+            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
         }
     }
-}
+})
+floating!(float)
+floating!(f32)
+floating!(f64)
 
 impl<T> Poly for T {
     fn fmt(t: &T, f: &mut Formatter) {
-        // XXX: formatting args
-        let s = sys::log_str(t);
-        f.buf.write(s.as_bytes());
+        match (f.width, f.precision) {
+            (None, None) => {
+                // XXX: sys::log_str should have a variant which takes a stream
+                //      and we should directly call that (avoids unnecessary
+                //      allocations)
+                let s = sys::log_str(t);
+                f.buf.write(s.as_bytes());
+            }
+
+            // If we have a specified width for formatting, then we have to make
+            // this allocation of a new string
+            _ => {
+                let s = sys::log_str(t);
+                f.pad(s);
+            }
+        }
     }
 }
 
@@ -358,9 +848,10 @@ fn fmt(t: &T, f: &mut Formatter) {
 //      time.
 impl<T> Pointer for *const T {
     fn fmt(t: &*const T, f: &mut Formatter) {
-        // XXX: formatting args
-        f.buf.write("0x".as_bytes());
-        LowerHex::fmt(&(*t as uint), f);
+        f.flags |= 1 << (parse::FlagAlternate as uint);
+        do ::uint::to_str_bytes(*t as uint, 16) |buf| {
+            f.pad_integral(buf, "0x", true);
+        }
     }
 }
 
index 673ea1d3fa8b586c883708503287dec3a9affd62..0d39ae84a6057432a2887fee8a6ae4961ea52973 100644 (file)
@@ -47,7 +47,7 @@ pub struct FormatSpec<'self> {
     /// Optionally specified character to fill alignment with
     fill: Option<char>,
     /// Optionally specified alignment
-    align: Option<Alignment>,
+    align: Alignment,
     /// Packed version of various flags provided
     flags: uint,
     /// The integer precision to use
@@ -68,7 +68,7 @@ pub enum Position<'self> {
 
 /// Enum of alignments which are supoprted.
 #[deriving(Eq)]
-pub enum Alignment { AlignLeft, AlignRight }
+pub enum Alignment { AlignLeft, AlignRight, AlignUnknown }
 
 /// Various flags which can be applied to format strings, the meaning of these
 /// flags is defined by the formatters themselves.
@@ -77,6 +77,7 @@ pub enum Flag {
     FlagSignPlus,
     FlagSignMinus,
     FlagAlternate,
+    FlagSignAwareZeroPad,
 }
 
 /// A count is used for the precision and width parameters of an integer, and
@@ -288,7 +289,7 @@ fn position(&mut self) -> Position<'self> {
     fn format(&mut self) -> FormatSpec<'self> {
         let mut spec = FormatSpec {
             fill: None,
-            align: None,
+            align: AlignUnknown,
             flags: 0,
             precision: CountImplied,
             width: CountImplied,
@@ -311,9 +312,9 @@ fn format(&mut self) -> FormatSpec<'self> {
         }
         // Alignment
         if self.consume('<') {
-            spec.align = Some(AlignLeft);
+            spec.align = AlignLeft;
         } else if self.consume('>') {
-            spec.align = Some(AlignRight);
+            spec.align = AlignRight;
         }
         // Sign flags
         if self.consume('+') {
@@ -326,6 +327,9 @@ fn format(&mut self) -> FormatSpec<'self> {
             spec.flags |= 1 << (FlagAlternate as uint);
         }
         // Width and precision
+        if self.consume('0') {
+            spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
+        }
         spec.width = self.count();
         if self.consume('.') {
             if self.consume('*') {
@@ -597,7 +601,7 @@ fn same(fmt: &'static str, p: ~[Piece<'static>]) {
     fn fmtdflt() -> FormatSpec<'static> {
         return FormatSpec {
             fill: None,
-            align: None,
+            align: AlignUnknown,
             flags: 0,
             precision: CountImplied,
             width: CountImplied,
@@ -656,7 +660,7 @@ fn format_type() {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountImplied,
                 width: CountImplied,
@@ -671,7 +675,7 @@ fn format_align_fill() {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
-                align: Some(AlignRight),
+                align: AlignRight,
                 flags: 0,
                 precision: CountImplied,
                 width: CountImplied,
@@ -683,7 +687,7 @@ fn format_align_fill() {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: Some('0'),
-                align: Some(AlignLeft),
+                align: AlignLeft,
                 flags: 0,
                 precision: CountImplied,
                 width: CountImplied,
@@ -695,7 +699,7 @@ fn format_align_fill() {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: Some('*'),
-                align: Some(AlignLeft),
+                align: AlignLeft,
                 flags: 0,
                 precision: CountImplied,
                 width: CountImplied,
@@ -710,7 +714,7 @@ fn format_counts() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountImplied,
                 width: CountIs(10),
@@ -722,7 +726,7 @@ fn format_counts() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountIs(10),
                 width: CountIsParam(10),
@@ -734,7 +738,7 @@ fn format_counts() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountIsNextParam,
                 width: CountImplied,
@@ -746,7 +750,7 @@ fn format_counts() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountIsParam(10),
                 width: CountImplied,
@@ -761,7 +765,7 @@ fn format_flags() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: (1 << FlagSignMinus as uint),
                 precision: CountImplied,
                 width: CountImplied,
@@ -773,7 +777,7 @@ fn format_flags() {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
                 precision: CountImplied,
                 width: CountImplied,
@@ -788,7 +792,7 @@ fn format_mixture() {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
-                align: None,
+                align: AlignUnknown,
                 flags: 0,
                 precision: CountImplied,
                 width: CountImplied,
index 6feb1d7a848038fb1ca1bc257e1b87ad3cf045f8..90763836fc6b6ef03f807949ac08c8f4c9ac365f 100644 (file)
@@ -36,7 +36,7 @@ pub struct Argument<'self> {
 
 pub struct FormatSpec {
     fill: char,
-    alignleft: bool,
+    align: parse::Alignment,
     flags: uint,
     precision: parse::Count,
     width: parse::Count,
index 7a22477685911cf9ee0a52afdc9f882b1ce3f49d..50e59cf438d0c21b46446664d40998497fd9f66d 100644 (file)
@@ -605,8 +605,8 @@ fn next(&mut self) -> Option<K> {
     }
 }
 
-impl<K: Eq + Hash, V, T: Iterator<(K, V)>> FromIterator<(K, V), T> for HashMap<K, V> {
-    fn from_iterator(iter: &mut T) -> HashMap<K, V> {
+impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
+    fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V> {
         let (lower, _) = iter.size_hint();
         let mut map = HashMap::with_capacity(lower);
         map.extend(iter);
@@ -614,8 +614,8 @@ fn from_iterator(iter: &mut T) -> HashMap<K, V> {
     }
 }
 
-impl<K: Eq + Hash, V, T: Iterator<(K, V)>> Extendable<(K, V), T> for HashMap<K, V> {
-    fn extend(&mut self, iter: &mut T) {
+impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
+    fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
@@ -745,8 +745,16 @@ pub fn union_iter<'a>(&'a self, other: &'a HashSet<T>)
 
 }
 
-impl<K: Eq + Hash, T: Iterator<K>> FromIterator<K, T> for HashSet<K> {
-    fn from_iterator(iter: &mut T) -> HashSet<K> {
+impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
+    fn clone(&self) -> HashSet<T> {
+        HashSet {
+            map: self.map.clone()
+        }
+    }
+}
+
+impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
+    fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
         let (lower, _) = iter.size_hint();
         let mut set = HashSet::with_capacity(lower);
         set.extend(iter);
@@ -754,8 +762,8 @@ fn from_iterator(iter: &mut T) -> HashSet<K> {
     }
 }
 
-impl<K: Eq + Hash, T: Iterator<K>> Extendable<K, T> for HashSet<K> {
-    fn extend(&mut self, iter: &mut T) {
+impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
+    fn extend<T: Iterator<K>>(&mut self, iter: &mut T) {
         for k in *iter {
             self.insert(k);
         }
@@ -1190,4 +1198,22 @@ fn test_move_iter() {
         let v = hs.move_iter().collect::<~[char]>();
         assert!(['a', 'b'] == v || ['b', 'a'] == v);
     }
+
+    #[test]
+    fn test_eq() {
+        let mut s1 = HashSet::new();
+        s1.insert(1);
+        s1.insert(2);
+        s1.insert(3);
+
+        let mut s2 = HashSet::new();
+        s2.insert(1);
+        s2.insert(2);
+
+        assert!(s1 != s2);
+
+        s2.insert(3);
+
+        assert_eq!(s1, s2);
+    }
 }
index 2c18bd272e81785cdc1379d708322cb0f0786918..c9e0c4f862d3a6e2f860c2f1878b51a33b6bb725 100644 (file)
@@ -1041,8 +1041,8 @@ pub fn stdin() -> @Reader {
 }
 
 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
-    let f = do path.to_c_str().with_ref |pathbuf| {
-        do "rb".to_c_str().with_ref |modebuf| {
+    let f = do path.with_c_str |pathbuf| {
+        do "rb".with_c_str |modebuf| {
             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
         }
     };
@@ -1291,7 +1291,7 @@ fn wb() -> c_int { O_WRONLY as c_int }
         }
     }
     let fd = unsafe {
-        do path.to_c_str().with_ref |pathbuf| {
+        do path.with_c_str |pathbuf| {
             libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
         }
     };
@@ -1574,8 +1574,8 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
 // FIXME: fileflags // #2004
 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
     unsafe {
-        let f = do path.to_c_str().with_ref |pathbuf| {
-            do "w".to_c_str().with_ref |modebuf| {
+        let f = do path.with_c_str |pathbuf| {
+            do "w".with_c_str |modebuf| {
                 libc::fopen(pathbuf, modebuf)
             }
         };
index bd89c271a36b0a08d48ea12c4e6511c004e7ec6b..34bbe9292a5cb9ec318e3c50ab9a98a9bc844767 100644 (file)
 use uint;
 
 /// Conversion from an `Iterator`
-pub trait FromIterator<A, T: Iterator<A>> {
+pub trait FromIterator<A> {
     /// Build a container with elements from an external iterator.
-    fn from_iterator(iterator: &mut T) -> Self;
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> Self;
 }
 
 /// A type growable from an `Iterator` implementation
-pub trait Extendable<A, T: Iterator<A>>: FromIterator<A, T> {
+pub trait Extendable<A>: FromIterator<A> {
     /// Extend a container with the elements yielded by an iterator
-    fn extend(&mut self, iterator: &mut T);
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T);
 }
 
 /// An interface for dealing with "external iterators". These types of iterators
@@ -174,6 +174,7 @@ fn enumerate(self) -> Enumerate<Self> {
     /// assert!(it.peek().is_none());
     /// assert!(it.next().is_none());
     /// ~~~
+    #[inline]
     fn peekable(self) -> Peekable<A, Self> {
         Peekable{iter: self, peeked: None}
     }
@@ -353,7 +354,7 @@ fn advance(&mut self, f: &fn(A) -> bool) -> bool {
     /// assert!(a == b);
     /// ~~~
     #[inline]
-    fn collect<B: FromIterator<A, Self>>(&mut self) -> B {
+    fn collect<B: FromIterator<A>>(&mut self) -> B {
         FromIterator::from_iterator(self)
     }
 
@@ -931,8 +932,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
-for Map<'self, A, B, T> {
+impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'self, A, B, T> {
     #[inline]
     fn next_back(&mut self) -> Option<B> {
         let next = self.iter.next_back();
@@ -940,8 +940,7 @@ fn next_back(&mut self) -> Option<B> {
     }
 }
 
-impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B>
-for Map<'self, A, B, T> {
+impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'self, A, B, T> {
     #[inline]
     fn indexable(&self) -> uint {
         self.iter.indexable()
index 6b45ddddf7e9378611f59c1f869078c46a1efb42..6a48e18a3cc2a3340826c9eed45a0a5d23d112f4 100644 (file)
 They cannot be implemented by user code, but are instead implemented
 by the compiler automatically for the types to which they apply.
 
-The 2 kinds are
-
-* Send - owned types and types containing owned types.  These types
-  may be transferred across task boundaries.
-
-* Freeze - types that are deeply immutable.
-
 */
 
-#[allow(missing_doc)];
-
+/// Types able to be transferred across task boundaries.
 #[lang="send"]
 pub trait Send {
     // empty.
 }
 
+/// Types that are either immutable or have inherited mutability.
 #[lang="freeze"]
 pub trait Freeze {
     // empty.
 }
 
+/// Types with a constant size known at compile-time.
 #[lang="sized"]
 pub trait Sized {
     // Empty.
index a73809d202c44c7eb64a47be72c228bc159f7e47..4dbe61b0c49d79c6a8a60a995065ed6781c8d654 100644 (file)
@@ -24,8 +24,8 @@
 ~~~{.rust}
 use std::local_data;
 
-static key_int: local_data::Key<int> = &local_data::Key;
-static key_vector: local_data::Key<~[int]> = &local_data::Key;
+local_data_key!(key_int: int);
+local_data_key!(key_vector: ~[int]);
 
 local_data::set(key_int, 3);
 local_data::get(key_int, |opt| assert_eq!(opt, Some(&3)));
diff --git a/src/libstd/nil.rs b/src/libstd/nil.rs
deleted file mode 100644 (file)
index d2e9cf9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012-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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Functions for the unit type.
-
-*/
-
-#[cfg(not(test))]
-use prelude::*;
-#[cfg(not(test))]
-use num::Zero;
-
-
-
-#[cfg(not(test))]
-impl Eq for () {
-    #[inline]
-    fn eq(&self, _other: &()) -> bool { true }
-    #[inline]
-    fn ne(&self, _other: &()) -> bool { false }
-}
-
-#[cfg(not(test))]
-impl Ord for () {
-    #[inline]
-    fn lt(&self, _other: &()) -> bool { false }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for () {
-    #[inline]
-    fn cmp(&self, _other: &()) -> Ordering { Equal }
-}
-
-#[cfg(not(test))]
-impl TotalEq for () {
-    #[inline]
-    fn equals(&self, _other: &()) -> bool { true }
-}
-
-#[cfg(not(test))]
-impl Zero for () {
-    #[inline]
-    fn zero() -> () { () }
-    #[inline]
-    fn is_zero(&self) -> bool { true }
-}
-
index 9e72b355bf9f96ae2d10f4a4c1b36893f0c96319..04a1cc11b26731f4e547c6294495f7a49c1fc09e 100644 (file)
@@ -468,55 +468,42 @@ fn is_zero(&self) -> bool { (**self).is_zero() }
 }
 
 /// Saturating math operations
-pub trait Saturating: Int {
+pub trait Saturating {
     /// Saturating addition operator.
     /// Returns a+b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_add(self, v: Self) -> Self;
+
+    /// Saturating subtraction operator.
+    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
+    fn saturating_sub(self, v: Self) -> Self;
+}
+
+impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
     #[inline]
-    fn saturating_add(self, v: Self) -> Self {
-        let x = self + v;
-        if v >= Zero::zero() {
-            if x < self {
-                // overflow
-                Bounded::max_value::<Self>()
-            } else { x }
-        } else {
-            if x > self {
-                // underflow
-                Bounded::min_value::<Self>()
-            } else { x }
+    fn saturating_add(self, v: T) -> T {
+        match self.checked_add(&v) {
+            Some(x) => x,
+            None => if v >= Zero::zero() {
+                Bounded::max_value::<T>()
+            } else {
+                Bounded::min_value::<T>()
+            }
         }
     }
 
-    /// Saturating subtraction operator.
-    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
     #[inline]
-    fn saturating_sub(self, v: Self) -> Self {
-        let x = self - v;
-        if v >= Zero::zero() {
-            if x > self {
-                // underflow
-                Bounded::min_value::<Self>()
-            } else { x }
-        } else {
-            if x < self {
-                // overflow
-                Bounded::max_value::<Self>()
-            } else { x }
+    fn saturating_sub(self, v: T) -> T {
+        match self.checked_sub(&v) {
+            Some(x) => x,
+            None => if v >= Zero::zero() {
+                Bounded::min_value::<T>()
+            } else {
+                Bounded::max_value::<T>()
+            }
         }
     }
 }
 
-impl Saturating for int {}
-impl Saturating for i8 {}
-impl Saturating for i16 {}
-impl Saturating for i32 {}
-impl Saturating for i64 {}
-impl Saturating for uint {}
-impl Saturating for u8 {}
-impl Saturating for u16 {}
-impl Saturating for u32 {}
-impl Saturating for u64 {}
-
 pub trait CheckedAdd: Add<Self, Self> {
     fn checked_add(&self, v: &Self) -> Option<Self>;
 }
index 04e839cf691dcefbd9c085f546d2559f68aa0ae3..af4fabef78b64687f3cb6b3ee7f0e64249b91d95 100644 (file)
@@ -46,8 +46,8 @@
 use ops::Add;
 use util;
 use num::Zero;
-use iterator::Iterator;
 use iterator;
+use iterator::{Iterator, DoubleEndedIterator};
 use str::{StrSlice, OwnedStr};
 use to_str::ToStr;
 use clone::DeepClone;
@@ -372,7 +372,7 @@ pub fn unwrap_or_zero(self) -> T {
         }
     }
 
-    /// Returns self or `Some(zero)` (for this type)
+    /// Returns self or `Some`-wrapped zero value
     #[inline]
     pub fn or_zero(self) -> Option<T> {
         match self {
@@ -407,6 +407,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+impl<A> DoubleEndedIterator<A> for OptionIterator<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.opt.take()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
index c916be79c53e5a3fa13c5e0d072c3139e3a149ad..b357489d62ff82174fab87f883b9b21509f94e06 100644 (file)
@@ -239,7 +239,7 @@ fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
 pub fn getenv(n: &str) -> Option<~str> {
     unsafe {
         do with_env_lock {
-            let s = do n.to_c_str().with_ref |buf| {
+            let s = do n.with_c_str |buf| {
                 libc::getenv(buf)
             };
             if s.is_null() {
@@ -274,8 +274,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 pub fn setenv(n: &str, v: &str) {
     unsafe {
         do with_env_lock {
-            do n.to_c_str().with_ref |nbuf| {
-                do v.to_c_str().with_ref |vbuf| {
+            do n.with_c_str |nbuf| {
+                do v.with_c_str |vbuf| {
                     libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
                 }
             }
@@ -306,7 +306,7 @@ pub fn unsetenv(n: &str) {
     fn _unsetenv(n: &str) {
         unsafe {
             do with_env_lock {
-                do n.to_c_str().with_ref |nbuf| {
+                do n.with_c_str |nbuf| {
                     libc::funcs::posix01::unistd::unsetenv(nbuf);
                 }
             }
@@ -328,7 +328,7 @@ fn _unsetenv(n: &str) {
 }
 
 pub fn fdopen(fd: c_int) -> *FILE {
-    do "r".to_c_str().with_ref |modebuf| {
+    do "r".with_c_str |modebuf| {
         unsafe {
             libc::fdopen(fd, modebuf)
         }
@@ -464,7 +464,7 @@ fn load_self() -> Option<~str> {
             let mut path = [0 as c_char, .. TMPBUF_SZ];
 
             do path.as_mut_buf |buf, len| {
-                let len = do "/proc/self/exe".to_c_str().with_ref |proc_self_buf| {
+                let len = do "/proc/self/exe".with_c_str |proc_self_buf| {
                     readlink(proc_self_buf, buf, len as size_t) as uint
                 };
 
@@ -593,7 +593,7 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool {
 /// Indicates whether a path represents a directory
 pub fn path_is_dir(p: &Path) -> bool {
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_is_dir(buf) != 0 as c_int
         }
     }
@@ -602,7 +602,7 @@ pub fn path_is_dir(p: &Path) -> bool {
 /// Indicates whether a path exists
 pub fn path_exists(p: &Path) -> bool {
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_exists(buf) != 0 as c_int
         }
     }
@@ -645,7 +645,7 @@ fn mkdir(p: &Path, _mode: c_int) -> bool {
 
     #[cfg(unix)]
     fn mkdir(p: &Path, mode: c_int) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
             }
@@ -697,7 +697,7 @@ unsafe fn get_list(p: &Path) -> ~[~str] {
             let mut strings = ~[];
             debug!("os::list_dir -- BEFORE OPENDIR");
 
-            let dir_ptr = do p.to_c_str().with_ref |buf| {
+            let dir_ptr = do p.with_c_str |buf| {
                 opendir(buf)
             };
 
@@ -819,7 +819,7 @@ fn rmdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn rmdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::rmdir(buf) == (0 as c_int)
             }
@@ -844,7 +844,7 @@ fn chdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn chdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::chdir(buf) == (0 as c_int)
             }
@@ -872,8 +872,8 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
     #[cfg(unix)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
         unsafe {
-            let istream = do from.to_c_str().with_ref |fromp| {
-                do "rb".to_c_str().with_ref |modebuf| {
+            let istream = do from.with_c_str |fromp| {
+                do "rb".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
@@ -884,8 +884,8 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \
                                                     for source file");
 
-            let ostream = do to.to_c_str().with_ref |top| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do to.with_c_str |top| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(top, modebuf)
                 }
             };
@@ -917,7 +917,7 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             fclose(ostream);
 
             // Give the new file the old file's permissions
-            if do to.to_c_str().with_ref |to_buf| {
+            if do to.with_c_str |to_buf| {
                 libc::chmod(to_buf, from_mode as libc::mode_t)
             } != 0 {
                 return false; // should be a condition...
@@ -944,7 +944,7 @@ fn unlink(p: &Path) -> bool {
     #[cfg(unix)]
     fn unlink(p: &Path) -> bool {
         unsafe {
-            do p.to_c_str().with_ref |buf| {
+            do p.with_c_str |buf| {
                 libc::unlink(buf) == (0 as c_int)
             }
         }
@@ -1282,7 +1282,7 @@ fn default_glob_t () -> libc::glob_t {
     }
 
     let mut g = default_glob_t();
-    do pattern.to_c_str().with_ref |c_pattern| {
+    do pattern.with_c_str |c_pattern| {
         unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
     };
     do(|| {
@@ -1929,14 +1929,14 @@ fn copy_file_ok() {
             let out = tempdir.push("out.txt");
 
             /* Write the temp input file */
-            let ostream = do input.to_c_str().with_ref |fromp| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do input.with_c_str |fromp| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
             assert!((ostream as uint != 0u));
             let s = ~"hello";
-            do "hello".to_c_str().with_ref |buf| {
+            do "hello".with_c_str |buf| {
                 let write_len = libc::fwrite(buf as *c_void,
                                              1u as size_t,
                                              (s.len() + 1u) as size_t,
@@ -2013,11 +2013,11 @@ fn lseek_(fd: c_int, size: uint) {
         remove_file(&path);
 
         let fd = unsafe {
-            let fd = do path.to_c_str().with_ref |path| {
+            let fd = do path.with_c_str |path| {
                 open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
             };
             lseek_(fd, size);
-            do "x".to_c_str().with_ref |x| {
+            do "x".with_c_str |x| {
                 assert!(write(fd, x as *c_void, 1) == 1);
             }
             fd
index 177f0efb6dad380677fef7b9d442ddbb5bf11411..de7658b5710b32cded88809f57693383a8896b5e 100644 (file)
@@ -381,7 +381,7 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "win32")]
 impl WindowsPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf, &mut st) } {
                 0 => Some(st),
@@ -415,7 +415,7 @@ pub fn get_mode(&self) -> Option<uint> {
 #[cfg(not(target_os = "win32"))]
 impl PosixPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
                 0 => Some(st),
@@ -493,7 +493,7 @@ pub fn get_ctime(&self) -> Option<(i64, int)> {
 #[cfg(unix)]
 impl PosixPath {
     pub fn lstat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::lstat(buf, &mut st) } {
                 0 => Some(st),
@@ -569,6 +569,10 @@ impl ToCStr for PosixPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 // FIXME (#3227): when default methods in traits are working, de-duplicate
@@ -781,6 +785,10 @@ impl c_str::ToCStr for WindowsPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 impl GenericPath for WindowsPath {
index deee49bc47235af321a648a502fc1b23035d8725..63f73002009312c21ccf7204f4c4aebba73bf72a 100644 (file)
@@ -69,7 +69,7 @@
 pub use from_str::FromStr;
 pub use to_bytes::IterBytes;
 pub use to_str::{ToStr, ToStrConsume};
-pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
+pub use tuple::{CopyableTuple, ImmutableTuple};
 pub use tuple::{CloneableTuple1, ImmutableTuple1};
 pub use tuple::{CloneableTuple2, CloneableTuple3, CloneableTuple4, CloneableTuple5};
 pub use tuple::{CloneableTuple6, CloneableTuple7, CloneableTuple8, CloneableTuple9};
index b13d46d540d4adae771882066939ec0011ffe512..de8f8c69e8432e25cd4137f9eae6007c3e59b561 100644 (file)
@@ -47,6 +47,7 @@ pub unsafe fn buf_len<T>(buf: **T) -> uint {
 }
 
 impl<T> Clone for *T {
+    #[inline]
     fn clone(&self) -> *T {
         *self
     }
@@ -481,7 +482,7 @@ struct Pair {
     fn test_position() {
         use libc::c_char;
 
-        do "hello".to_c_str().with_ref |p| {
+        do "hello".with_c_str |p| {
             unsafe {
                 assert!(2u == position(p, |c| *c == 'l' as c_char));
                 assert!(4u == position(p, |c| *c == 'o' as c_char));
@@ -492,9 +493,9 @@ fn test_position() {
 
     #[test]
     fn test_buf_len() {
-        do "hello".to_c_str().with_ref |p0| {
-            do "there".to_c_str().with_ref |p1| {
-                do "thing".to_c_str().with_ref |p2| {
+        do "hello".with_c_str |p0| {
+            do "there".with_c_str |p1| {
+                do "thing".with_c_str |p2| {
                     let v = ~[p0, p1, p2, null()];
                     do v.as_imm_buf |vp, len| {
                         assert_eq!(unsafe { buf_len(vp) }, 3u);
index 500278fddb0b16110bd329e42ebc62b7566b560c..bd2ea1d6ac6af9e099c7f5bb97ed11f3f0eba81d 100644 (file)
@@ -461,6 +461,26 @@ fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
      * ~~~
      */
     fn shuffle_mut<T>(&mut self, values: &mut [T]);
+
+    /**
+     * Sample up to `n` values from an iterator.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     *
+     * use std::rand;
+     * use std::rand::RngUtil;
+     *
+     * fn main() {
+     *     let mut rng = rand::rng();
+     *     let vals = range(1, 100).to_owned_vec();
+     *     let sample = rng.sample(vals.iter(), 5);
+     *     printfln!(sample);
+     * }
+     * ~~~
+     */
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A];
 }
 
 /// Extension methods for random number generators
@@ -607,6 +627,23 @@ fn shuffle_mut<T>(&mut self, values: &mut [T]) {
             values.swap(i, self.gen_uint_range(0u, i + 1u));
         }
     }
+
+    /// Randomly sample up to `n` elements from an iterator
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
+        let mut reservoir : ~[A] = vec::with_capacity(n);
+        for (i, elem) in iter.enumerate() {
+            if i < n {
+                reservoir.push(elem);
+                loop
+            }
+
+            let k = self.gen_uint_range(0, i + 1);
+            if k < reservoir.len() {
+                reservoir[k] = elem
+            }
+        }
+        reservoir
+    }
 }
 
 /// Create a random number generator with a default algorithm and seed.
@@ -914,6 +951,7 @@ pub fn random<T: Rand>() -> T {
 
 #[cfg(test)]
 mod test {
+    use iterator::{Iterator, range};
     use option::{Option, Some};
     use super::*;
 
@@ -1130,6 +1168,24 @@ pub enum rust_rng {}
             }
         }
     }
+
+    #[test]
+    fn test_sample() {
+        let MIN_VAL = 1;
+        let MAX_VAL = 100;
+
+        let mut r = rng();
+        let vals = range(MIN_VAL, MAX_VAL).to_owned_vec();
+        let small_sample = r.sample(vals.iter(), 5);
+        let large_sample = r.sample(vals.iter(), vals.len() + 5);
+
+        assert_eq!(small_sample.len(), 5);
+        assert_eq!(large_sample.len(), vals.len());
+
+        assert!(small_sample.iter().all(|e| {
+            **e >= MIN_VAL && **e <= MAX_VAL
+        }));
+    }
 }
 
 #[cfg(test)]
index 9de5e69148ae998cc39065e34844e0a4e3a0cdca..9ae901d60bc46ee755f13a98c8495b9b9d3a51e5 100644 (file)
@@ -18,8 +18,7 @@
 use iterator::Iterator;
 use option::{None, Option, Some, OptionIterator};
 use vec;
-use vec::{OwnedVector, ImmutableVector};
-use container::Container;
+use vec::OwnedVector;
 use to_str::ToStr;
 use str::StrSlice;
 
@@ -269,86 +268,76 @@ pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
     }
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Maps each element in the vector `ts` using the operation `op`.  Should an
-/// error occur, no further mappings are performed and the error is returned.
-/// Should no error occur, a vector containing the result of each map is
-/// returned.
+/// Takes each element in the iterator: if it is an error, no further
+/// elements are taken, and the error is returned.
+/// Should no error occur, a vector containing the values of each Result
+/// is returned.
 ///
 /// Here is an example which increments every integer in a vector,
 /// checking for overflow:
 ///
-///     fn inc_conditionally(x: uint) -> result<uint,str> {
+///     fn inc_conditionally(x: uint) -> Result<uint, &'static str> {
 ///         if x == uint::max_value { return Err("overflow"); }
 ///         else { return Ok(x+1u); }
 ///     }
-///     map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
-///         assert!(incd == ~[2u, 3u, 4u]);
-///     }
+///     let v = [1u, 2, 3];
+///     let res = collect(v.iter().map(|&x| inc_conditionally(x)));
+///     assert!(res == Ok(~[2u, 3, 4]));
 #[inline]
-pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
-                      -> Result<~[V],U> {
-    let mut vs: ~[V] = vec::with_capacity(ts.len());
-    for t in ts.iter() {
-        match op(t) {
-          Ok(v) => vs.push(v),
-          Err(u) => return Err(u)
+pub fn collect<T, E, Iter: Iterator<Result<T, E>>>(mut iterator: Iter)
+    -> Result<~[T], E> {
+    let (lower, _) = iterator.size_hint();
+    let mut vs: ~[T] = vec::with_capacity(lower);
+    for t in iterator {
+        match t {
+            Ok(v) => vs.push(v),
+            Err(u) => return Err(u)
         }
     }
-    return Ok(vs);
+    Ok(vs)
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Same as map, but it operates over two parallel vectors.
+/// Perform a fold operation over the result values from an iterator.
 ///
-/// A precondition is used here to ensure that the vectors are the same
-/// length.  While we do not often use preconditions in the standard
-/// library, a precondition is used here because result::t is generally
-/// used in 'careful' code contexts where it is both appropriate and easy
-/// to accommodate an error like the vectors being of different lengths.
+/// If an `Err` is encountered, it is immediately returned.
+/// Otherwise, the folded value is returned.
 #[inline]
-pub fn map_vec2<S, T, U: ToStr, V>(ss: &[S], ts: &[T],
-                                   op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
-    assert!(vec::same_length(ss, ts));
-    let n = ts.len();
-    let mut vs = vec::with_capacity(n);
-    let mut i = 0u;
-    while i < n {
-        match op(&ss[i],&ts[i]) {
-          Ok(v) => vs.push(v),
-          Err(u) => return Err(u)
+pub fn fold<T, V, E,
+            Iter: Iterator<Result<T, E>>>(
+            mut iterator: Iter,
+            mut init: V,
+            f: &fn(V, T) -> V)
+         -> Result<V, E> {
+    for t in iterator {
+        match t {
+            Ok(v) => init = f(init, v),
+            Err(u) => return Err(u)
         }
-        i += 1u;
     }
-    return Ok(vs);
+    Ok(init)
 }
 
-// FIXME: #8228 Replaceable by an external iterator?
-/// Applies op to the pairwise elements from `ss` and `ts`, aborting on
-/// error.  This could be implemented using `map_zip()` but it is more efficient
-/// on its own as no result vector is built.
+/// Perform a trivial fold operation over the result values
+/// from an iterator.
+///
+/// If an `Err` is encountered, it is immediately returned.
+/// Otherwise, a simple `Ok(())` is returned.
 #[inline]
-pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
-                                 op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
-    assert!(vec::same_length(ss, ts));
-    let n = ts.len();
-    let mut i = 0u;
-    while i < n {
-        match op(&ss[i],&ts[i]) {
-          Ok(()) => (),
-          Err(u) => return Err(u)
-        }
-        i += 1u;
-    }
-    return Ok(());
+pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
+             iterator: Iter)
+          -> Result<(), E> {
+    fold(iterator, (), |_, _| ())
 }
 
+
 #[cfg(test)]
 mod tests {
     use super::*;
 
     use either;
+    use iterator::range;
     use str::OwnedStr;
+    use vec::ImmutableVector;
 
     pub fn op1() -> Result<int, ~str> { Ok(666) }
 
@@ -431,4 +420,44 @@ pub fn test_to_either() {
         assert_eq!(r.to_either(), either::Right(100));
         assert_eq!(err.to_either(), either::Left(404));
     }
+
+    #[test]
+    fn test_collect() {
+        assert_eq!(collect(range(0, 0)
+                           .map(|_| Ok::<int, ()>(0))),
+                   Ok(~[]));
+        assert_eq!(collect(range(0, 3)
+                           .map(|x| Ok::<int, ()>(x))),
+                   Ok(~[0, 1, 2]));
+        assert_eq!(collect(range(0, 3)
+                           .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
+                   Err(2));
+
+        // test that it does not take more elements than it needs
+        let functions = [|| Ok(()), || Err(1), || fail!()];
+
+        assert_eq!(collect(functions.iter().map(|f| (*f)())),
+                   Err(1));
+    }
+
+    #[test]
+    fn test_fold() {
+        assert_eq!(fold_(range(0, 0)
+                        .map(|_| Ok::<(), ()>(()))),
+                   Ok(()));
+        assert_eq!(fold(range(0, 3)
+                        .map(|x| Ok::<int, ()>(x)),
+                        0, |a, b| a + b),
+                   Ok(3));
+        assert_eq!(fold_(range(0, 3)
+                        .map(|x| if x > 1 { Err(x) } else { Ok(()) })),
+                   Err(2));
+
+        // test that it does not take more elements than it needs
+        let functions = [|| Ok(()), || Err(1), || fail!()];
+
+        assert_eq!(fold_(functions.iter()
+                        .map(|f| (*f)())),
+                   Err(1));
+    }
 }
index f620a7347a4cd31bf403146bfa4c62c2ceff9a5e..ba4cbc668038fcec80364da26d167f7ae5e762cd 100644 (file)
@@ -52,7 +52,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
     match try_take_task_borrow_list() {
         None => { // not recording borrows
             let msg = "borrowed";
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line);
             }
         }
@@ -68,7 +68,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
                     sep = " and at ";
                 }
             }
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line)
             }
         }
@@ -208,7 +208,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
             let br = borrow_list.pop();
             if br.box != a || br.file != file || br.line != line {
                 let err = fmt!("wrong borrow found, br=%?", br);
-                do err.to_c_str().with_ref |msg_p| {
+                do err.with_c_str |msg_p| {
                     sys::begin_unwind_(msg_p, file, line)
                 }
             }
index 117795f6c90e0ab49860e92cd73c6277fceea12a..4ee65a2b4495fa275d6baca8c4393229f4292155 100644 (file)
@@ -66,7 +66,7 @@ pub fn init(crate_map: *u8) {
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
         Some(spec) => {
-            do spec.to_c_str().with_ref |buf| {
+            do spec.with_c_str |buf| {
                 unsafe { rust_update_log_settings(crate_map, buf) }
             }
         }
index 3a991e92b0b5f1c421dd48772e01c07e6d74ed5f..65214d0cea78a6d415a4fcc609e6c04b166909c1 100644 (file)
 mod sleeper_list;
 
 /// Stack segments and caching.
-mod stack;
+pub mod stack;
 
 /// CPU context swapping.
 mod context;
index c669f25d8b738033b78c7ab4188cd1be0579bcaa..708166518bb89e406930dbcd07778b8dd8d50103 100644 (file)
@@ -64,7 +64,7 @@ pub struct Coroutine {
     /// The segment of stack on which the task is currently running or
     /// if the task is blocked, on which the task will resume
     /// execution.
-    priv current_stack_segment: StackSegment,
+    current_stack_segment: StackSegment,
     /// Always valid if the task is alive and not running.
     saved_context: Context
 }
index 038ebad3540aecd29657474dffaacaaf8a2ab365..a26b8a3ad594de52f5bc128b24eaa580f664fe02 100644 (file)
@@ -654,7 +654,7 @@ fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
 
     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_JOIN_GROUP)
             }
@@ -668,7 +668,7 @@ fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
 
     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_LEAVE_GROUP)
             }
index e240395a495d36f02f60cc0daadd06c58353c773..11d64f4697cb8e3ad28950b591b39b4684642a76 100644 (file)
@@ -373,12 +373,12 @@ pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
 }
 
 pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
-    do ip.to_c_str().with_ref |ip_buf| {
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
 pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
-    do ip.to_c_str().with_ref |ip_buf| {
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
index 31e317604c77e073ba75edde11acddec9d970e13..bd284b39983045f8a64324c2c8a84064a908ac75 100644 (file)
@@ -68,7 +68,7 @@ pub struct ProcessOptions<'self> {
      * If this is Some(vec-of-names-and-values) then the new process will
      * have an environment containing the given named values only.
      */
-    env: Option<&'self [(~str, ~str)]>,
+    env: Option<~[(~str, ~str)]>,
 
     /**
      * If this is None then the new process will use the same initial working
@@ -171,7 +171,7 @@ pub fn new(prog: &str, args: &[~str], options: ProcessOptions)
             Some(fd) => (None, fd)
         };
 
-        let res = spawn_process_os(prog, args, options.env, options.dir,
+        let res = spawn_process_os(prog, args, options.env.clone(), options.dir,
                                    in_fd, out_fd, err_fd);
 
         unsafe {
@@ -444,7 +444,7 @@ struct SpawnProcessResult {
 
 #[cfg(windows)]
 fn spawn_process_os(prog: &str, args: &[~str],
-                    env: Option<&[(~str, ~str)]>,
+                    env: Option<~[(~str, ~str)]>,
                     dir: Option<&Path>,
                     in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
 
@@ -506,7 +506,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
 
         do with_envp(env) |envp| {
             do with_dirp(dir) |dirp| {
-                do cmd.to_c_str().with_ref |cmdp| {
+                do cmd.with_c_str |cmdp| {
                     let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
                                                  ptr::mut_null(), ptr::mut_null(), TRUE,
                                                  0, envp, dirp, &mut si, &mut pi);
@@ -627,7 +627,7 @@ fn backslash_run_ends_in_quote(s: &str, mut i: uint) -> bool {
 
 #[cfg(unix)]
 fn spawn_process_os(prog: &str, args: &[~str],
-                    env: Option<&[(~str, ~str)]>,
+                    env: Option<~[(~str, ~str)]>,
                     dir: Option<&Path>,
                     in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
 
@@ -717,7 +717,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: &fn(**libc::c_char) -> T) -> T {
 }
 
 #[cfg(unix)]
-fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
+fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
     use vec;
 
     // On posixy systems we can pass a char** for envp, which is a
@@ -749,7 +749,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
 }
 
 #[cfg(windows)]
-fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
+fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
     // On win32 we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
     // \0 to terminate.
@@ -775,7 +775,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
 
 fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
     match d {
-      Some(dir) => dir.to_c_str().with_ref(|buf| cb(buf)),
+      Some(dir) => dir.with_c_str(|buf| cb(buf)),
       None => cb(ptr::null())
     }
 }
@@ -1284,14 +1284,14 @@ fn test_change_working_directory() {
     }
 
     #[cfg(unix,not(target_os="android"))]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("env", [], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
         })
     }
     #[cfg(unix,target_os="android")]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
@@ -1299,7 +1299,7 @@ fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
     }
 
     #[cfg(windows)]
-    fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process {
+    fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("cmd", [~"/c", ~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
@@ -1344,7 +1344,7 @@ fn test_add_to_env() {
         let mut new_env = os::env();
         new_env.push((~"RUN_TEST_NEW_ENV", ~"123"));
 
-        let mut prog = run_env(Some(new_env.slice(0, new_env.len())));
+        let mut prog = run_env(Some(new_env));
         let output = str::from_bytes(prog.finish_with_output().output);
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"));
index c4bd0a6d043544c8807002675b6e93fb1ae5f369..9370e7b0e84c9021f7d03be5b04ad0c5485d591b 100644 (file)
@@ -110,7 +110,7 @@ pub mod linkhack {
 #[path = "num/f32.rs"]   pub mod f32;
 #[path = "num/f64.rs"]   pub mod f64;
 
-pub mod nil;
+pub mod unit;
 pub mod bool;
 pub mod char;
 pub mod tuple;
index 886e4d86ab643f23d3ed3003489ad154dae749e2..a759b8cbd62355ec530eabf74bf62bce8dffe65d 100644 (file)
@@ -33,6 +33,7 @@
 use ptr::RawPtr;
 use to_str::ToStr;
 use uint;
+use unstable::raw::{Repr, Slice};
 use vec;
 use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
 
@@ -758,15 +759,7 @@ macro_rules! utf8_acc_cont_byte(
     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as uint)
 )
 
-// UTF-8 tags and ranges
 static TAG_CONT_U8: u8 = 128u8;
-static TAG_CONT: uint = 128u;
-static MAX_ONE_B: uint = 128u;
-static TAG_TWO_B: uint = 192u;
-static MAX_TWO_B: uint = 2048u;
-static TAG_THREE_B: uint = 224u;
-static MAX_THREE_B: uint = 65536u;
-static TAG_FOUR_B: uint = 240u;
 static MAX_UNICODE: uint = 1114112u;
 
 /// Unsafe operations
@@ -1057,7 +1050,7 @@ pub trait Str {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a str;
 
-    /// Convert `self` into a ~str.
+    /// Convert `self` into a ~str, not making a copy if possible
     fn into_owned(self) -> ~str;
 }
 
@@ -1988,40 +1981,18 @@ fn push_str(&mut self, rhs: &str) {
     #[inline]
     fn push_char(&mut self, c: char) {
         assert!((c as uint) < MAX_UNICODE); // FIXME: #7609: should be enforced on all `char`
+        let cur_len = self.len();
+        self.reserve_at_least(cur_len + 4); // may use up to 4 bytes
+
+        // Attempt to not use an intermediate buffer by just pushing bytes
+        // directly onto this string.
         unsafe {
-            let code = c as uint;
-            let nb = if code < MAX_ONE_B { 1u }
-            else if code < MAX_TWO_B { 2u }
-            else if code < MAX_THREE_B { 3u }
-            else { 4u };
-            let len = self.len();
-            let new_len = len + nb;
-            self.reserve_at_least(new_len);
-            let off = len as int;
-            do self.as_mut_buf |buf, _len| {
-                match nb {
-                    1u => {
-                        *ptr::mut_offset(buf, off) = code as u8;
-                    }
-                    2u => {
-                        *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8;
-                        *ptr::mut_offset(buf, off + 1) = (code & 63u | TAG_CONT) as u8;
-                    }
-                    3u => {
-                        *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8;
-                        *ptr::mut_offset(buf, off + 1) = (code >> 6u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 2) = (code & 63u | TAG_CONT) as u8;
-                    }
-                    4u => {
-                        *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8;
-                        *ptr::mut_offset(buf, off + 1) = (code >> 12u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 2) = (code >> 6u & 63u | TAG_CONT) as u8;
-                        *ptr::mut_offset(buf, off + 3) = (code & 63u | TAG_CONT) as u8;
-                    }
-                    _ => {}
-                }
-            }
-            raw::set_len(self, new_len);
+            let v = self.repr();
+            let len = c.encode_utf8(cast::transmute(Slice {
+                data: ((&(*v).data) as *u8).offset(cur_len as int),
+                len: 4,
+            }));
+            raw::set_len(self, cur_len + len);
         }
     }
 
@@ -2140,9 +2111,9 @@ fn clone(&self) -> @str {
     }
 }
 
-impl<T: Iterator<char>> FromIterator<char, T> for ~str {
+impl FromIterator<char> for ~str {
     #[inline]
-    fn from_iterator(iterator: &mut T) -> ~str {
+    fn from_iterator<T: Iterator<char>>(iterator: &mut T) -> ~str {
         let (lower, _) = iterator.size_hint();
         let mut buf = with_capacity(lower);
         buf.extend(iterator);
@@ -2150,9 +2121,9 @@ fn from_iterator(iterator: &mut T) -> ~str {
     }
 }
 
-impl<T: Iterator<char>> Extendable<char, T> for ~str {
+impl Extendable<char> for ~str {
     #[inline]
-    fn extend(&mut self, iterator: &mut T) {
+    fn extend<T: Iterator<char>>(&mut self, iterator: &mut T) {
         let (lower, _) = iterator.size_hint();
         let reserve = lower + self.len();
         self.reserve_at_least(reserve);
index 701d57388158bd0697ebf030911c86ef95b39630..e0068f5e53e141a1e666e13f6f1f4ddde1e86571 100644 (file)
@@ -23,7 +23,7 @@
 use option::{Some, None};
 
 /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
-#[deriving(Clone, Eq)]
+#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
 pub struct Ascii { priv chr: u8 }
 
 impl Ascii {
@@ -250,21 +250,40 @@ fn into_bytes(self) -> ~[u8] {
     }
 }
 
-
-/// Convert the string to ASCII upper case:
-/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
-/// but non-ASCII letters are unchanged.
-#[inline]
-pub fn to_ascii_upper(string: &str) -> ~str {
-    map_bytes(string, ASCII_UPPER_MAP)
+/// Extension methods for ASCII-subset only operations on strings
+pub trait StrAsciiExt {
+    /// Convert the string to ASCII upper case:
+    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+    /// but non-ASCII letters are unchanged.
+    fn to_ascii_upper(&self) -> ~str;
+
+    /// Convert the string to ASCII lower case:
+    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+    /// but non-ASCII letters are unchanged.
+    fn to_ascii_lower(&self) -> ~str;
+
+    /// Check that two strings are an ASCII case-insensitive match.
+    /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
+    /// but without allocating and copying temporary strings.
+    fn eq_ignore_ascii_case(&self, other: &str) -> bool;
 }
 
-/// Convert the string to ASCII lower case:
-/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
-/// but non-ASCII letters are unchanged.
-#[inline]
-pub fn to_ascii_lower(string: &str) -> ~str {
-    map_bytes(string, ASCII_LOWER_MAP)
+impl<'self> StrAsciiExt for &'self str {
+    #[inline]
+    fn to_ascii_upper(&self) -> ~str {
+        map_bytes(*self, ASCII_UPPER_MAP)
+    }
+
+    #[inline]
+    fn to_ascii_lower(&self) -> ~str {
+        map_bytes(*self, ASCII_LOWER_MAP)
+    }
+
+    #[inline]
+    fn eq_ignore_ascii_case(&self, other: &str) -> bool {
+        self.len() == other.len() && self.as_bytes().iter().zip(other.as_bytes().iter()).all(
+            |(byte_self, byte_other)| ASCII_LOWER_MAP[*byte_self] == ASCII_LOWER_MAP[*byte_other])
+    }
 }
 
 #[inline]
@@ -283,15 +302,6 @@ fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
     result
 }
 
-/// Check that two strings are an ASCII case-insensitive match.
-/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
-/// but without allocating and copying temporary strings.
-#[inline]
-pub fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
-    a.len() == b.len() && a.as_bytes().iter().zip(b.as_bytes().iter()).all(
-        |(byte_a, byte_b)| ASCII_LOWER_MAP[*byte_a] == ASCII_LOWER_MAP[*byte_b])
-}
-
 static ASCII_LOWER_MAP: &'static [u8] = &[
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@@ -453,49 +463,48 @@ fn test_ascii_to_bytes() {
 
     #[test]
     fn test_to_ascii_upper() {
-        assert_eq!(to_ascii_upper("url()URL()uRl()ürl"), ~"URL()URL()URL()üRL");
-        assert_eq!(to_ascii_upper("hıKß"), ~"HıKß");
+        assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), ~"URL()URL()URL()üRL");
+        assert_eq!("hıKß".to_ascii_upper(), ~"HıKß");
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let upper = if 'a' <= c && c <= 'z' { c + 'A' - 'a' } else { c };
-            assert_eq!(to_ascii_upper(from_char(i as char)), from_char(upper))
+            assert_eq!(from_char(i as char).to_ascii_upper(), from_char(upper))
             i += 1;
         }
     }
 
     #[test]
     fn test_to_ascii_lower() {
-        assert_eq!(to_ascii_lower("url()URL()uRl()Ürl"), ~"url()url()url()Ürl");
+        assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), ~"url()url()url()Ürl");
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert_eq!(to_ascii_lower("HİKß"), ~"hİKß");
+        assert_eq!("HİKß".to_ascii_lower(), ~"hİKß");
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
-            assert_eq!(to_ascii_lower(from_char(i as char)), from_char(lower))
+            assert_eq!(from_char(i as char).to_ascii_lower(), from_char(lower))
             i += 1;
         }
     }
 
-
     #[test]
     fn test_eq_ignore_ascii_case() {
-        assert!(eq_ignore_ascii_case("url()URL()uRl()Ürl", "url()url()url()Ürl"));
-        assert!(!eq_ignore_ascii_case("Ürl", "ürl"));
+        assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
+        assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert!(eq_ignore_ascii_case("HİKß", "hİKß"));
-        assert!(!eq_ignore_ascii_case("İ", "i"));
-        assert!(!eq_ignore_ascii_case("K", "k"));
-        assert!(!eq_ignore_ascii_case("ß", "s"));
+        assert!("HİKß".eq_ignore_ascii_case("hİKß"));
+        assert!(!"İ".eq_ignore_ascii_case("i"));
+        assert!(!"K".eq_ignore_ascii_case("k"));
+        assert!(!"ß".eq_ignore_ascii_case("s"));
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
-            assert!(eq_ignore_ascii_case(from_char(i as char), from_char(lower)));
+            assert!(from_char(i as char).eq_ignore_ascii_case(from_char(lower)));
             i += 1;
         }
     }
index 03e6412fcb8c739fb8bcc562123a66bfdb1549de..bfb9bee78028c3d59755739f3021f64194d0c427 100644 (file)
@@ -105,8 +105,8 @@ pub trait FailWithCause {
 
 impl FailWithCause for ~str {
     fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
@@ -115,8 +115,8 @@ fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
 
 impl FailWithCause for &'static str {
     fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
index da1fb9abaeeb6aa0b9d158c3073d5bc9e8e758dc..f5c7b719c4f19bfba24cdd28755b15dba8e0ba96 100644 (file)
@@ -205,16 +205,16 @@ pub fn upper_bound_iter<'a>(&'a self, key: uint) -> TrieMapIterator<'a, T> {
     }
 }
 
-impl<T, Iter: Iterator<(uint, T)>> FromIterator<(uint, T), Iter> for TrieMap<T> {
-    fn from_iterator(iter: &mut Iter) -> TrieMap<T> {
+impl<T> FromIterator<(uint, T)> for TrieMap<T> {
+    fn from_iterator<Iter: Iterator<(uint, T)>>(iter: &mut Iter) -> TrieMap<T> {
         let mut map = TrieMap::new();
         map.extend(iter);
         map
     }
 }
 
-impl<T, Iter: Iterator<(uint, T)>> Extendable<(uint, T), Iter> for TrieMap<T> {
-    fn extend(&mut self, iter: &mut Iter) {
+impl<T> Extendable<(uint, T)> for TrieMap<T> {
+    fn extend<Iter: Iterator<(uint, T)>>(&mut self, iter: &mut Iter) {
         for (k, v) in *iter {
             self.insert(k, v);
         }
@@ -294,16 +294,16 @@ pub fn upper_bound_iter<'a>(&'a self, val: uint) -> TrieSetIterator<'a> {
     }
 }
 
-impl<Iter: Iterator<uint>> FromIterator<uint, Iter> for TrieSet {
-    fn from_iterator(iter: &mut Iter) -> TrieSet {
+impl FromIterator<uint> for TrieSet {
+    fn from_iterator<Iter: Iterator<uint>>(iter: &mut Iter) -> TrieSet {
         let mut set = TrieSet::new();
         set.extend(iter);
         set
     }
 }
 
-impl<Iter: Iterator<uint>> Extendable<uint, Iter> for TrieSet {
-    fn extend(&mut self, iter: &mut Iter) {
+impl Extendable<uint> for TrieSet {
+    fn extend<Iter: Iterator<uint>>(&mut self, iter: &mut Iter) {
         for elem in *iter {
             self.insert(elem);
         }
index 8a3c024ede50d253a323c9b02c9f0148503dc9d6..12073a1f4f0951e4db9d64ba54de5279a5bed565 100644 (file)
@@ -13,9 +13,6 @@
 #[allow(missing_doc)];
 
 use clone::Clone;
-use vec;
-use vec::ImmutableVector;
-use iterator::Iterator;
 
 pub use self::inner::*;
 
@@ -79,55 +76,6 @@ fn second_ref<'a>(&'a self) -> &'a U {
     }
 }
 
-pub trait ExtendedTupleOps<A,B> {
-    fn zip(&self) -> ~[(A, B)];
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
-}
-
-impl<'self,
-     A:Clone,
-     B:Clone>
-     ExtendedTupleOps<A,B> for
-     (&'self [A], &'self [B]) {
-    #[inline]
-    fn zip(&self) -> ~[(A, B)] {
-        match *self {
-            (ref a, ref b) => {
-                vec::zip_slice(*a, *b)
-            }
-        }
-    }
-
-    #[inline]
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
-        match *self {
-            (ref a, ref b) => {
-                a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
-            }
-        }
-    }
-}
-
-impl<A:Clone, B:Clone> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
-    #[inline]
-    fn zip(&self) -> ~[(A, B)] {
-        match *self {
-            (ref a, ref b) => {
-                vec::zip_slice(*a, *b)
-            }
-        }
-    }
-
-    #[inline]
-    fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
-        match *self {
-            (ref a, ref b) => {
-                a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
-            }
-        }
-    }
-}
-
 // macro for implementing n-ary tuple functions and operations
 
 macro_rules! tuple_impls {
diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs
new file mode 100644 (file)
index 0000000..82f14e4
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2012-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+Functions for the unit type.
+
+*/
+
+#[cfg(not(test))]
+use prelude::*;
+#[cfg(not(test))]
+use num::Zero;
+
+#[cfg(not(test))]
+impl Eq for () {
+    #[inline]
+    fn eq(&self, _other: &()) -> bool { true }
+    #[inline]
+    fn ne(&self, _other: &()) -> bool { false }
+}
+
+#[cfg(not(test))]
+impl Ord for () {
+    #[inline]
+    fn lt(&self, _other: &()) -> bool { false }
+}
+
+#[cfg(not(test))]
+impl TotalOrd for () {
+    #[inline]
+    fn cmp(&self, _other: &()) -> Ordering { Equal }
+}
+
+#[cfg(not(test))]
+impl TotalEq for () {
+    #[inline]
+    fn equals(&self, _other: &()) -> bool { true }
+}
+
+#[cfg(not(test))]
+impl Zero for () {
+    #[inline]
+    fn zero() -> () { () }
+    #[inline]
+    fn is_zero(&self) -> bool { true }
+}
index 49e3e0777df84e58356fe734fe07d3e37c36f34f..005cedd0ffdfdccca83d869c3b519e091beb4f6e 100644 (file)
@@ -66,7 +66,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, ~str> {
         // T but that feature is still unimplemented
 
         let maybe_symbol_value = do dl::check_for_errors_in {
-            do symbol.to_c_str().with_ref |raw_string| {
+            do symbol.with_c_str |raw_string| {
                 dl::symbol(self.handle, raw_string)
             }
         };
@@ -145,7 +145,7 @@ mod dl {
     use result::*;
 
     pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
-        do filename.to_c_str().with_ref |raw_name| {
+        do filename.with_c_str |raw_name| {
             dlopen(raw_name, Lazy as libc::c_int)
         }
     }
index 956ffb82902de0addac7b55c8b0a33f9e22b2e7f..91b4283ba12dd92236cb847bbaf833331bbd2fa9 100644 (file)
@@ -29,7 +29,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
                          index: size_t, len: size_t) {
     let msg = fmt!("index out of bounds: the len is %d but the index is %d",
                     len as int, index as int);
-    do msg.to_c_str().with_ref |buf| {
+    do msg.with_c_str |buf| {
         fail_(buf, file, line);
     }
 }
index 0e074b53d6b4b88aa6a61356d68245b608da80d7..bdf84604fb37f852bf3898ba49efe3d800c996b6 100644 (file)
@@ -56,6 +56,7 @@ impl<'self, T> Repr<Slice<T>> for &'self [T] {}
 impl<'self> Repr<Slice<u8>> for &'self str {}
 impl<T> Repr<*Box<T>> for @T {}
 impl<T> Repr<*Box<Vec<T>>> for @[T] {}
+impl Repr<*String> for ~str {}
 
 // sure would be nice to have this
 // impl<T> Repr<*Vec<T>> for ~[T] {}
index 27e09d8547989f1bbe2214f9adaceb97805fb08d..7748c040a1ddc28aeac01d8f86a49821d88d93f4 100644 (file)
@@ -390,39 +390,6 @@ pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
     (ts, us)
 }
 
-/**
- * Convert two vectors to a vector of pairs, by reference. As zip().
- */
-pub fn zip_slice<T:Clone,U:Clone>(v: &[T], u: &[U]) -> ~[(T, U)] {
-    let mut zipped = ~[];
-    let sz = v.len();
-    let mut i = 0u;
-    assert_eq!(sz, u.len());
-    while i < sz {
-        zipped.push((v[i].clone(), u[i].clone()));
-        i += 1u;
-    }
-    zipped
-}
-
-/**
- * Convert two vectors to a vector of pairs.
- *
- * Returns a vector of tuples, where the i-th tuple contains the
- * i-th elements from each of the input vectors.
- */
-pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
-    let mut i = v.len();
-    assert_eq!(i, u.len());
-    let mut w = with_capacity(i);
-    while i > 0 {
-        w.push((v.pop(),u.pop()));
-        i -= 1;
-    }
-    w.reverse();
-    w
-}
-
 /**
  * Iterate over all permutations of vector `v`.
  *
@@ -707,26 +674,23 @@ pub trait Vector<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
+
 impl<'self,T> Vector<T> for &'self [T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { *self }
 }
+
 impl<T> Vector<T> for ~[T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
+
 impl<T> Vector<T> for @[T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
 
 impl<'self, T> Container for &'self [T] {
-    /// Returns true if a vector contains no elements
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.as_imm_buf(|_p, len| len == 0u)
-    }
-
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -735,12 +699,6 @@ fn len(&self) -> uint {
 }
 
 impl<T> Container for ~[T] {
-    /// Returns true if a vector contains no elements
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.as_imm_buf(|_p, len| len == 0u)
-    }
-
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -748,13 +706,17 @@ fn len(&self) -> uint {
     }
 }
 
-#[allow(missing_doc)]
+/// Extension methods for vector slices with copyable elements
 pub trait CopyableVector<T> {
+    /// Copy `self` into a new owned vector
     fn to_owned(&self) -> ~[T];
+
+    /// Convert `self` into a owned vector, not making a copy if possible.
+    fn into_owned(self) -> ~[T];
 }
 
-/// Extension methods for vectors
-impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
+/// Extension methods for vector slices
+impl<'self, T: Clone> CopyableVector<T> for &'self [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
@@ -764,6 +726,27 @@ fn to_owned(&self) -> ~[T] {
         }
         result
     }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
+}
+
+/// Extension methods for owned vectors
+impl<T: Clone> CopyableVector<T> for ~[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.clone() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self }
+}
+
+/// Extension methods for managed vectors
+impl<T: Clone> CopyableVector<T> for @[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.as_slice().to_owned() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
 }
 
 #[allow(missing_doc)]
@@ -2316,8 +2299,8 @@ fn next(&mut self) -> Option<T> {
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
-    fn from_iterator(iterator: &mut T) -> ~[A] {
+impl<A> FromIterator<A> for ~[A] {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
         let mut xs = with_capacity(lower);
         for x in *iterator {
@@ -2327,8 +2310,8 @@ fn from_iterator(iterator: &mut T) -> ~[A] {
     }
 }
 
-impl<A, T: Iterator<A>> Extendable<A, T> for ~[A] {
-    fn extend(&mut self, iterator: &mut T) {
+impl<A> Extendable<A> for ~[A] {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
         let (lower, _) = iterator.size_hint();
         let len = self.len();
         self.reserve(len + lower);
@@ -2837,14 +2820,7 @@ fn test_each_permutation() {
 
     #[test]
     fn test_zip_unzip() {
-        let v1 = ~[1, 2, 3];
-        let v2 = ~[4, 5, 6];
-
-        let z1 = zip(v1, v2);
-
-        assert_eq!((1, 4), z1[0]);
-        assert_eq!((2, 5), z1[1]);
-        assert_eq!((3, 6), z1[2]);
+        let z1 = ~[(1, 4), (2, 5), (3, 6)];
 
         let (left, right) = unzip(z1);
 
index 1fea0c2e6f92db4a1e099ede69a4df1863c8f7ad..6c3fb82965d1c162976ce91f15dcd1743b96babd 100644 (file)
@@ -89,11 +89,11 @@ pub struct Ctx {
 }
 
 impl Ctx {
-    fn extend(@mut self, elt: ident) -> @path {
+    fn extend(&self, elt: ident) -> @path {
         @vec::append(self.path.clone(), [path_name(elt)])
     }
 
-    fn map_method(@mut self,
+    fn map_method(&mut self,
                   impl_did: def_id,
                   impl_path: @path,
                   m: @method,
@@ -107,7 +107,7 @@ fn map_method(@mut self,
         self.map.insert(m.self_id, node_local(special_idents::self_));
     }
 
-    fn map_struct_def(@mut self,
+    fn map_struct_def(&mut self,
                       struct_def: @ast::struct_def,
                       parent_node: ast_node,
                       ident: ast::ident) {
@@ -130,7 +130,7 @@ fn map_struct_def(@mut self,
         }
     }
 
-    fn map_expr(@mut self, ex: @expr) {
+    fn map_expr(&mut self, ex: @expr) {
         self.map.insert(ex.id, node_expr(ex));
 
         // Expressions which are or might be calls:
@@ -141,10 +141,10 @@ fn map_expr(@mut self, ex: @expr) {
             }
         }
 
-        visit::visit_expr(self as @mut Visitor<()>, ex, ());
+        visit::walk_expr(self, ex, ());
     }
 
-    fn map_fn(@mut self,
+    fn map_fn(&mut self,
               fk: &visit::fn_kind,
               decl: &fn_decl,
               body: &Block,
@@ -153,21 +153,21 @@ fn map_fn(@mut self,
         for a in decl.inputs.iter() {
             self.map.insert(a.id, node_arg);
         }
-        visit::visit_fn(self as @mut Visitor<()>, fk, decl, body, sp, id, ());
+        visit::walk_fn(self, fk, decl, body, sp, id, ());
     }
 
-    fn map_stmt(@mut self, stmt: @stmt) {
+    fn map_stmt(&mut self, stmt: @stmt) {
         self.map.insert(stmt_id(stmt), node_stmt(stmt));
-        visit::visit_stmt(self as @mut Visitor<()>, stmt, ());
+        visit::walk_stmt(self, stmt, ());
     }
 
-    fn map_block(@mut self, b: &Block) {
+    fn map_block(&mut self, b: &Block) {
         // clone is FIXME #2543
         self.map.insert(b.id, node_block((*b).clone()));
-        visit::visit_block(self as @mut Visitor<()>, b, ());
+        visit::walk_block(self, b, ());
     }
 
-    fn map_pat(@mut self, pat: @pat) {
+    fn map_pat(&mut self, pat: @pat) {
         match pat.node {
             pat_ident(_, ref path, _) => {
                 // Note: this is at least *potentially* a pattern...
@@ -177,12 +177,12 @@ fn map_pat(@mut self, pat: @pat) {
             _ => ()
         }
 
-        visit::visit_pat(self as @mut Visitor<()>, pat, ());
+        visit::walk_pat(self, pat, ());
     }
 }
 
 impl Visitor<()> for Ctx {
-    fn visit_item(@mut self, i: @item, _: ()) {
+    fn visit_item(&mut self, i: @item, _: ()) {
         // clone is FIXME #2543
         let item_path = @self.path.clone();
         self.map.insert(i.id, node_item(i, item_path));
@@ -190,7 +190,8 @@ fn visit_item(@mut self, i: @item, _: ()) {
             item_impl(_, _, _, ref ms) => {
                 let impl_did = ast_util::local_def(i.id);
                 for m in ms.iter() {
-                    self.map_method(impl_did, self.extend(i.ident), *m, false)
+                    let extended = { self.extend(i.ident) };
+                    self.map_method(impl_did, extended, *m, false)
                 }
             }
             item_enum(ref enum_definition, _) => {
@@ -254,24 +255,24 @@ fn visit_item(@mut self, i: @item, _: ()) {
             }
             _ => self.path.push(path_name(i.ident))
         }
-        visit::visit_item(self as @mut Visitor<()>, i, ());
+        visit::walk_item(self, i, ());
         self.path.pop();
     }
 
-    fn visit_pat(@mut self, pat: @pat, _: ()) {
+    fn visit_pat(&mut self, pat: @pat, _: ()) {
         self.map_pat(pat);
-        visit::visit_pat(self as @mut Visitor<()>, pat, ())
+        visit::walk_pat(self, pat, ())
     }
 
-    fn visit_expr(@mut self, expr: @expr, _: ()) {
+    fn visit_expr(&mut self, expr: @expr, _: ()) {
         self.map_expr(expr)
     }
 
-    fn visit_stmt(@mut self, stmt: @stmt, _: ()) {
+    fn visit_stmt(&mut self, stmt: @stmt, _: ()) {
         self.map_stmt(stmt)
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -281,56 +282,56 @@ fn visit_fn(@mut self,
         self.map_fn(function_kind, function_declaration, block, span, node_id)
     }
 
-    fn visit_block(@mut self, block: &Block, _: ()) {
+    fn visit_block(&mut self, block: &Block, _: ()) {
         self.map_block(block)
     }
 
     // XXX: Methods below can become default methods.
 
-    fn visit_mod(@mut self, module: &_mod, _: span, _: NodeId, _: ()) {
-        visit::visit_mod(self as @mut Visitor<()>, module, ())
+    fn visit_mod(&mut self, module: &_mod, _: span, _: NodeId, _: ()) {
+        visit::walk_mod(self, module, ())
     }
 
-    fn visit_view_item(@mut self, view_item: &view_item, _: ()) {
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, ())
+    fn visit_view_item(&mut self, view_item: &view_item, _: ()) {
+        visit::walk_view_item(self, view_item, ())
     }
 
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, _: ()) {
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, ())
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, _: ()) {
+        visit::walk_foreign_item(self, foreign_item, ())
     }
 
-    fn visit_local(@mut self, local: @Local, _: ()) {
-        visit::visit_local(self as @mut Visitor<()>, local, ())
+    fn visit_local(&mut self, local: @Local, _: ()) {
+        visit::walk_local(self, local, ())
     }
 
-    fn visit_arm(@mut self, arm: &arm, _: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, ())
+    fn visit_arm(&mut self, arm: &arm, _: ()) {
+        visit::walk_arm(self, arm, ())
     }
 
-    fn visit_decl(@mut self, decl: @decl, _: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, decl, ())
+    fn visit_decl(&mut self, decl: @decl, _: ()) {
+        visit::walk_decl(self, decl, ())
     }
 
-    fn visit_expr_post(@mut self, _: @expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &Ty, _: ()) {
-        visit::visit_ty(self as @mut Visitor<()>, typ, ())
+    fn visit_ty(&mut self, typ: &Ty, _: ()) {
+        visit::walk_ty(self, typ, ())
     }
 
-    fn visit_generics(@mut self, generics: &Generics, _: ()) {
-        visit::visit_generics(self as @mut Visitor<()>, generics, ())
+    fn visit_generics(&mut self, generics: &Generics, _: ()) {
+        visit::walk_generics(self, generics, ())
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
                 span: span,
                 node_id: NodeId,
                 _: ()) {
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -339,21 +340,21 @@ fn visit_fn(@mut self,
                         ())
     }
 
-    fn visit_ty_method(@mut self, ty_method: &TypeMethod, _: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, ty_method, ())
+    fn visit_ty_method(&mut self, ty_method: &TypeMethod, _: ()) {
+        visit::walk_ty_method(self, ty_method, ())
     }
 
-    fn visit_trait_method(@mut self, trait_method: &trait_method, _: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, ())
+    fn visit_trait_method(&mut self, trait_method: &trait_method, _: ()) {
+        visit::walk_trait_method(self, trait_method, ())
     }
 
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_def: @struct_def,
                         ident: ident,
                         generics: &Generics,
                         node_id: NodeId,
                         _: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_def,
                                 ident,
                                 generics,
@@ -361,8 +362,8 @@ fn visit_struct_def(@mut self,
                                 ())
     }
 
-    fn visit_struct_field(@mut self, struct_field: @struct_field, _: ()) {
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, ())
+    fn visit_struct_field(&mut self, struct_field: @struct_field, _: ()) {
+        visit::walk_struct_field(self, struct_field, ())
     }
 }
 
@@ -372,7 +373,7 @@ pub fn map_crate(diag: @mut span_handler, c: &Crate) -> map {
         path: ~[],
         diag: diag,
     };
-    visit::visit_crate(cx as @mut Visitor<()>, c, ());
+    visit::walk_crate(cx, c, ());
     cx.map
 }
 
@@ -409,7 +410,7 @@ pub fn map_decoded_item(diag: @mut span_handler,
     }
 
     // visit the item / method contents and add those to the map:
-    ii.accept((), cx as @mut Visitor<()>);
+    ii.accept((), cx);
 }
 
 pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
index 02eaf432b5402ba91b62217807ecd2a922cda2ee..cfbe61ca65e682726add25c8286f1b00c468e2ff 100644 (file)
@@ -298,7 +298,7 @@ pub fn struct_field_visibility(field: ast::struct_field) -> visibility {
 pub trait inlined_item_utils {
     fn ident(&self) -> ident;
     fn id(&self) -> ast::NodeId;
-    fn accept<E: Clone>(&self, e: E, v: @mut Visitor<E>);
+    fn accept<E: Clone, V:Visitor<E>>(&self, e: E, v: &mut V);
 }
 
 impl inlined_item_utils for inlined_item {
@@ -318,11 +318,11 @@ fn id(&self) -> ast::NodeId {
         }
     }
 
-    fn accept<E: Clone>(&self, e: E, v: @mut Visitor<E>) {
+    fn accept<E: Clone, V:Visitor<E>>(&self, e: E, v: &mut V) {
         match *self {
             ii_item(i) => v.visit_item(i, e),
             ii_foreign(i) => v.visit_foreign_item(i, e),
-            ii_method(_, _, m) => visit::visit_method_helper(v, m, e),
+            ii_method(_, _, m) => visit::walk_method_helper(v, m, e),
         }
     }
 }
@@ -390,14 +390,24 @@ pub fn add(&mut self, id: NodeId) {
     }
 }
 
-struct IdVisitor {
+pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
+                  -> @mut Visitor<()> {
+    let visitor = @mut IdVisitor {
+        visit_callback: vfn,
+        pass_through_items: pass_through_items,
+        visited_outermost: false,
+    };
+    visitor as @mut Visitor<()>
+}
+
+pub struct IdVisitor {
     visit_callback: @fn(NodeId),
     pass_through_items: bool,
     visited_outermost: bool,
 }
 
 impl IdVisitor {
-    fn visit_generics_helper(@mut self, generics: &Generics) {
+    fn visit_generics_helper(&self, generics: &Generics) {
         for type_parameter in generics.ty_params.iter() {
             (self.visit_callback)(type_parameter.id)
         }
@@ -408,16 +418,16 @@ fn visit_generics_helper(@mut self, generics: &Generics) {
 }
 
 impl Visitor<()> for IdVisitor {
-    fn visit_mod(@mut self,
+    fn visit_mod(&mut self,
                  module: &_mod,
                  _span: span,
                  node_id: NodeId,
                  env: ()) {
         (self.visit_callback)(node_id);
-        visit::visit_mod(self as @mut Visitor<()>, module, env)
+        visit::walk_mod(self, module, env)
     }
 
-    fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
+    fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         match view_item.node {
             view_item_extern_mod(_, _, _, node_id) => {
                 (self.visit_callback)(node_id)
@@ -439,15 +449,15 @@ fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
                 }
             }
         }
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, env)
+        visit::walk_view_item(self, view_item, env)
     }
 
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) {
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
         (self.visit_callback)(foreign_item.id);
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, env)
+        visit::walk_foreign_item(self, foreign_item, env)
     }
 
-    fn visit_item(@mut self, item: @item, env: ()) {
+    fn visit_item(&mut self, item: @item, env: ()) {
         if !self.pass_through_items {
             if self.visited_outermost {
                 return
@@ -466,42 +476,42 @@ fn visit_item(@mut self, item: @item, env: ()) {
             _ => {}
         }
 
-        visit::visit_item(self as @mut Visitor<()>, item, env);
+        visit::walk_item(self, item, env);
 
         self.visited_outermost = false
     }
 
-    fn visit_local(@mut self, local: @Local, env: ()) {
+    fn visit_local(&mut self, local: @Local, env: ()) {
         (self.visit_callback)(local.id);
-        visit::visit_local(self as @mut Visitor<()>, local, env)
+        visit::walk_local(self, local, env)
     }
 
-    fn visit_block(@mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: &Block, env: ()) {
         (self.visit_callback)(block.id);
-        visit::visit_block(self as @mut Visitor<()>, block, env)
+        visit::walk_block(self, block, env)
     }
 
-    fn visit_stmt(@mut self, statement: @stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: @stmt, env: ()) {
         (self.visit_callback)(ast_util::stmt_id(statement));
-        visit::visit_stmt(self as @mut Visitor<()>, statement, env)
+        visit::walk_stmt(self, statement, env)
     }
 
     // XXX: Default
-    fn visit_arm(@mut self, arm: &arm, env: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, env)
+    fn visit_arm(&mut self, arm: &arm, env: ()) {
+        visit::walk_arm(self, arm, env)
     }
 
-    fn visit_pat(@mut self, pattern: @pat, env: ()) {
+    fn visit_pat(&mut self, pattern: @pat, env: ()) {
         (self.visit_callback)(pattern.id);
-        visit::visit_pat(self as @mut Visitor<()>, pattern, env)
+        visit::walk_pat(self, pattern, env)
     }
 
     // XXX: Default
-    fn visit_decl(@mut self, declaration: @decl, env: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, declaration, env)
+    fn visit_decl(&mut self, declaration: @decl, env: ()) {
+        visit::walk_decl(self, declaration, env)
     }
 
-    fn visit_expr(@mut self, expression: @expr, env: ()) {
+    fn visit_expr(&mut self, expression: @expr, env: ()) {
         {
             let optional_callee_id = expression.get_callee_id();
             for callee_id in optional_callee_id.iter() {
@@ -509,29 +519,29 @@ fn visit_expr(@mut self, expression: @expr, env: ()) {
             }
         }
         (self.visit_callback)(expression.id);
-        visit::visit_expr(self as @mut Visitor<()>, expression, env)
+        visit::walk_expr(self, expression, env)
     }
 
     // XXX: Default
-    fn visit_expr_post(@mut self, _: @expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &Ty, env: ()) {
+    fn visit_ty(&mut self, typ: &Ty, env: ()) {
         (self.visit_callback)(typ.id);
         match typ.node {
             ty_path(_, _, id) => (self.visit_callback)(id),
             _ => {}
         }
-        visit::visit_ty(self as @mut Visitor<()>, typ, env)
+        visit::walk_ty(self, typ, env)
     }
 
-    fn visit_generics(@mut self, generics: &Generics, env: ()) {
+    fn visit_generics(&mut self, generics: &Generics, env: ()) {
         self.visit_generics_helper(generics);
-        visit::visit_generics(self as @mut Visitor<()>, generics, env)
+        visit::walk_generics(self, generics, env)
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -563,7 +573,7 @@ fn visit_fn(@mut self,
             (self.visit_callback)(argument.id)
         }
 
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -580,23 +590,23 @@ fn visit_fn(@mut self,
     }
 
     // XXX: Default
-    fn visit_ty_method(@mut self, type_method: &TypeMethod, env: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, type_method, env)
+    fn visit_ty_method(&mut self, type_method: &TypeMethod, env: ()) {
+        visit::walk_ty_method(self, type_method, env)
     }
 
     // XXX: Default
-    fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, env)
+    fn visit_trait_method(&mut self, trait_method: &trait_method, env: ()) {
+        visit::walk_trait_method(self, trait_method, env)
     }
 
     // XXX: Default
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_definition: @struct_def,
                         identifier: ident,
                         generics: &Generics,
                         node_id: NodeId,
                         env: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_definition,
                                 identifier,
                                 generics,
@@ -604,24 +614,19 @@ fn visit_struct_def(@mut self,
                                 env)
     }
 
-    fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) {
+    fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
         (self.visit_callback)(struct_field.node.id);
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, env)
+        visit::walk_struct_field(self, struct_field, env)
     }
 }
 
-pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
-                  -> @mut Visitor<()> {
-    let visitor = @mut IdVisitor {
+pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
+    let mut id_visitor = IdVisitor {
         visit_callback: vfn,
-        pass_through_items: pass_through_items,
+        pass_through_items: true,
         visited_outermost: false,
     };
-    visitor as @mut Visitor<()>
-}
-
-pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
-    item.accept((), id_visitor(|id| vfn(id), true));
+    item.accept((), &mut id_visitor);
 }
 
 pub fn compute_id_range(visit_ids_fn: &fn(@fn(NodeId))) -> id_range {
@@ -680,49 +685,49 @@ struct EachViewItemData {
 }
 
 impl SimpleVisitor for EachViewItemData {
-    fn visit_mod(@mut self, _: &_mod, _: span, _: NodeId) {
+    fn visit_mod(&mut self, _: &_mod, _: span, _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_view_item(@mut self, view_item: &view_item) {
+    fn visit_view_item(&mut self, view_item: &view_item) {
         let _ = (self.callback)(view_item);
     }
-    fn visit_foreign_item(@mut self, _: @foreign_item) {
+    fn visit_foreign_item(&mut self, _: @foreign_item) {
         // XXX: Default method.
     }
-    fn visit_item(@mut self, _: @item) {
+    fn visit_item(&mut self, _: @item) {
         // XXX: Default method.
     }
-    fn visit_local(@mut self, _: @Local) {
+    fn visit_local(&mut self, _: @Local) {
         // XXX: Default method.
     }
-    fn visit_block(@mut self, _: &Block) {
+    fn visit_block(&mut self, _: &Block) {
         // XXX: Default method.
     }
-    fn visit_stmt(@mut self, _: @stmt) {
+    fn visit_stmt(&mut self, _: @stmt) {
         // XXX: Default method.
     }
-    fn visit_arm(@mut self, _: &arm) {
+    fn visit_arm(&mut self, _: &arm) {
         // XXX: Default method.
     }
-    fn visit_pat(@mut self, _: @pat) {
+    fn visit_pat(&mut self, _: @pat) {
         // XXX: Default method.
     }
-    fn visit_decl(@mut self, _: @decl) {
+    fn visit_decl(&mut self, _: @decl) {
         // XXX: Default method.
     }
-    fn visit_expr(@mut self, _: @expr) {
+    fn visit_expr(&mut self, _: @expr) {
         // XXX: Default method.
     }
-    fn visit_expr_post(@mut self, _: @expr) {
+    fn visit_expr_post(&mut self, _: @expr) {
         // XXX: Default method.
     }
-    fn visit_ty(@mut self, _: &Ty) {
+    fn visit_ty(&mut self, _: &Ty) {
         // XXX: Default method.
     }
-    fn visit_generics(@mut self, _: &Generics) {
+    fn visit_generics(&mut self, _: &Generics) {
         // XXX: Default method.
     }
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 _: &visit::fn_kind,
                 _: &fn_decl,
                 _: &Block,
@@ -730,23 +735,23 @@ fn visit_fn(@mut self,
                 _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_ty_method(@mut self, _: &TypeMethod) {
+    fn visit_ty_method(&mut self, _: &TypeMethod) {
         // XXX: Default method.
     }
-    fn visit_trait_method(@mut self, _: &trait_method) {
+    fn visit_trait_method(&mut self, _: &trait_method) {
         // XXX: Default method.
     }
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         _: @struct_def,
                         _: ident,
                         _: &Generics,
                         _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_struct_field(@mut self, _: @struct_field) {
+    fn visit_struct_field(&mut self, _: @struct_field) {
         // XXX: Default method.
     }
-    fn visit_struct_method(@mut self, _: @method) {
+    fn visit_struct_method(&mut self, _: @method) {
         // XXX: Default method.
     }
 }
@@ -759,7 +764,7 @@ fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool {
         let visitor = @mut SimpleVisitorVisitor {
             simple_visitor: data as @mut SimpleVisitor,
         };
-        visit::visit_crate(visitor as @mut Visitor<()>, self, ());
+        visit::walk_crate(visitor, self, ());
         true
     }
 }
index c9e01b0f0d596d3ed1a41f645b9538d052641418..cb2d4f8ba2432b5ae0ec588087ebd84fcbd1af2f 100644 (file)
@@ -27,7 +27,7 @@ pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     let var = get_single_str_from_tts(ext_cx, sp, tts, "option_env!");
 
     let e = match os::getenv(var) {
-      None => quote_expr!(::std::option::None),
+      None => quote_expr!(::std::option::None::<&'static str>),
       Some(s) => quote_expr!(::std::option::Some($s))
     };
     MRExpr(e)
index 1547446957ed4a194da272b0d5c1a30ded60f57b..a4132e6c8793a5c550a7f3281c877ce49988a8f1 100644 (file)
@@ -522,7 +522,7 @@ struct NewNameFinderContext {
 }
 
 impl Visitor<()> for NewNameFinderContext {
-    fn visit_pat(@mut self, pattern: @ast::pat, _: ()) {
+    fn visit_pat(&mut self, pattern: @ast::pat, _: ()) {
         match *pattern {
             // we found a pat_ident!
             ast::pat {
@@ -548,74 +548,74 @@ fn visit_pat(@mut self, pattern: @ast::pat, _: ()) {
                 }
             }
             // use the default traversal for non-pat_idents
-            _ => visit::visit_pat(self as @mut Visitor<()>, pattern, ())
+            _ => visit::walk_pat(self, pattern, ())
         }
     }
 
     // XXX: Methods below can become default methods.
 
-    fn visit_mod(@mut self, module: &ast::_mod, _: span, _: NodeId, _: ()) {
-        visit::visit_mod(self as @mut Visitor<()>, module, ())
+    fn visit_mod(&mut self, module: &ast::_mod, _: span, _: NodeId, _: ()) {
+        visit::walk_mod(self, module, ())
     }
 
-    fn visit_view_item(@mut self, view_item: &ast::view_item, _: ()) {
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, ())
+    fn visit_view_item(&mut self, view_item: &ast::view_item, _: ()) {
+        visit::walk_view_item(self, view_item, ())
     }
 
-    fn visit_item(@mut self, item: @ast::item, _: ()) {
-        visit::visit_item(self as @mut Visitor<()>, item, ())
+    fn visit_item(&mut self, item: @ast::item, _: ()) {
+        visit::walk_item(self, item, ())
     }
 
-    fn visit_foreign_item(@mut self,
+    fn visit_foreign_item(&mut self,
                           foreign_item: @ast::foreign_item,
                           _: ()) {
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, ())
+        visit::walk_foreign_item(self, foreign_item, ())
     }
 
-    fn visit_local(@mut self, local: @ast::Local, _: ()) {
-        visit::visit_local(self as @mut Visitor<()>, local, ())
+    fn visit_local(&mut self, local: @ast::Local, _: ()) {
+        visit::walk_local(self, local, ())
     }
 
-    fn visit_block(@mut self, block: &ast::Block, _: ()) {
-        visit::visit_block(self as @mut Visitor<()>, block, ())
+    fn visit_block(&mut self, block: &ast::Block, _: ()) {
+        visit::walk_block(self, block, ())
     }
 
-    fn visit_stmt(@mut self, stmt: @ast::stmt, _: ()) {
-        visit::visit_stmt(self as @mut Visitor<()>, stmt, ())
+    fn visit_stmt(&mut self, stmt: @ast::stmt, _: ()) {
+        visit::walk_stmt(self, stmt, ())
     }
 
-    fn visit_arm(@mut self, arm: &ast::arm, _: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, ())
+    fn visit_arm(&mut self, arm: &ast::arm, _: ()) {
+        visit::walk_arm(self, arm, ())
     }
 
-    fn visit_decl(@mut self, decl: @ast::decl, _: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, decl, ())
+    fn visit_decl(&mut self, decl: @ast::decl, _: ()) {
+        visit::walk_decl(self, decl, ())
     }
 
-    fn visit_expr(@mut self, expr: @ast::expr, _: ()) {
-        visit::visit_expr(self as @mut Visitor<()>, expr, ())
+    fn visit_expr(&mut self, expr: @ast::expr, _: ()) {
+        visit::walk_expr(self, expr, ())
     }
 
-    fn visit_expr_post(@mut self, _: @ast::expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @ast::expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &ast::Ty, _: ()) {
-        visit::visit_ty(self as @mut Visitor<()>, typ, ())
+    fn visit_ty(&mut self, typ: &ast::Ty, _: ()) {
+        visit::walk_ty(self, typ, ())
     }
 
-    fn visit_generics(@mut self, generics: &ast::Generics, _: ()) {
-        visit::visit_generics(self as @mut Visitor<()>, generics, ())
+    fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
+        visit::walk_generics(self, generics, ())
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &ast::fn_decl,
                 block: &ast::Block,
                 span: span,
                 node_id: NodeId,
                 _: ()) {
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -624,23 +624,23 @@ fn visit_fn(@mut self,
                         ())
     }
 
-    fn visit_ty_method(@mut self, ty_method: &ast::TypeMethod, _: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, ty_method, ())
+    fn visit_ty_method(&mut self, ty_method: &ast::TypeMethod, _: ()) {
+        visit::walk_ty_method(self, ty_method, ())
     }
 
-    fn visit_trait_method(@mut self,
+    fn visit_trait_method(&mut self,
                           trait_method: &ast::trait_method,
                           _: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, ())
+        visit::walk_trait_method(self, trait_method, ())
     }
 
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_def: @ast::struct_def,
                         ident: ident,
                         generics: &ast::Generics,
                         node_id: NodeId,
                         _: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_def,
                                 ident,
                                 generics,
@@ -648,10 +648,10 @@ fn visit_struct_def(@mut self,
                                 ())
     }
 
-    fn visit_struct_field(@mut self,
+    fn visit_struct_field(&mut self,
                           struct_field: @ast::struct_field,
                           _: ()) {
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, ())
+        visit::walk_struct_field(self, struct_field, ())
     }
 }
 
@@ -957,6 +957,17 @@ macro_rules! printfln (
             println(fmt!($($arg),+))
         )
     )
+
+    // NOTE: use this after a snapshot lands to abstract the details
+    // of the TLS interface.
+    macro_rules! local_data_key (
+        ($name:ident: $ty:ty) => (
+            static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+        );
+        (pub $name:ident: $ty:ty) => (
+            pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+        )
+    )
 }";
 }
 
index 65d2f798f31dfe853fc58bc52501322a987a8819..6999f046b7b7aeeee3f4bd442e7e62f44439d6f8 100644 (file)
@@ -127,7 +127,13 @@ fn verify_piece(&mut self, p: &parse::Piece) {
                 }
             }
             parse::Argument(ref arg) => {
-                // argument first (it's first in the format string)
+                // width/precision first, if they have implicit positional
+                // parameters it makes more sense to consume them first.
+                self.verify_count(arg.format.width);
+                self.verify_count(arg.format.precision);
+
+                // argument second, if it's an implicit positional parameter
+                // it's written second, so it should come after width/precision.
                 let pos = match arg.position {
                     parse::ArgumentNext => {
                         let i = self.next_arg;
@@ -144,10 +150,6 @@ fn verify_piece(&mut self, p: &parse::Piece) {
                 } else { Known(arg.format.ty.to_managed()) };
                 self.verify_arg_type(pos, ty);
 
-                // width/precision next
-                self.verify_count(arg.format.width);
-                self.verify_count(arg.format.precision);
-
                 // and finally the method being applied
                 match arg.method {
                     None => {}
@@ -315,6 +317,10 @@ fn verify_same(&self, sp: span, ty: ArgumentType,
     /// Translate a `parse::Piece` to a static `rt::Piece`
     fn trans_piece(&mut self, piece: &parse::Piece) -> @ast::expr {
         let sp = self.fmtsp;
+        let parsepath = |s: &str| {
+            ~[self.ecx.ident_of("std"), self.ecx.ident_of("fmt"),
+              self.ecx.ident_of("parse"), self.ecx.ident_of(s)]
+        };
         let rtpath = |s: &str| {
             ~[self.ecx.ident_of("std"), self.ecx.ident_of("fmt"),
               self.ecx.ident_of("rt"), self.ecx.ident_of(s)]
@@ -480,20 +486,24 @@ fn trans_piece(&mut self, piece: &parse::Piece) -> @ast::expr {
                 let fill = self.ecx.expr_lit(sp, ast::lit_int(fill as i64,
                                                               ast::ty_char));
                 let align = match arg.format.align {
-                    None | Some(parse::AlignLeft) => {
-                        self.ecx.expr_bool(sp, true)
+                    parse::AlignLeft => {
+                        self.ecx.path_global(sp, parsepath("AlignLeft"))
                     }
-                    Some(parse::AlignRight) => {
-                        self.ecx.expr_bool(sp, false)
+                    parse::AlignRight => {
+                        self.ecx.path_global(sp, parsepath("AlignRight"))
+                    }
+                    parse::AlignUnknown => {
+                        self.ecx.path_global(sp, parsepath("AlignUnknown"))
                     }
                 };
+                let align = self.ecx.expr_path(align);
                 let flags = self.ecx.expr_uint(sp, arg.format.flags);
                 let prec = trans_count(arg.format.precision);
                 let width = trans_count(arg.format.width);
                 let path = self.ecx.path_global(sp, rtpath("FormatSpec"));
                 let fmt = self.ecx.expr_struct(sp, path, ~[
                     self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
-                    self.ecx.field_imm(sp, self.ecx.ident_of("alignleft"), align),
+                    self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
                     self.ecx.field_imm(sp, self.ecx.ident_of("flags"), flags),
                     self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec),
                     self.ecx.field_imm(sp, self.ecx.ident_of("width"), width),
@@ -627,15 +637,17 @@ fn format_arg(&self, sp: span, arg: Either<uint, @str>,
             Known(tyname) => {
                 let fmt_trait = match tyname.as_slice() {
                     "?" => "Poly",
-                    "d" | "i" => "Signed",
-                    "u" => "Unsigned",
                     "b" => "Bool",
                     "c" => "Char",
+                    "d" | "i" => "Signed",
+                    "f" => "Float",
                     "o" => "Octal",
+                    "p" => "Pointer",
+                    "s" => "String",
+                    "t" => "Binary",
+                    "u" => "Unsigned",
                     "x" => "LowerHex",
                     "X" => "UpperHex",
-                    "s" => "String",
-                    "p" => "Pointer",
                     _ => {
                         self.ecx.span_err(sp, fmt!("unknown format trait \
                                                     `%s`", tyname));
index b38de31c56a7ff8117836a1bf5ea5f6a9001021e..a2664dcf890ad3b3a44d035c05399b291e8c7dc6 100644 (file)
@@ -3445,7 +3445,7 @@ pub fn parse_fn_decl(&self) -> fn_decl {
                 |p| p.parse_arg()
             );
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
 
         let (ret_style, ret_ty) = self.parse_ret_ty();
         ast::fn_decl {
@@ -3608,7 +3608,7 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
 
         let hi = self.span.hi;
 
-        let inputs = either::lefts(args_or_capture_items);
+        let inputs = either::lefts(args_or_capture_items.move_iter()).collect();
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
         let fn_decl = ast::fn_decl {
@@ -3641,7 +3641,7 @@ fn parse_fn_block_decl(&self) -> fn_decl {
         };
 
         ast::fn_decl {
-            inputs: either::lefts(inputs_captures),
+            inputs: either::lefts(inputs_captures.move_iter()).collect(),
             output: output,
             cf: return_val,
         }
index c3a5ba7116d9197cd9a207aded1c286829e045cd..8178e7f3760b723e49df1a5e07ca06ff00de8efc 100644 (file)
@@ -66,33 +66,97 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics {
     }
 }
 
-pub trait Visitor<E> {
-    fn visit_mod(@mut self, &_mod, span, NodeId, E);
-    fn visit_view_item(@mut self, &view_item, E);
-    fn visit_foreign_item(@mut self, @foreign_item, E);
-    fn visit_item(@mut self, @item, E);
-    fn visit_local(@mut self, @Local, E);
-    fn visit_block(@mut self, &Block, E);
-    fn visit_stmt(@mut self, @stmt, E);
-    fn visit_arm(@mut self, &arm, E);
-    fn visit_pat(@mut self, @pat, E);
-    fn visit_decl(@mut self, @decl, E);
-    fn visit_expr(@mut self, @expr, E);
-    fn visit_expr_post(@mut self, @expr, E);
-    fn visit_ty(@mut self, &Ty, E);
-    fn visit_generics(@mut self, &Generics, E);
-    fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId, E);
-    fn visit_ty_method(@mut self, &TypeMethod, E);
-    fn visit_trait_method(@mut self, &trait_method, E);
-    fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId, E);
-    fn visit_struct_field(@mut self, @struct_field, E);
-}
-
-pub fn visit_crate<E:Clone>(visitor: @mut Visitor<E>, crate: &Crate, env: E) {
+pub trait Visitor<E:Clone> {
+    fn visit_mod(&mut self, m:&_mod, _s:span, _n:NodeId, e:E) { walk_mod(self, m, e) }
+    fn visit_view_item(&mut self, i:&view_item, e:E) { walk_view_item(self, i, e) }
+    fn visit_foreign_item(&mut self, i:@foreign_item, e:E) { walk_foreign_item(self, i, e) }
+    fn visit_item(&mut self, i:@item, e:E) { walk_item(self, i, e) }
+    fn visit_local(&mut self, l:@Local, e:E) { walk_local(self, l, e) }
+    fn visit_block(&mut self, b:&Block, e:E) { walk_block(self, b, e) }
+    fn visit_stmt(&mut self, s:@stmt, e:E) { walk_stmt(self, s, e) }
+    fn visit_arm(&mut self, a:&arm, e:E) { walk_arm(self, a, e) }
+    fn visit_pat(&mut self, p:@pat, e:E) { walk_pat(self, p, e) }
+    fn visit_decl(&mut self, d:@decl, e:E) { walk_decl(self, d, e) }
+    fn visit_expr(&mut self, ex:@expr, e:E) { walk_expr(self, ex, e) }
+    fn visit_expr_post(&mut self, _ex:@expr, _e:E) { }
+    fn visit_ty(&mut self, _t:&Ty, _e:E) { }
+    fn visit_generics(&mut self, g:&Generics, e:E) { walk_generics(self, g, e) }
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:span, n:NodeId, e:E) {
+        walk_fn(self, fk, fd, b, s, n , e)
+    }
+    fn visit_ty_method(&mut self, t:&TypeMethod, e:E) { walk_ty_method(self, t, e) }
+    fn visit_trait_method(&mut self, t:&trait_method, e:E) { walk_trait_method(self, t, e) }
+    fn visit_struct_def(&mut self, s:@struct_def, i:ident, g:&Generics, n:NodeId, e:E) {
+        walk_struct_def(self, s, i, g, n, e)
+    }
+    fn visit_struct_field(&mut self, s:@struct_field, e:E) { walk_struct_field(self, s, e) }
+}
+
+impl<E:Clone> Visitor<E> for @mut Visitor<E> {
+    fn visit_mod(&mut self, a:&_mod, b:span, c:NodeId, e:E) {
+        (*self).visit_mod(a, b, c, e)
+    }
+    fn visit_view_item(&mut self, a:&view_item, e:E) {
+        (*self).visit_view_item(a, e)
+    }
+    fn visit_foreign_item(&mut self, a:@foreign_item, e:E) {
+        (*self).visit_foreign_item(a, e)
+    }
+    fn visit_item(&mut self, a:@item, e:E) {
+        (*self).visit_item(a, e)
+    }
+    fn visit_local(&mut self, a:@Local, e:E) {
+        (*self).visit_local(a, e)
+    }
+    fn visit_block(&mut self, a:&Block, e:E) {
+        (*self).visit_block(a, e)
+    }
+    fn visit_stmt(&mut self, a:@stmt, e:E) {
+        (*self).visit_stmt(a, e)
+    }
+    fn visit_arm(&mut self, a:&arm, e:E) {
+        (*self).visit_arm(a, e)
+    }
+    fn visit_pat(&mut self, a:@pat, e:E) {
+        (*self).visit_pat(a, e)
+    }
+    fn visit_decl(&mut self, a:@decl, e:E) {
+        (*self).visit_decl(a, e)
+    }
+    fn visit_expr(&mut self, a:@expr, e:E) {
+        (*self).visit_expr(a, e)
+    }
+    fn visit_expr_post(&mut self, a:@expr, e:E) {
+        (*self).visit_expr_post(a, e)
+    }
+    fn visit_ty(&mut self, a:&Ty, e:E) {
+        (*self).visit_ty(a, e)
+    }
+    fn visit_generics(&mut self, a:&Generics, e:E) {
+        (*self).visit_generics(a, e)
+    }
+    fn visit_fn(&mut self, a:&fn_kind, b:&fn_decl, c:&Block, d:span, f:NodeId, e:E) {
+        (*self).visit_fn(a, b, c, d, f, e)
+    }
+    fn visit_ty_method(&mut self, a:&TypeMethod, e:E) {
+        (*self).visit_ty_method(a, e)
+    }
+    fn visit_trait_method(&mut self, a:&trait_method, e:E) {
+        (*self).visit_trait_method(a, e)
+    }
+    fn visit_struct_def(&mut self, a:@struct_def, b:ident, c:&Generics, d:NodeId, e:E) {
+        (*self).visit_struct_def(a, b, c, d, e)
+    }
+    fn visit_struct_field(&mut self, a:@struct_field, e:E) {
+        (*self).visit_struct_field(a, e)
+    }
+}
+
+pub fn walk_crate<E:Clone, V:Visitor<E>>(visitor: &mut V, crate: &Crate, env: E) {
     visitor.visit_mod(&crate.module, crate.span, CRATE_NODE_ID, env)
 }
 
-pub fn visit_mod<E:Clone>(visitor: @mut Visitor<E>, module: &_mod, env: E) {
+pub fn walk_mod<E:Clone, V:Visitor<E>>(visitor: &mut V, module: &_mod, env: E) {
     for view_item in module.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
@@ -101,11 +165,11 @@ pub fn visit_mod<E:Clone>(visitor: @mut Visitor<E>, module: &_mod, env: E) {
     }
 }
 
-pub fn visit_view_item<E:Clone>(_: @mut Visitor<E>, _: &view_item, _: E) {
+pub fn walk_view_item<E:Clone, V:Visitor<E>>(_: &mut V, _: &view_item, _: E) {
     // Empty!
 }
 
-pub fn visit_local<E:Clone>(visitor: @mut Visitor<E>, local: &Local, env: E) {
+pub fn walk_local<E:Clone, V:Visitor<E>>(visitor: &mut V, local: &Local, env: E) {
     visitor.visit_pat(local.pat, env.clone());
     visitor.visit_ty(&local.ty, env.clone());
     match local.init {
@@ -114,13 +178,13 @@ pub fn visit_local<E:Clone>(visitor: @mut Visitor<E>, local: &Local, env: E) {
     }
 }
 
-fn visit_trait_ref<E:Clone>(visitor: @mut Visitor<E>,
+fn walk_trait_ref<E:Clone, V:Visitor<E>>(visitor: &mut V,
                             trait_ref: &ast::trait_ref,
                             env: E) {
-    visit_path(visitor, &trait_ref.path, env)
+    walk_path(visitor, &trait_ref.path, env)
 }
 
-pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
+pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
     match item.node {
         item_static(ref typ, _, expr) => {
             visitor.visit_ty(typ, env.clone());
@@ -151,7 +215,7 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
         }
         item_enum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters, env.clone());
-            visit_enum_def(visitor, enum_definition, type_parameters, env)
+            walk_enum_def(visitor, enum_definition, type_parameters, env)
         }
         item_impl(ref type_parameters,
                   ref trait_references,
@@ -159,11 +223,11 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
                   ref methods) => {
             visitor.visit_generics(type_parameters, env.clone());
             for trait_reference in trait_references.iter() {
-                visit_trait_ref(visitor, trait_reference, env.clone())
+                walk_trait_ref(visitor, trait_reference, env.clone())
             }
             visitor.visit_ty(typ, env.clone());
             for method in methods.iter() {
-                visit_method_helper(visitor, *method, env.clone())
+                walk_method_helper(visitor, *method, env.clone())
             }
         }
         item_struct(struct_definition, ref generics) => {
@@ -177,17 +241,17 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
         item_trait(ref generics, ref trait_paths, ref methods) => {
             visitor.visit_generics(generics, env.clone());
             for trait_path in trait_paths.iter() {
-                visit_path(visitor, &trait_path.path, env.clone())
+                walk_path(visitor, &trait_path.path, env.clone())
             }
             for method in methods.iter() {
                 visitor.visit_trait_method(method, env.clone())
             }
         }
-        item_mac(ref macro) => visit_mac(visitor, macro, env),
+        item_mac(ref macro) => walk_mac(visitor, macro, env),
     }
 }
 
-pub fn visit_enum_def<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_enum_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                enum_definition: &ast::enum_def,
                                generics: &Generics,
                                env: E) {
@@ -209,11 +273,11 @@ pub fn visit_enum_def<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn skip_ty<E>(_: @mut Visitor<E>, _: &Ty, _: E) {
+pub fn skip_ty<E, V:Visitor<E>>(_: &mut V, _: &Ty, _: E) {
     // Empty!
 }
 
-pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
+pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     match typ.node {
         ty_box(ref mutable_type) | ty_uniq(ref mutable_type) |
         ty_vec(ref mutable_type) | ty_ptr(ref mutable_type) |
@@ -231,7 +295,7 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
              }
              visitor.visit_ty(&function_declaration.decl.output, env.clone());
              for bounds in function_declaration.bounds.iter() {
-                visit_ty_param_bounds(visitor, bounds, env.clone())
+                walk_ty_param_bounds(visitor, bounds, env.clone())
              }
         }
         ty_bare_fn(ref function_declaration) => {
@@ -241,9 +305,9 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
             visitor.visit_ty(&function_declaration.decl.output, env.clone())
         }
         ty_path(ref path, ref bounds, _) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for bounds in bounds.iter() {
-                visit_ty_param_bounds(visitor, bounds, env.clone())
+                walk_ty_param_bounds(visitor, bounds, env.clone())
             }
         }
         ty_fixed_length_vec(ref mutable_type, expression) => {
@@ -254,16 +318,16 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
     }
 }
 
-pub fn visit_path<E:Clone>(visitor: @mut Visitor<E>, path: &Path, env: E) {
+pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     for typ in path.types.iter() {
         visitor.visit_ty(typ, env.clone())
     }
 }
 
-pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
+pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &pat, env: E) {
     match pattern.node {
         pat_enum(ref path, ref children) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for children in children.iter() {
                 for child in children.iter() {
                     visitor.visit_pat(*child, env.clone())
@@ -271,7 +335,7 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
             }
         }
         pat_struct(ref path, ref fields, _) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for field in fields.iter() {
                 visitor.visit_pat(field.pat, env.clone())
             }
@@ -287,7 +351,7 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
             visitor.visit_pat(subpattern, env)
         }
         pat_ident(_, ref path, ref optional_subpattern) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             match *optional_subpattern {
                 None => {}
                 Some(subpattern) => visitor.visit_pat(subpattern, env),
@@ -313,40 +377,40 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
     }
 }
 
-pub fn visit_foreign_item<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_foreign_item<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    foreign_item: &foreign_item,
                                    env: E) {
     match foreign_item.node {
         foreign_item_fn(ref function_declaration, ref generics) => {
-            visit_fn_decl(visitor, function_declaration, env.clone());
+            walk_fn_decl(visitor, function_declaration, env.clone());
             visitor.visit_generics(generics, env)
         }
         foreign_item_static(ref typ, _) => visitor.visit_ty(typ, env),
     }
 }
 
-pub fn visit_ty_param_bounds<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_ty_param_bounds<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                       bounds: &OptVec<TyParamBound>,
                                       env: E) {
     for bound in bounds.iter() {
         match *bound {
             TraitTyParamBound(ref typ) => {
-                visit_trait_ref(visitor, typ, env.clone())
+                walk_trait_ref(visitor, typ, env.clone())
             }
             RegionTyParamBound => {}
         }
     }
 }
 
-pub fn visit_generics<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_generics<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                generics: &Generics,
                                env: E) {
     for type_parameter in generics.ty_params.iter() {
-        visit_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
+        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
     }
 }
 
-pub fn visit_fn_decl<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
                               function_declaration: &fn_decl,
                               env: E) {
     for argument in function_declaration.inputs.iter() {
@@ -360,7 +424,7 @@ pub fn visit_fn_decl<E:Clone>(visitor: @mut Visitor<E>,
 // visit_fn() and check for fk_method().  I named this visit_method_helper()
 // because it is not a default impl of any method, though I doubt that really
 // clarifies anything. - Niko
-pub fn visit_method_helper<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                     method: &method,
                                     env: E) {
     visitor.visit_fn(&fk_method(method.ident, &method.generics, method),
@@ -371,20 +435,20 @@ pub fn visit_method_helper<E:Clone>(visitor: @mut Visitor<E>,
                      env)
 }
 
-pub fn visit_fn<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          function_kind: &fn_kind,
                          function_declaration: &fn_decl,
                          function_body: &Block,
                          _: span,
                          _: NodeId,
                          env: E) {
-    visit_fn_decl(visitor, function_declaration, env.clone());
+    walk_fn_decl(visitor, function_declaration, env.clone());
     let generics = generics_of_fn(function_kind);
     visitor.visit_generics(&generics, env.clone());
     visitor.visit_block(function_body, env)
 }
 
-pub fn visit_ty_method<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                 method_type: &TypeMethod,
                                 env: E) {
     for argument_type in method_type.decl.inputs.iter() {
@@ -394,18 +458,18 @@ pub fn visit_ty_method<E:Clone>(visitor: @mut Visitor<E>,
     visitor.visit_ty(&method_type.decl.output, env.clone())
 }
 
-pub fn visit_trait_method<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_trait_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    trait_method: &trait_method,
                                    env: E) {
     match *trait_method {
         required(ref method_type) => {
             visitor.visit_ty_method(method_type, env)
         }
-        provided(method) => visit_method_helper(visitor, method, env),
+        provided(method) => walk_method_helper(visitor, method, env),
     }
 }
 
-pub fn visit_struct_def<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_struct_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                  struct_definition: @struct_def,
                                  _: ast::ident,
                                  _: &Generics,
@@ -416,40 +480,40 @@ pub fn visit_struct_def<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_struct_field<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_struct_field<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    struct_field: &struct_field,
                                    env: E) {
     visitor.visit_ty(&struct_field.node.ty, env)
 }
 
-pub fn visit_block<E:Clone>(visitor: @mut Visitor<E>, block: &Block, env: E) {
+pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: &Block, env: E) {
     for view_item in block.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
     for statement in block.stmts.iter() {
         visitor.visit_stmt(*statement, env.clone())
     }
-    visit_expr_opt(visitor, block.expr, env)
+    walk_expr_opt(visitor, block.expr, env)
 }
 
-pub fn visit_stmt<E>(visitor: @mut Visitor<E>, statement: &stmt, env: E) {
+pub fn walk_stmt<E:Clone, V:Visitor<E>>(visitor: &mut V, statement: &stmt, env: E) {
     match statement.node {
         stmt_decl(declaration, _) => visitor.visit_decl(declaration, env),
         stmt_expr(expression, _) | stmt_semi(expression, _) => {
             visitor.visit_expr(expression, env)
         }
-        stmt_mac(ref macro, _) => visit_mac(visitor, macro, env),
+        stmt_mac(ref macro, _) => walk_mac(visitor, macro, env),
     }
 }
 
-pub fn visit_decl<E:Clone>(visitor: @mut Visitor<E>, declaration: &decl, env: E) {
+pub fn walk_decl<E:Clone, V:Visitor<E>>(visitor: &mut V, declaration: &decl, env: E) {
     match declaration.node {
         decl_local(ref local) => visitor.visit_local(*local, env),
         decl_item(item) => visitor.visit_item(item, env),
     }
 }
 
-pub fn visit_expr_opt<E>(visitor: @mut Visitor<E>,
+pub fn walk_expr_opt<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          optional_expression: Option<@expr>,
                          env: E) {
     match optional_expression {
@@ -458,7 +522,7 @@ pub fn visit_expr_opt<E>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_exprs<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_exprs<E:Clone, V:Visitor<E>>(visitor: &mut V,
                             expressions: &[@expr],
                             env: E) {
     for expression in expressions.iter() {
@@ -466,28 +530,28 @@ pub fn visit_exprs<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_mac<E>(_: @mut Visitor<E>, _: &mac, _: E) {
+pub fn walk_mac<E, V:Visitor<E>>(_: &mut V, _: &mac, _: E) {
     // Empty!
 }
 
-pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E) {
+pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @expr, env: E) {
     match expression.node {
         expr_vstore(subexpression, _) => {
             visitor.visit_expr(subexpression, env.clone())
         }
         expr_vec(ref subexpressions, _) => {
-            visit_exprs(visitor, *subexpressions, env.clone())
+            walk_exprs(visitor, *subexpressions, env.clone())
         }
         expr_repeat(element, count, _) => {
             visitor.visit_expr(element, env.clone());
             visitor.visit_expr(count, env.clone())
         }
         expr_struct(ref path, ref fields, optional_base) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for field in fields.iter() {
                 visitor.visit_expr(field.expr, env.clone())
             }
-            visit_expr_opt(visitor, optional_base, env.clone())
+            walk_expr_opt(visitor, optional_base, env.clone())
         }
         expr_tup(ref subexpressions) => {
             for subexpression in subexpressions.iter() {
@@ -501,7 +565,7 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
             visitor.visit_expr(callee_expression, env.clone())
         }
         expr_method_call(_, callee, _, ref types, ref arguments, _) => {
-            visit_exprs(visitor, *arguments, env.clone());
+            walk_exprs(visitor, *arguments, env.clone());
             for typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
@@ -524,7 +588,7 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
         expr_if(head_expression, ref if_block, optional_else) => {
             visitor.visit_expr(head_expression, env.clone());
             visitor.visit_block(if_block, env.clone());
-            visit_expr_opt(visitor, optional_else, env.clone())
+            walk_expr_opt(visitor, optional_else, env.clone())
         }
         expr_while(subexpression, ref block) => {
             visitor.visit_expr(subexpression, env.clone());
@@ -569,16 +633,16 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
             visitor.visit_expr(main_expression, env.clone());
             visitor.visit_expr(index_expression, env.clone())
         }
-        expr_path(ref path) => visit_path(visitor, path, env.clone()),
+        expr_path(ref path) => walk_path(visitor, path, env.clone()),
         expr_self | expr_break(_) | expr_again(_) => {}
         expr_ret(optional_expression) => {
-            visit_expr_opt(visitor, optional_expression, env.clone())
+            walk_expr_opt(visitor, optional_expression, env.clone())
         }
         expr_log(level, subexpression) => {
             visitor.visit_expr(level, env.clone());
             visitor.visit_expr(subexpression, env.clone());
         }
-        expr_mac(ref macro) => visit_mac(visitor, macro, env.clone()),
+        expr_mac(ref macro) => walk_mac(visitor, macro, env.clone()),
         expr_paren(subexpression) => {
             visitor.visit_expr(subexpression, env.clone())
         }
@@ -595,11 +659,11 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
     visitor.visit_expr_post(expression, env.clone())
 }
 
-pub fn visit_arm<E:Clone>(visitor: @mut Visitor<E>, arm: &arm, env: E) {
+pub fn walk_arm<E:Clone, V:Visitor<E>>(visitor: &mut V, arm: &arm, env: E) {
     for pattern in arm.pats.iter() {
         visitor.visit_pat(*pattern, env.clone())
     }
-    visit_expr_opt(visitor, arm.guard, env.clone());
+    walk_expr_opt(visitor, arm.guard, env.clone());
     visitor.visit_block(&arm.body, env)
 }
 
@@ -607,26 +671,26 @@ pub fn visit_arm<E:Clone>(visitor: @mut Visitor<E>, arm: &arm, env: E) {
 // calls the given functions on the nodes.
 
 pub trait SimpleVisitor {
-    fn visit_mod(@mut self, &_mod, span, NodeId);
-    fn visit_view_item(@mut self, &view_item);
-    fn visit_foreign_item(@mut self, @foreign_item);
-    fn visit_item(@mut self, @item);
-    fn visit_local(@mut self, @Local);
-    fn visit_block(@mut self, &Block);
-    fn visit_stmt(@mut self, @stmt);
-    fn visit_arm(@mut self, &arm);
-    fn visit_pat(@mut self, @pat);
-    fn visit_decl(@mut self, @decl);
-    fn visit_expr(@mut self, @expr);
-    fn visit_expr_post(@mut self, @expr);
-    fn visit_ty(@mut self, &Ty);
-    fn visit_generics(@mut self, &Generics);
-    fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId);
-    fn visit_ty_method(@mut self, &TypeMethod);
-    fn visit_trait_method(@mut self, &trait_method);
-    fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId);
-    fn visit_struct_field(@mut self, @struct_field);
-    fn visit_struct_method(@mut self, @method);
+    fn visit_mod(&mut self, &_mod, span, NodeId);
+    fn visit_view_item(&mut self, &view_item);
+    fn visit_foreign_item(&mut self, @foreign_item);
+    fn visit_item(&mut self, @item);
+    fn visit_local(&mut self, @Local);
+    fn visit_block(&mut self, &Block);
+    fn visit_stmt(&mut self, @stmt);
+    fn visit_arm(&mut self, &arm);
+    fn visit_pat(&mut self, @pat);
+    fn visit_decl(&mut self, @decl);
+    fn visit_expr(&mut self, @expr);
+    fn visit_expr_post(&mut self, @expr);
+    fn visit_ty(&mut self, &Ty);
+    fn visit_generics(&mut self, &Generics);
+    fn visit_fn(&mut self, &fn_kind, &fn_decl, &Block, span, NodeId);
+    fn visit_ty_method(&mut self, &TypeMethod);
+    fn visit_trait_method(&mut self, &trait_method);
+    fn visit_struct_def(&mut self, @struct_def, ident, &Generics, NodeId);
+    fn visit_struct_field(&mut self, @struct_field);
+    fn visit_struct_method(&mut self, @method);
 }
 
 pub struct SimpleVisitorVisitor {
@@ -634,66 +698,66 @@ pub struct SimpleVisitorVisitor {
 }
 
 impl Visitor<()> for SimpleVisitorVisitor {
-    fn visit_mod(@mut self,
+    fn visit_mod(&mut self,
                  module: &_mod,
                  span: span,
                  node_id: NodeId,
                  env: ()) {
         self.simple_visitor.visit_mod(module, span, node_id);
-        visit_mod(self as @mut Visitor<()>, module, env)
+        walk_mod(self, module, env)
     }
-    fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
+    fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         self.simple_visitor.visit_view_item(view_item);
-        visit_view_item(self as @mut Visitor<()>, view_item, env)
+        walk_view_item(self, view_item, env)
     }
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) {
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
         self.simple_visitor.visit_foreign_item(foreign_item);
-        visit_foreign_item(self as @mut Visitor<()>, foreign_item, env)
+        walk_foreign_item(self, foreign_item, env)
     }
-    fn visit_item(@mut self, item: @item, env: ()) {
+    fn visit_item(&mut self, item: @item, env: ()) {
         self.simple_visitor.visit_item(item);
-        visit_item(self as @mut Visitor<()>, item, env)
+        walk_item(self, item, env)
     }
-    fn visit_local(@mut self, local: @Local, env: ()) {
+    fn visit_local(&mut self, local: @Local, env: ()) {
         self.simple_visitor.visit_local(local);
-        visit_local(self as @mut Visitor<()>, local, env)
+        walk_local(self, local, env)
     }
-    fn visit_block(@mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: &Block, env: ()) {
         self.simple_visitor.visit_block(block);
-        visit_block(self as @mut Visitor<()>, block, env)
+        walk_block(self, block, env)
     }
-    fn visit_stmt(@mut self, statement: @stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: @stmt, env: ()) {
         self.simple_visitor.visit_stmt(statement);
-        visit_stmt(self as @mut Visitor<()>, statement, env)
+        walk_stmt(self, statement, env)
     }
-    fn visit_arm(@mut self, arm: &arm, env: ()) {
+    fn visit_arm(&mut self, arm: &arm, env: ()) {
         self.simple_visitor.visit_arm(arm);
-        visit_arm(self as @mut Visitor<()>, arm, env)
+        walk_arm(self, arm, env)
     }
-    fn visit_pat(@mut self, pattern: @pat, env: ()) {
+    fn visit_pat(&mut self, pattern: @pat, env: ()) {
         self.simple_visitor.visit_pat(pattern);
-        visit_pat(self as @mut Visitor<()>, pattern, env)
+        walk_pat(self, pattern, env)
     }
-    fn visit_decl(@mut self, declaration: @decl, env: ()) {
+    fn visit_decl(&mut self, declaration: @decl, env: ()) {
         self.simple_visitor.visit_decl(declaration);
-        visit_decl(self as @mut Visitor<()>, declaration, env)
+        walk_decl(self, declaration, env)
     }
-    fn visit_expr(@mut self, expression: @expr, env: ()) {
+    fn visit_expr(&mut self, expression: @expr, env: ()) {
         self.simple_visitor.visit_expr(expression);
-        visit_expr(self as @mut Visitor<()>, expression, env)
+        walk_expr(self, expression, env)
     }
-    fn visit_expr_post(@mut self, expression: @expr, _: ()) {
+    fn visit_expr_post(&mut self, expression: @expr, _: ()) {
         self.simple_visitor.visit_expr_post(expression)
     }
-    fn visit_ty(@mut self, typ: &Ty, env: ()) {
+    fn visit_ty(&mut self, typ: &Ty, env: ()) {
         self.simple_visitor.visit_ty(typ);
-        visit_ty(self as @mut Visitor<()>, typ, env)
+        walk_ty(self, typ, env)
     }
-    fn visit_generics(@mut self, generics: &Generics, env: ()) {
+    fn visit_generics(&mut self, generics: &Generics, env: ()) {
         self.simple_visitor.visit_generics(generics);
-        visit_generics(self as @mut Visitor<()>, generics, env)
+        walk_generics(self, generics, env)
     }
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -705,7 +769,7 @@ fn visit_fn(@mut self,
                                      block,
                                      span,
                                      node_id);
-        visit_fn(self as @mut Visitor<()>,
+        walk_fn(self,
                  function_kind,
                  function_declaration,
                  block,
@@ -713,15 +777,15 @@ fn visit_fn(@mut self,
                  node_id,
                  env)
     }
-    fn visit_ty_method(@mut self, method_type: &TypeMethod, env: ()) {
+    fn visit_ty_method(&mut self, method_type: &TypeMethod, env: ()) {
         self.simple_visitor.visit_ty_method(method_type);
-        visit_ty_method(self as @mut Visitor<()>, method_type, env)
+        walk_ty_method(self, method_type, env)
     }
-    fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) {
+    fn visit_trait_method(&mut self, trait_method: &trait_method, env: ()) {
         self.simple_visitor.visit_trait_method(trait_method);
-        visit_trait_method(self as @mut Visitor<()>, trait_method, env)
+        walk_trait_method(self, trait_method, env)
     }
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_definition: @struct_def,
                         identifier: ident,
                         generics: &Generics,
@@ -731,16 +795,16 @@ fn visit_struct_def(@mut self,
                                              identifier,
                                              generics,
                                              node_id);
-        visit_struct_def(self as @mut Visitor<()>,
+        walk_struct_def(self,
                          struct_definition,
                          identifier,
                          generics,
                          node_id,
                          env)
     }
-    fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) {
+    fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
         self.simple_visitor.visit_struct_field(struct_field);
-        visit_struct_field(self as @mut Visitor<()>, struct_field, env)
+        walk_struct_field(self, struct_field, env)
     }
 }
 
index 987434b424e9cea4a4bfa2b1e552d88114f06c6a..ad170d9173f71b6909fcecd0713a8b209cec546d 100644 (file)
@@ -1,3 +1,11 @@
+S 2013-08-14 e7b5729
+  freebsd-x86_64 9de0b5583a5c4413f9e77df7071498385e936dd2
+  linux-i386 29119a9072f74c639c2bad998edc40e582da540e
+  linux-x86_64 319fb73727da9a8e4dd6debe37e7647e40ed361b
+  macos-i386 f74a0f02efec35e327a9c819c5c8347579d1b7fe
+  macos-x86_64 f44aba76e9d7a9a28b8a6dd78f14576e7c84fbf3
+  winnt-i386 49dd1f264e17e6cd929c827ccbe23ee09058c7fc
+
 S 2013-08-12 ecfc9a8
   freebsd-x86_64 ae903580d6328b8517dc64b013c1b0740bfa4e83
   linux-i386 3076bf032ce980157a894a0a4446902ba8b1783d
diff --git a/src/test/auxiliary/iss.rs b/src/test/auxiliary/iss.rs
new file mode 100644 (file)
index 0000000..a3ead83
--- /dev/null
@@ -0,0 +1,23 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[link(name="iss6919_3", vers="0.1")];
+
+// part of issue-6919.rs
+
+struct C<'self> {
+    k: &'self fn(),
+}
+
+fn no_op() { }
+pub static D : C<'static> = C {
+    k: no_op
+};
+
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs
new file mode 100644 (file)
index 0000000..2e254e5
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Foo {
+    fn bar();
+}
+
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs
new file mode 100644 (file)
index 0000000..9e4d90e
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// for this issue, this code must be built in a library
+
+use std::cast;
+
+trait A {}
+struct B;
+impl A for B {}
+
+fn bar<T>(_: &mut A, _: &T) {}
+
+fn foo<T>(t: &T) {
+    let b = B;
+    bar(unsafe { cast::transmute(&b as &A) }, t)
+}
+
index 576b1c452a5ecccb05d4e408203639022967512c..4f60391892da37439f1fe84fc20ddd15c086e6ed 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::local_data;
 
-static key: local_data::Key<@&int> = &local_data::Key;
+local_data_key!(key: @&int)
 //~^ ERROR only 'static is allowed
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-3907.rs b/src/test/compile-fail/issue-3907.rs
new file mode 100644 (file)
index 0000000..df18a5a
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue_3907.rs
+extern mod issue_3907;
+
+type Foo = issue_3907::Foo; //~ ERROR: reference to trait
+
+struct S {
+    name: int
+}
+
+impl Foo for S { //~ ERROR: Foo is not a trait
+    fn bar() { }
+}
+
+fn main() {
+    let s = S {
+        name: 0
+    };
+    s.bar();
+}
+
diff --git a/src/test/compile-fail/issue-4096.rs b/src/test/compile-fail/issue-4096.rs
new file mode 100644 (file)
index 0000000..3f1172b
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Nummy {
+    fn from_inty<T>() -> Self;
+}
+
+impl Nummy for float {
+    fn from_inty<T>() -> float { 0.0 }
+}
+
+fn main() {
+    let _1:float = Nummy::from_inty::<int>();  //~ ERROR not enough type
+    //~^ NOTE Static methods have an extra implicit type parameter
+}
diff --git a/src/test/compile-fail/issue-5439.rs b/src/test/compile-fail/issue-5439.rs
new file mode 100644 (file)
index 0000000..8bd9bb3
--- /dev/null
@@ -0,0 +1,29 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    foo: int,
+}
+
+struct Bar {
+    bar: int,
+}
+
+impl Bar {
+    fn make_foo (&self, i: int) -> ~Foo {
+        return ~Foo { nonexistent: self, foo: i }; //~ ERROR: no field named
+    }
+}
+
+fn main () {
+    let bar = Bar { bar: 1 };
+    let foo = bar.make_foo(2);
+    println(fmt!("%d", foo.foo));
+}
diff --git a/src/test/compile-fail/macro-local-data-key-priv.rs b/src/test/compile-fail/macro-local-data-key-priv.rs
new file mode 100644 (file)
index 0000000..a64c5c0
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::local_data;
+
+// check that the local data keys are private by default.
+
+mod bar {
+    local_data_key!(baz: float)
+}
+
+fn main() {
+    local_data::set(bar::baz, -10.0);
+    //~^ ERROR unresolved name `bar::baz`
+}
index 14d8b04ade4ebef069c0b4131353f53d1b1a2434..09e4380f346794da39d2ec91dd280b9c28ce39fe 100644 (file)
@@ -29,8 +29,9 @@ fn main() {
         _ => ()
     }
     match 'c' {
-        S { _ } => (),   //~ ERROR mismatched types: expected `char` but found struct
+        S { _ } => (),   //~ ERROR mismatched types: expected `char` but found a structure pattern
+
         _ => ()
     }
     f(true);            //~ ERROR mismatched types: expected `char` but found `bool`
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/static-vec-repeat-not-constant.rs b/src/test/compile-fail/static-vec-repeat-not-constant.rs
new file mode 100644 (file)
index 0000000..7721e18
--- /dev/null
@@ -0,0 +1,15 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo() -> int { 23 }
+
+static a: [int, ..2] = [foo(), ..2]; //~ ERROR: function calls in constants are limited to struct and enum constructors
+
+fn main() {}
diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs
new file mode 100644 (file)
index 0000000..cafead3
--- /dev/null
@@ -0,0 +1,26 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct a {
+    b: uint,
+    c: uint
+}
+
+impl a {
+    fn foo(&self) {
+        let a { x, y } = self.d; //~ ERROR attempted access of field `d`
+        //~^ ERROR struct `a` does not have a field named `x`
+        //~^^ ERROR struct `a` does not have a field named `y`
+        //~^^^ ERROR pattern does not mention field `b`
+        //~^^^^ ERROR pattern does not mention field `c`
+    }
+}
+
+fn main() {}
diff --git a/src/test/debug-info/lexical-scope-in-for-loop.rs b/src/test/debug-info/lexical-scope-in-for-loop.rs
new file mode 100644 (file)
index 0000000..9aae26b
--- /dev/null
@@ -0,0 +1,77 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// FIRST ITERATION
+// debugger:finish
+// debugger:print x
+// check:$1 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = -1
+// debugger:continue
+
+// SECOND ITERATION
+// debugger:finish
+// debugger:print x
+// check:$3 = 2
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = -2
+// debugger:continue
+
+// THIRD ITERATION
+// debugger:finish
+// debugger:print x
+// check:$5 = 3
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = -3
+// debugger:continue
+
+// AFTER LOOP
+// debugger:finish
+// debugger:print x
+// check:$7 = 1000000
+// debugger:continue
+
+fn main() {
+
+    let range = [1, 2, 3];
+
+    let x = 1000000; // wan meeeljen doollaars!
+
+    for &x in range.iter() {
+        zzz();
+        sentinel();
+
+        let x = -1 * x;
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-if.rs b/src/test/debug-info/lexical-scope-in-if.rs
new file mode 100644 (file)
index 0000000..296ad7c
--- /dev/null
@@ -0,0 +1,128 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// BEFORE if
+// debugger:finish
+// debugger:print x
+// check:$1 = 999
+// debugger:print y
+// check:$2 = -1
+// debugger:continue
+
+// AT BEGINNING of 'then' block
+// debugger:finish
+// debugger:print x
+// check:$3 = 999
+// debugger:print y
+// check:$4 = -1
+// debugger:continue
+
+// AFTER 1st redeclaration of 'x'
+// debugger:finish
+// debugger:print x
+// check:$5 = 1001
+// debugger:print y
+// check:$6 = -1
+// debugger:continue
+
+// AFTER 2st redeclaration of 'x'
+// debugger:finish
+// debugger:print x
+// check:$7 = 1002
+// debugger:print y
+// check:$8 = 1003
+// debugger:continue
+
+// AFTER 1st if expression
+// debugger:finish
+// debugger:print x
+// check:$9 = 999
+// debugger:print y
+// check:$10 = -1
+// debugger:continue
+
+// BEGINNING of else branch
+// debugger:finish
+// debugger:print x
+// check:$11 = 999
+// debugger:print y
+// check:$12 = -1
+// debugger:continue
+
+// BEGINNING of else branch
+// debugger:finish
+// debugger:print x
+// check:$13 = 1004
+// debugger:print y
+// check:$14 = 1005
+// debugger:continue
+
+// BEGINNING of else branch
+// debugger:finish
+// debugger:print x
+// check:$15 = 999
+// debugger:print y
+// check:$16 = -1
+// debugger:continue
+
+use std::util;
+
+fn main() {
+
+    let x = 999;
+    let y = -1;
+
+    zzz();
+    sentinel();
+
+    if x < 1000 {
+        zzz();
+        sentinel();
+
+        let x = 1001;
+
+        zzz();
+        sentinel();
+
+        let x = 1002;
+        let y = 1003;
+        zzz();
+        sentinel();
+    } else {
+        util::unreachable();
+    }
+
+    zzz();
+    sentinel();
+
+    if x > 1000 {
+        util::unreachable();
+    } else {
+        zzz();
+        sentinel();
+
+        let x = 1004;
+        let y = 1005;
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-managed-closure.rs b/src/test/debug-info/lexical-scope-in-managed-closure.rs
new file mode 100644 (file)
index 0000000..d04818b
--- /dev/null
@@ -0,0 +1,79 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 1000
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 2.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = false
+// debugger:continue
+
+fn main() {
+
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    let managed_closure: @fn(int) = |x| {
+        zzz();
+        sentinel();
+
+        let x = 2.5;
+
+        zzz();
+        sentinel();
+
+        let x = true;
+
+        zzz();
+        sentinel();
+    };
+
+    zzz();
+    sentinel();
+
+    managed_closure(1000);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-match.rs b/src/test/debug-info/lexical-scope-in-match.rs
new file mode 100644 (file)
index 0000000..ccdb20d
--- /dev/null
@@ -0,0 +1,148 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print shadowed
+// check:$1 = 231
+// debugger:print not_shadowed
+// check:$2 = 232
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$3 = 233
+// debugger:print not_shadowed
+// check:$4 = 232
+// debugger:print local_to_arm
+// check:$5 = 234
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$6 = 236
+// debugger:print not_shadowed
+// check:$7 = 232
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$8 = 237
+// debugger:print not_shadowed
+// check:$9 = 232
+// debugger:print local_to_arm
+// check:$10 = 238
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$11 = 239
+// debugger:print not_shadowed
+// check:$12 = 232
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$13 = 241
+// debugger:print not_shadowed
+// check:$14 = 232
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$15 = 243
+// debugger:print *local_to_arm
+// check:$16 = 244
+// debugger:continue
+
+// debugger:finish
+// debugger:print shadowed
+// check:$17 = 231
+// debugger:print not_shadowed
+// check:$18 = 232
+// debugger:continue
+
+struct Struct {
+    x: int,
+    y: int
+}
+
+fn main() {
+
+    let shadowed = 231;
+    let not_shadowed = 232;
+
+    zzz();
+    sentinel();
+
+    match (233, 234) {
+        (shadowed, local_to_arm) => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match (235, 236) {
+        // with literal
+        (235, shadowed) => {
+
+            zzz();
+            sentinel();
+        }
+        _ => {}
+    }
+
+    match Struct { x: 237, y: 238 } {
+        Struct { x: shadowed, y: local_to_arm } => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match Struct { x: 239, y: 240 } {
+        // ignored field
+        Struct { x: shadowed, _ } => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    match Struct { x: 241, y: 242 } {
+        // with literal
+        Struct { x: shadowed, y: 242 } => {
+
+            zzz();
+            sentinel();
+        }
+        _ => {}
+    }
+
+    match (243, 244) {
+        (shadowed, ref local_to_arm) => {
+
+            zzz();
+            sentinel();
+        }
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-stack-closure.rs b/src/test/debug-info/lexical-scope-in-stack-closure.rs
new file mode 100644 (file)
index 0000000..dd86b4a
--- /dev/null
@@ -0,0 +1,79 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 1000
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 2.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = false
+// debugger:continue
+
+fn main() {
+
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    let stack_closure: &fn(int) = |x| {
+        zzz();
+        sentinel();
+
+        let x = 2.5;
+
+        zzz();
+        sentinel();
+
+        let x = true;
+
+        zzz();
+        sentinel();
+    };
+
+    zzz();
+    sentinel();
+
+    stack_closure(1000);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-unconditional-loop.rs b/src/test/debug-info/lexical-scope-in-unconditional-loop.rs
new file mode 100644 (file)
index 0000000..21c4e74
--- /dev/null
@@ -0,0 +1,127 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// FIRST ITERATION
+// debugger:finish
+// debugger:print x
+// check:$1 = 0
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 101
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 101
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = -987
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = 101
+// debugger:continue
+
+
+// SECOND ITERATION
+// debugger:finish
+// debugger:print x
+// check:$7 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$8 = 2
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$9 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$10 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$11 = -987
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$12 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$13 = 2
+// debugger:continue
+
+fn main() {
+
+    let mut x = 0;
+
+    loop {
+        if x >= 2 {
+            break;
+        }
+
+        zzz();
+        sentinel();
+
+        x += 1;
+        zzz();
+        sentinel();
+
+        // Shadow x
+        let x = x + 100;
+        zzz();
+        sentinel();
+
+        // open scope within loop's top level scope
+        {
+            zzz();
+            sentinel();
+
+            let x = -987;
+
+            zzz();
+            sentinel();
+        }
+
+        // Check that we get the x before the inner scope again
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-unique-closure.rs b/src/test/debug-info/lexical-scope-in-unique-closure.rs
new file mode 100644 (file)
index 0000000..32251f4
--- /dev/null
@@ -0,0 +1,79 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 1000
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 2.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = false
+// debugger:continue
+
+fn main() {
+
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    let unique_closure: ~fn(int) = |x| {
+        zzz();
+        sentinel();
+
+        let x = 2.5;
+
+        zzz();
+        sentinel();
+
+        let x = true;
+
+        zzz();
+        sentinel();
+    };
+
+    zzz();
+    sentinel();
+
+    unique_closure(1000);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-in-while.rs b/src/test/debug-info/lexical-scope-in-while.rs
new file mode 100644 (file)
index 0000000..b350130
--- /dev/null
@@ -0,0 +1,123 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// FIRST ITERATION
+// debugger:finish
+// debugger:print x
+// check:$1 = 0
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 101
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 101
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = -987
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = 101
+// debugger:continue
+
+
+// SECOND ITERATION
+// debugger:finish
+// debugger:print x
+// check:$7 = 1
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$8 = 2
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$9 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$10 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$11 = -987
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$12 = 102
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$13 = 2
+// debugger:continue
+
+fn main() {
+
+    let mut x = 0;
+
+    while x < 2 {
+        zzz();
+        sentinel();
+
+        x += 1;
+        zzz();
+        sentinel();
+
+        // Shadow x
+        let x = x + 100;
+        zzz();
+        sentinel();
+
+        // open scope within loop's top level scope
+        {
+            zzz();
+            sentinel();
+
+            let x = -987;
+
+            zzz();
+            sentinel();
+        }
+
+        // Check that we get the x before the inner scope again
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scope-with-macro.rs b/src/test/debug-info/lexical-scope-with-macro.rs
new file mode 100644 (file)
index 0000000..409ecd5
--- /dev/null
@@ -0,0 +1,129 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print a
+// check:$1 = 10
+// debugger:print b
+// check:$2 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$3 = 890242
+// debugger:print b
+// check:$4 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$5 = 10
+// debugger:print b
+// check:$6 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$7 = 102
+// debugger:print b
+// check:$8 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$9 = 110
+// debugger:print b
+// check:$10 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$11 = 10
+// debugger:print b
+// check:$12 = 34
+// debugger:continue
+
+// debugger:finish
+// debugger:print a
+// check:$13 = 10
+// debugger:print b
+// check:$14 = 34
+// debugger:print c
+// check:$15 = 400
+// debugger:continue
+
+macro_rules! trivial(
+    ($e1:expr) => ($e1)
+)
+
+macro_rules! no_new_scope(
+    ($e1:expr) => (($e1 + 2) - 1)
+)
+
+macro_rules! new_scope(
+    () => ({
+        let a = 890242;
+        zzz();
+        sentinel();
+    })
+)
+
+macro_rules! shadow_within_macro(
+    ($e1:expr) => ({
+        let a = $e1 + 2;
+
+        zzz();
+        sentinel();
+
+        let a = $e1 + 10;
+
+        zzz();
+        sentinel();
+    })
+)
+
+
+macro_rules! dup_expr(
+    ($e1:expr) => (($e1) + ($e1))
+)
+
+
+fn main() {
+
+    let a = trivial!(10);
+    let b = no_new_scope!(33);
+
+    zzz();
+    sentinel();
+
+    new_scope!();
+
+    zzz();
+    sentinel();
+
+    shadow_within_macro!(100);
+
+    zzz();
+    sentinel();
+
+    let c = dup_expr!(10 * 20);
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/lexical-scopes-in-block-expression.rs b/src/test/debug-info/lexical-scopes-in-block-expression.rs
new file mode 100644 (file)
index 0000000..03de640
--- /dev/null
@@ -0,0 +1,344 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// STRUCT EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$1 = -1
+// debugger:print ten
+// check:$2 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$3 = 11
+// debugger:print ten
+// check:$4 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$5 = -1
+// debugger:print ten
+// check:$6 = 10
+// debugger:continue
+
+// FUNCTION CALL
+// debugger:finish
+// debugger:print val
+// check:$7 = -1
+// debugger:print ten
+// check:$8 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$9 = 12
+// debugger:print ten
+// check:$10 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$11 = -1
+// debugger:print ten
+// check:$12 = 10
+// debugger:continue
+
+// TUPLE EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$13 = -1
+// debugger:print ten
+// check:$14 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$15 = 13
+// debugger:print ten
+// check:$16 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$17 = -1
+// debugger:print ten
+// check:$18 = 10
+// debugger:continue
+
+// VEC EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$19 = -1
+// debugger:print ten
+// check:$20 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$21 = 14
+// debugger:print ten
+// check:$22 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$23 = -1
+// debugger:print ten
+// check:$24 = 10
+// debugger:continue
+
+// REPEAT VEC EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$25 = -1
+// debugger:print ten
+// check:$26 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$27 = 15
+// debugger:print ten
+// check:$28 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$29 = -1
+// debugger:print ten
+// check:$30 = 10
+// debugger:continue
+
+// ASSIGNMENT EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$31 = -1
+// debugger:print ten
+// check:$32 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$33 = 16
+// debugger:print ten
+// check:$34 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$35 = -1
+// debugger:print ten
+// check:$36 = 10
+// debugger:continue
+
+
+// ARITHMETIC EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$37 = -1
+// debugger:print ten
+// check:$38 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$39 = 17
+// debugger:print ten
+// check:$40 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$41 = -1
+// debugger:print ten
+// check:$42 = 10
+// debugger:continue
+
+// INDEX EXPRESSION
+// debugger:finish
+// debugger:print val
+// check:$43 = -1
+// debugger:print ten
+// check:$44 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$45 = 18
+// debugger:print ten
+// check:$46 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print val
+// check:$47 = -1
+// debugger:print ten
+// check:$48 = 10
+// debugger:continue
+
+struct Point {
+    x: int,
+    y: int
+}
+
+fn a_function(x: int) -> int {
+    x + 1
+}
+
+fn main() {
+
+    let val = -1;
+    let ten = 10;
+
+    // surrounded by struct expression
+    let point = Point {
+        x: {
+            zzz();
+            sentinel();
+
+            let val = ten + 1;
+
+            zzz();
+            sentinel();
+
+            val
+        },
+        y: 10
+    };
+
+    zzz();
+    sentinel();
+
+    // surrounded by function call
+    let _ = a_function({
+        zzz();
+        sentinel();
+
+        let val = ten + 2;
+
+        zzz();
+        sentinel();
+
+        val
+    });
+
+    zzz();
+    sentinel();
+
+
+    // surrounded by tup
+    let _ = ({
+        zzz();
+        sentinel();
+
+        let val = ten + 3;
+
+        zzz();
+        sentinel();
+
+        val
+    }, 0);
+
+    zzz();
+    sentinel();
+
+    // surrounded by vec
+    let _ = [{
+        zzz();
+        sentinel();
+
+        let val = ten + 4;
+
+        zzz();
+        sentinel();
+
+        val
+    }, 0, 0];
+
+    zzz();
+    sentinel();
+
+    // surrounded by repeat vec
+    let _ = [{
+        zzz();
+        sentinel();
+
+        let val = ten + 5;
+
+        zzz();
+        sentinel();
+
+        val
+    }, ..10];
+
+    zzz();
+    sentinel();
+
+    // assignment expression
+    let mut var = 0;
+    var = {
+        zzz();
+        sentinel();
+
+        let val = ten + 6;
+
+        zzz();
+        sentinel();
+
+        val
+    };
+
+    zzz();
+    sentinel();
+
+    // arithmetic expression
+    var = 10 + -{
+        zzz();
+        sentinel();
+
+        let val = ten + 7;
+
+        zzz();
+        sentinel();
+
+        val
+    } * 5;
+
+    zzz();
+    sentinel();
+
+    // index expression
+    let a_vector = [10, ..20];
+    let _ = a_vector[{
+        zzz();
+        sentinel();
+
+        let val = ten + 8;
+
+        zzz();
+        sentinel();
+
+        val
+    }];
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/name-shadowing-and-scope-nesting.rs b/src/test/debug-info/name-shadowing-and-scope-nesting.rs
new file mode 100644 (file)
index 0000000..ba8c08e
--- /dev/null
@@ -0,0 +1,95 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:print y
+// check:$2 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 10
+// debugger:print y
+// check:$4 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = 10.5
+// debugger:print y
+// check:$6 = 20
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$7 = true
+// debugger:print y
+// check:$8 = 2220
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$9 = 203203.5
+// debugger:print y
+// check:$10 = 2220
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$11 = 10.5
+// debugger:print y
+// check:$12 = 20
+// debugger:continue
+
+fn main() {
+    let x = false;
+    let y = true;
+
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+
+    {
+        let x = true;
+        let y = 2220;
+
+        zzz();
+        sentinel();
+
+        let x = 203203.5;
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/shadowed-argument.rs b/src/test/debug-info/shadowed-argument.rs
new file mode 100644 (file)
index 0000000..b79b65c
--- /dev/null
@@ -0,0 +1,59 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:print y
+// check:$2 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 10
+// debugger:print y
+// check:$4 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = 10.5
+// debugger:print y
+// check:$6 = 20
+// debugger:continue
+
+fn a_function(x: bool, y: bool) {
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+}
+
+fn main() {
+    a_function(false, true);
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/shadowed-variable.rs b/src/test/debug-info/shadowed-variable.rs
new file mode 100644 (file)
index 0000000..a532f7f
--- /dev/null
@@ -0,0 +1,58 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:print y
+// check:$2 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 10
+// debugger:print y
+// check:$4 = true
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = 10.5
+// debugger:print y
+// check:$6 = 20
+// debugger:continue
+
+fn main() {
+    let x = false;
+    let y = true;
+
+    zzz();
+    sentinel();
+
+    let x = 10;
+
+    zzz();
+    sentinel();
+
+    let x = 10.5;
+    let y = 20;
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/simple-lexical-scope.rs b/src/test/debug-info/simple-lexical-scope.rs
new file mode 100644 (file)
index 0000000..96a394b
--- /dev/null
@@ -0,0 +1,87 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
+
+// compile-flags:-Z extra-debug-info
+// debugger:break zzz
+// debugger:run
+
+// debugger:finish
+// debugger:print x
+// check:$1 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$2 = false
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$3 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$4 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$5 = 10.5
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$6 = 10
+// debugger:continue
+
+// debugger:finish
+// debugger:print x
+// check:$7 = false
+// debugger:continue
+
+
+fn main() {
+    let x = false;
+
+    zzz();
+    sentinel();
+
+    {
+        zzz();
+        sentinel();
+
+        let x = 10;
+
+        zzz();
+        sentinel();
+
+        {
+            zzz();
+            sentinel();
+
+            let x = 10.5;
+
+            zzz();
+            sentinel();
+        }
+
+        zzz();
+        sentinel();
+    }
+
+    zzz();
+    sentinel();
+}
+
+fn zzz() {()}
+fn sentinel() {()}
diff --git a/src/test/debug-info/variable-scope.rs b/src/test/debug-info/variable-scope.rs
deleted file mode 100644 (file)
index dd3a167..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-
-// compile-flags:-Z extra-debug-info
-// debugger:break zzz
-// debugger:run
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:print y
-// check:$2 = true
-
-// debugger:continue
-// debugger:finish
-// debugger:print x
-// check:$3 = 10
-
-// debugger:continue
-// debugger:finish
-// debugger:print x
-// check:$4 = false
-// debugger:print y
-// check:$5 = 11
-
-fn main() {
-    let x = false;
-    let y = true;
-
-    zzz();
-
-    {
-        let x = 10;
-        zzz();
-    }
-
-    let y = 11;
-    zzz();
-}
-
-fn zzz() {()}
diff --git a/src/test/run-fail/assert-eq-macro-fail b/src/test/run-fail/assert-eq-macro-fail
deleted file mode 100755 (executable)
index 2841756..0000000
Binary files a/src/test/run-fail/assert-eq-macro-fail and /dev/null differ
diff --git a/src/test/run-fail/borrowck-wg-fail-object-arg.rs b/src/test/run-fail/borrowck-wg-fail-object-arg.rs
new file mode 100644 (file)
index 0000000..c70d752
--- /dev/null
@@ -0,0 +1,22 @@
+// error-pattern:borrowed
+
+trait Foo {
+    fn foo(&self, @mut int);
+}
+
+impl Foo for int {
+    fn foo(&self, x: @mut int) {
+        *x += *self;
+    }
+}
+
+fn it_takes_two(f: &Foo, g: &mut Foo) {
+}
+
+fn main() {
+    let x = @mut 3_i;
+    let y = x as @mut Foo;
+    let z = y;
+
+    it_takes_two(y, z);
+}
diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs
deleted file mode 100644 (file)
index f31fea5..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// In this case, the code should compile but
-// the assert should fail at runtime
-// error-pattern:assertion failed
-extern mod extra;
-use std::vec::{same_length, zip};
-
-fn enum_chars(start: u8, end: u8) -> ~[char] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i as char); i += 1 as u8; }
-    return r;
-}
-
-fn enum_uints(start: uint, end: uint) -> ~[uint] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i); i += 1; }
-    return r;
-}
-
-fn main() {
-    let a = 'a' as u8;
-    let j = 'j' as u8;
-    let k = 1;
-    let l = 9;
-    let chars = enum_chars(a, j);
-    let ints = enum_uints(k, l);
-
-    assert!(same_length(chars, ints));
-    let ps = zip(chars, ints);
-    fail!("the impossible happened");
-}
index e91c11f5cd0a703eea86f5080aec6051d1c52bf9..22c5e9dad25a4723cab72ca83277e7daf3acf79d 100644 (file)
@@ -20,11 +20,11 @@ mod libc {
 }
 
 fn atol(s: ~str) -> int {
-    s.to_c_str().with_ref(|x| unsafe { libc::atol(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atol(x as *u8) })
 }
 
 fn atoll(s: ~str) -> i64 {
-    s.to_c_str().with_ref(|x| unsafe { libc::atoll(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atoll(x as *u8) })
 }
 
 pub fn main() {
index 412efcc25a877434ae6379c71a53d4627b0bacaf..cbf4c36c5df3c9bddf0e082d9445bec8dd1d8064 100644 (file)
@@ -9,6 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let opt: Option<&'static str> = option_env!("__HOPEFULLY_DOESNT_EXIST__");
-    assert!(opt.is_none());
+    assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none());
 }
index b5a114ef22364e64dc2bea3f7ccf326b914afa50..827f950dab241ec9924c16ebd736d6fdec2de15f 100644 (file)
@@ -26,7 +26,7 @@ mod libc {
 fn strlen(str: ~str) -> uint {
     unsafe {
         // C string is terminated with a zero
-        do str.to_c_str().with_ref |buf| {
+        do str.with_c_str |buf| {
             libc::my_strlen(buf as *u8)
         }
     }
index 562642453fd27b48dbd20a4bb6b354aaa8516af5..a0d3eb7d803287d3a6dcc1b2d97e6074e0992a4e 100644 (file)
@@ -22,50 +22,170 @@ impl fmt::Signed for B {
 }
 
 pub fn main() {
-    fn t(a: ~str, b: &str) { assert_eq!(a, b.to_owned()); }
+    macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) })
 
     // Make sure there's a poly formatter that takes anything
-    t(ifmt!("{}", 1), "1");
-    t(ifmt!("{}", A), "{}");
-    t(ifmt!("{}", ()), "()");
-    t(ifmt!("{}", @(~1, "foo")), "@(~1, \"foo\")");
+    t!(ifmt!("{}", 1), "1");
+    t!(ifmt!("{}", A), "{}");
+    t!(ifmt!("{}", ()), "()");
+    t!(ifmt!("{}", @(~1, "foo")), "@(~1, \"foo\")");
 
     // Various edge cases without formats
-    t(ifmt!(""), "");
-    t(ifmt!("hello"), "hello");
-    t(ifmt!("hello \\{"), "hello {");
+    t!(ifmt!(""), "");
+    t!(ifmt!("hello"), "hello");
+    t!(ifmt!("hello \\{"), "hello {");
 
     // At least exercise all the formats
-    t(ifmt!("{:b}", true), "true");
-    t(ifmt!("{:c}", '☃'), "☃");
-    t(ifmt!("{:d}", 10), "10");
-    t(ifmt!("{:i}", 10), "10");
-    t(ifmt!("{:u}", 10u), "10");
-    t(ifmt!("{:o}", 10u), "12");
-    t(ifmt!("{:x}", 10u), "a");
-    t(ifmt!("{:X}", 10u), "A");
-    t(ifmt!("{:s}", "foo"), "foo");
-    t(ifmt!("{:p}", 0x1234 as *int), "0x1234");
-    t(ifmt!("{:p}", 0x1234 as *mut int), "0x1234");
-    t(ifmt!("{:d}", A), "aloha");
-    t(ifmt!("{:d}", B), "adios");
-    t(ifmt!("foo {:s} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
-    t(ifmt!("{1} {0}", 0, 1), "1 0");
-    t(ifmt!("{foo} {bar}", foo=0, bar=1), "0 1");
-    t(ifmt!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
-    t(ifmt!("{} {0:s}", "a"), "a a");
-    t(ifmt!("{} {0}", "a"), "\"a\" \"a\"");
+    t!(ifmt!("{:b}", true), "true");
+    t!(ifmt!("{:c}", '☃'), "☃");
+    t!(ifmt!("{:d}", 10), "10");
+    t!(ifmt!("{:i}", 10), "10");
+    t!(ifmt!("{:u}", 10u), "10");
+    t!(ifmt!("{:o}", 10u), "12");
+    t!(ifmt!("{:x}", 10u), "a");
+    t!(ifmt!("{:X}", 10u), "A");
+    t!(ifmt!("{:s}", "foo"), "foo");
+    t!(ifmt!("{:p}", 0x1234 as *int), "0x1234");
+    t!(ifmt!("{:p}", 0x1234 as *mut int), "0x1234");
+    t!(ifmt!("{:d}", A), "aloha");
+    t!(ifmt!("{:d}", B), "adios");
+    t!(ifmt!("foo {:s} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");
+    t!(ifmt!("{1} {0}", 0, 1), "1 0");
+    t!(ifmt!("{foo} {bar}", foo=0, bar=1), "0 1");
+    t!(ifmt!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0");
+    t!(ifmt!("{} {0:s}", "a"), "a a");
+    t!(ifmt!("{} {0}", "a"), "\"a\" \"a\"");
 
     // Methods should probably work
-    t(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 0u), "c0");
-    t(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 1u), "a1");
-    t(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 2u), "b2");
-    t(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 3u), "d3");
-    t(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "a"), "aa");
-    t(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "b"), "bb");
-    t(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "c"), "cc");
-    t(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "d"), "dd");
-    t(ifmt!("{1, select, a{#{0:s}} other{#{1}}}", "b", "a"), "ab");
-    t(ifmt!("{1, select, a{#{0}} other{#{1}}}", "c", "b"), "bb");
+    t!(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 0u), "c0");
+    t!(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 1u), "a1");
+    t!(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 2u), "b2");
+    t!(ifmt!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 3u), "d3");
+    t!(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "a"), "aa");
+    t!(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "b"), "bb");
+    t!(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "c"), "cc");
+    t!(ifmt!("{0, select, a{a#} b{b#} c{c#} other{d#}}", "d"), "dd");
+    t!(ifmt!("{1, select, a{#{0:s}} other{#{1}}}", "b", "a"), "ab");
+    t!(ifmt!("{1, select, a{#{0}} other{#{1}}}", "c", "b"), "bb");
+
+    // Formatting strings and their arguments
+    t!(ifmt!("{:s}", "a"), "a");
+    t!(ifmt!("{:4s}", "a"), "a   ");
+    t!(ifmt!("{:>4s}", "a"), "   a");
+    t!(ifmt!("{:<4s}", "a"), "a   ");
+    t!(ifmt!("{:.4s}", "a"), "a");
+    t!(ifmt!("{:4.4s}", "a"), "a   ");
+    t!(ifmt!("{:4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
+    t!(ifmt!("{:<4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
+    t!(ifmt!("{:>4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
+    t!(ifmt!("{:>10.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
+    t!(ifmt!("{:2.4s}", "aaaaa"), "aaaa");
+    t!(ifmt!("{:2.4s}", "aaaa"), "aaaa");
+    t!(ifmt!("{:2.4s}", "aaa"), "aaa");
+    t!(ifmt!("{:2.4s}", "aa"), "aa");
+    t!(ifmt!("{:2.4s}", "a"), "a ");
+    t!(ifmt!("{:0>2s}", "a"), "0a");
+    t!(ifmt!("{:.*s}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa");
+    t!(ifmt!("{:.1$s}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa");
+    t!(ifmt!("{:1$s}", "a", 4), "a   ");
+    t!(ifmt!("{:-#s}", "a"), "a");
+    t!(ifmt!("{:+#s}", "a"), "a");
+
+    // Formatting integers should select the right implementation based off the
+    // type of the argument. Also, hex/octal/binary should be defined for
+    // integers, but they shouldn't emit the negative sign.
+    t!(ifmt!("{:d}", -1i), "-1");
+    t!(ifmt!("{:d}", -1i8), "-1");
+    t!(ifmt!("{:d}", -1i16), "-1");
+    t!(ifmt!("{:d}", -1i32), "-1");
+    t!(ifmt!("{:d}", -1i64), "-1");
+    t!(ifmt!("{:t}", 1i), "1");
+    t!(ifmt!("{:t}", 1i8), "1");
+    t!(ifmt!("{:t}", 1i16), "1");
+    t!(ifmt!("{:t}", 1i32), "1");
+    t!(ifmt!("{:t}", 1i64), "1");
+    t!(ifmt!("{:x}", 1i), "1");
+    t!(ifmt!("{:x}", 1i8), "1");
+    t!(ifmt!("{:x}", 1i16), "1");
+    t!(ifmt!("{:x}", 1i32), "1");
+    t!(ifmt!("{:x}", 1i64), "1");
+    t!(ifmt!("{:X}", 1i), "1");
+    t!(ifmt!("{:X}", 1i8), "1");
+    t!(ifmt!("{:X}", 1i16), "1");
+    t!(ifmt!("{:X}", 1i32), "1");
+    t!(ifmt!("{:X}", 1i64), "1");
+    t!(ifmt!("{:o}", 1i), "1");
+    t!(ifmt!("{:o}", 1i8), "1");
+    t!(ifmt!("{:o}", 1i16), "1");
+    t!(ifmt!("{:o}", 1i32), "1");
+    t!(ifmt!("{:o}", 1i64), "1");
+
+    t!(ifmt!("{:u}", 1u), "1");
+    t!(ifmt!("{:u}", 1u8), "1");
+    t!(ifmt!("{:u}", 1u16), "1");
+    t!(ifmt!("{:u}", 1u32), "1");
+    t!(ifmt!("{:u}", 1u64), "1");
+    t!(ifmt!("{:t}", 1u), "1");
+    t!(ifmt!("{:t}", 1u8), "1");
+    t!(ifmt!("{:t}", 1u16), "1");
+    t!(ifmt!("{:t}", 1u32), "1");
+    t!(ifmt!("{:t}", 1u64), "1");
+    t!(ifmt!("{:x}", 1u), "1");
+    t!(ifmt!("{:x}", 1u8), "1");
+    t!(ifmt!("{:x}", 1u16), "1");
+    t!(ifmt!("{:x}", 1u32), "1");
+    t!(ifmt!("{:x}", 1u64), "1");
+    t!(ifmt!("{:X}", 1u), "1");
+    t!(ifmt!("{:X}", 1u8), "1");
+    t!(ifmt!("{:X}", 1u16), "1");
+    t!(ifmt!("{:X}", 1u32), "1");
+    t!(ifmt!("{:X}", 1u64), "1");
+    t!(ifmt!("{:o}", 1u), "1");
+    t!(ifmt!("{:o}", 1u8), "1");
+    t!(ifmt!("{:o}", 1u16), "1");
+    t!(ifmt!("{:o}", 1u32), "1");
+    t!(ifmt!("{:o}", 1u64), "1");
+
+    // Test the flags for formatting integers
+    t!(ifmt!("{:3d}", 1),  "  1");
+    t!(ifmt!("{:>3d}", 1),  "  1");
+    t!(ifmt!("{:>+3d}", 1), " +1");
+    t!(ifmt!("{:<3d}", 1), "1  ");
+    t!(ifmt!("{:#d}", 1), "1");
+    t!(ifmt!("{:#x}", 10), "0xa");
+    t!(ifmt!("{:#X}", 10), "0xA");
+    t!(ifmt!("{:#5x}", 10), "  0xa");
+    t!(ifmt!("{:#o}", 10), "0o12");
+    t!(ifmt!("{:08x}", 10),  "0000000a");
+    t!(ifmt!("{:8x}", 10),   "       a");
+    t!(ifmt!("{:<8x}", 10),  "a       ");
+    t!(ifmt!("{:>8x}", 10),  "       a");
+    t!(ifmt!("{:#08x}", 10), "0x00000a");
+    t!(ifmt!("{:08d}", -10), "-0000010");
+    t!(ifmt!("{:x}", -1u8), "ff");
+    t!(ifmt!("{:X}", -1u8), "FF");
+    t!(ifmt!("{:t}", -1u8), "11111111");
+    t!(ifmt!("{:o}", -1u8), "377");
+    t!(ifmt!("{:#x}", -1u8), "0xff");
+    t!(ifmt!("{:#X}", -1u8), "0xFF");
+    t!(ifmt!("{:#t}", -1u8), "0b11111111");
+    t!(ifmt!("{:#o}", -1u8), "0o377");
+
+    // Signed combinations
+    t!(ifmt!("{:+5d}", 1),  "   +1");
+    t!(ifmt!("{:+5d}", -1), "   -1");
+    t!(ifmt!("{:05d}", 1),   "00001");
+    t!(ifmt!("{:05d}", -1),  "-0001");
+    t!(ifmt!("{:+05d}", 1),  "+0001");
+    t!(ifmt!("{:+05d}", -1), "-0001");
+
+    // Some float stuff
+    t!(ifmt!("{:f}", 1.0f), "1");
+    t!(ifmt!("{:f}", 1.0f32), "1");
+    t!(ifmt!("{:f}", 1.0f64), "1");
+    t!(ifmt!("{:.3f}", 1.0f), "1.000");
+    t!(ifmt!("{:10.3f}", 1.0f),   "     1.000");
+    t!(ifmt!("{:+10.3f}", 1.0f),  "    +1.000");
+    t!(ifmt!("{:+10.3f}", -1.0f), "    -1.000");
 }
 
diff --git a/src/test/run-pass/issue-4464.rs b/src/test/run-pass/issue-4464.rs
new file mode 100644 (file)
index 0000000..529f8ec
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn broken<'r>(v: &'r [u8], i: uint, j: uint) -> &'r [u8] { v.slice(i, j) }
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-4759-1.rs b/src/test/run-pass/issue-4759-1.rs
new file mode 100644 (file)
index 0000000..ad8ee98
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait U { fn f(self); }
+impl U for int { fn f(self) {} }
+pub fn main() { 4.f(); }
diff --git a/src/test/run-pass/issue-4759.rs b/src/test/run-pass/issue-4759.rs
new file mode 100644 (file)
index 0000000..4591203
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct T { a: ~int }
+
+trait U {
+    fn f(self);
+}
+
+impl U for ~int {
+    fn f(self) { }
+}
+
+pub fn main() {
+    let T { a: a } = T { a: ~0 };
+    a.f();
+}
+
diff --git a/src/test/run-pass/issue-5666.rs b/src/test/run-pass/issue-5666.rs
new file mode 100644 (file)
index 0000000..1be5d07
--- /dev/null
@@ -0,0 +1,35 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Dog {
+    name : ~str
+}
+
+trait Barks {
+    fn bark(&self) -> ~str;
+}
+
+impl Barks for Dog {
+    fn bark(&self) -> ~str {
+        return fmt!("woof! (I'm %s)", self.name);
+    }
+}
+
+
+pub fn main() {
+    let snoopy = ~Dog{name: ~"snoopy"};
+    let bubbles = ~Dog{name: ~"bubbles"};
+    let barker = [snoopy as ~Barks, bubbles as ~Barks];
+
+    for pup in barker.iter() {
+        println(fmt!("%s", pup.bark()));
+    }
+}
+
diff --git a/src/test/run-pass/issue-5884.rs b/src/test/run-pass/issue-5884.rs
new file mode 100644 (file)
index 0000000..ea0e40b
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Foo {
+    a: int,
+}
+
+struct Bar<'self> {
+    a: ~Option<int>,
+    b: &'self Foo,
+}
+
+fn check(a: @Foo) {
+    let mut _ic = Bar{ b: a, a: ~None };
+}
+
+pub fn main(){}
diff --git a/src/test/run-pass/issue-5917.rs b/src/test/run-pass/issue-5917.rs
new file mode 100644 (file)
index 0000000..fb6a068
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test
+
+use std::io;
+
+struct T (&'static [int]);
+static t : T = T (&'static [5, 4, 3]);
+fn main () {
+    assert_eq!(t[0], 5);
+}
\ No newline at end of file
diff --git a/src/test/run-pass/issue-5926.rs b/src/test/run-pass/issue-5926.rs
new file mode 100644 (file)
index 0000000..7557df2
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let  mut your_favorite_numbers = @[1,2,3];
+    let  mut my_favorite_numbers = @[4,5,6];
+    let  f = your_favorite_numbers + my_favorite_numbers;
+    println(fmt!("The third favorite number is %?.", f))
+}
+
diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs
new file mode 100644 (file)
index 0000000..bf586ee
--- /dev/null
@@ -0,0 +1,26 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub enum Thing {
+    A(~Foo)
+}
+
+pub trait Foo {}
+
+pub struct Struct;
+
+impl Foo for Struct {}
+
+pub fn main() {
+    match A(~Struct as ~Foo) {
+        A(a) => 0,
+    };
+}
+
diff --git a/src/test/run-pass/issue-6470.rs b/src/test/run-pass/issue-6470.rs
new file mode 100644 (file)
index 0000000..73d0e18
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test
+
+pub mod Bar {
+    pub struct Foo {
+        v: int,
+    }
+
+    extern {
+        #[rust_stack]
+        pub fn foo(v: *Foo) -> Foo;
+    }
+}
+
+fn main() { }
+
diff --git a/src/test/run-pass/issue-6557.rs b/src/test/run-pass/issue-6557.rs
new file mode 100644 (file)
index 0000000..1ba5053
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(~(x, y): ~(int, int)) {}
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-6898.rs b/src/test/run-pass/issue-6898.rs
new file mode 100644 (file)
index 0000000..2d612bb
--- /dev/null
@@ -0,0 +1,40 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::unstable::intrinsics;
+
+/// Returns the size of a type
+pub fn size_of<T>() -> uint {
+    TypeInfo::size_of::<T>()
+}
+
+/// Returns the size of the type that `val` points to
+pub fn size_of_val<T>(val: &T) -> uint {
+    val.size_of_val()
+}
+
+pub trait TypeInfo {
+    fn size_of() -> uint;
+    fn size_of_val(&self) -> uint;
+}
+
+impl<T> TypeInfo for T {
+    /// The size of the type in bytes.
+    fn size_of() -> uint {
+        unsafe { intrinsics::size_of::<T>() }
+    }
+
+    /// Returns the size of the type of `self` in bytes.
+    fn size_of_val(&self) -> uint {
+        TypeInfo::size_of::<T>()
+    }
+}
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-6919.rs b/src/test/run-pass/issue-6919.rs
new file mode 100644 (file)
index 0000000..f63811f
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:iss.rs
+// xfail-fast
+
+extern mod iss ( name = "iss6919_3" );
+
+pub fn main() {
+    iss::D.k;
+}
+
diff --git a/src/test/run-pass/issue-7222.rs b/src/test/run-pass/issue-7222.rs
new file mode 100644 (file)
index 0000000..98c0064
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    static FOO: float = 10.0;
+
+    match 0.0 {
+        0.0 .. FOO => (),
+        _ => ()
+    }
+}
+
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
new file mode 100644 (file)
index 0000000..48f3480
--- /dev/null
@@ -0,0 +1,21 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait A {}
+struct B;
+impl A for B {}
+
+fn foo(_: &mut A) {}
+
+fn main() {
+    let mut b = B;
+    foo(&mut b as &mut A);
+}
+
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
new file mode 100644 (file)
index 0000000..ad37196
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait A {}
+struct B;
+impl A for B {}
+
+struct C<'self> {
+    foo: &'self mut A,
+}
+
+fn foo(a: &mut A) {
+    C{ foo: a };
+}
+
+fn main() {
+}
+
diff --git a/src/test/run-pass/issue-8398.rs b/src/test/run-pass/issue-8398.rs
new file mode 100644 (file)
index 0000000..5e04c96
--- /dev/null
@@ -0,0 +1,18 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::rt::io;
+
+fn foo(a: &mut io::Writer) {
+    a.write([])
+}
+
+fn main(){}
+
diff --git a/src/test/run-pass/issue-8401.rs b/src/test/run-pass/issue-8401.rs
new file mode 100644 (file)
index 0000000..cf78683
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue_8401.rs
+// xfail-fast
+
+extern mod issue_8401;
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-8498.rs b/src/test/run-pass/issue-8498.rs
new file mode 100644 (file)
index 0000000..40f9835
--- /dev/null
@@ -0,0 +1,44 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-test
+use std::io;
+
+fn main() {
+// This is ok
+    match &[(~5,~7)] {
+        ps => {
+           let (ref y, _) = ps[0];
+           io::println(fmt!("1. y = %d", **y));
+           assert!(**y == 5);
+        }
+    }
+
+// This is not entirely ok
+    match Some(&[(~5,)]) {
+        Some(ps) => {
+           let (ref y,) = ps[0];
+           io::println(fmt!("2. y = %d", **y));
+           if **y != 5 { io::println("sadness"); }
+        }
+        None => ()
+    }
+
+// This is not ok
+    match Some(&[(~5,~7)]) {
+        Some(ps) => {
+           let (ref y, ref z) = ps[0];
+           io::println(fmt!("3. y = %d z = %d", **y, **z));
+           assert!(**y == 5);
+        }
+        None => ()
+    }
+}
+
diff --git a/src/test/run-pass/macro-local-data-key.rs b/src/test/run-pass/macro-local-data-key.rs
new file mode 100644 (file)
index 0000000..b53d7b3
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::local_data;
+
+local_data_key!(foo: int)
+
+mod bar {
+    local_data_key!(pub baz: float)
+}
+
+fn main() {
+    local_data::get(foo, |x| assert!(x.is_none()));
+    local_data::get(bar::baz, |y| assert!(y.is_none()));
+
+    local_data::set(foo, 3);
+    local_data::set(bar::baz, -10.0);
+
+    local_data::get(foo, |x| assert_eq!(*x.unwrap(), 3));
+    local_data::get(bar::baz, |y| assert_eq!(*y.unwrap(), -10.0));
+}
diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/run-pass/objects-coerce-freeze-borrored.rs
new file mode 100644 (file)
index 0000000..4dda5ca
--- /dev/null
@@ -0,0 +1,48 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can coerce an `@Object` to an `&Object`
+
+trait Foo {
+    fn foo(&self) -> uint;
+    fn bar(&mut self) -> uint;
+}
+
+impl Foo for uint {
+    fn foo(&self) -> uint {
+        *self
+    }
+
+    fn bar(&mut self) -> uint {
+        *self += 1;
+        *self
+    }
+}
+
+fn do_it_mut(obj: &mut Foo) {
+    let x = obj.bar();
+    let y = obj.foo();
+    assert_eq!(x, y);
+
+    do_it_imm(obj, y);
+}
+
+fn do_it_imm(obj: &Foo, v: uint) {
+    let y = obj.foo();
+    assert_eq!(v, y);
+}
+
+fn main() {
+    let mut x = 22_u;
+    let obj = &mut x as &mut Foo;
+    do_it_mut(obj);
+    do_it_imm(obj, 23u);
+    do_it_mut(obj);
+}
diff --git a/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs b/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs
new file mode 100644 (file)
index 0000000..fe4eb2e
--- /dev/null
@@ -0,0 +1,44 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we can coerce an `@Object` to an `&Object`
+
+trait Foo {
+    fn foo(&self) -> uint;
+    fn bar(&mut self) -> uint;
+}
+
+impl Foo for uint {
+    fn foo(&self) -> uint {
+        *self
+    }
+
+    fn bar(&mut self) -> uint {
+        *self += 1;
+        *self
+    }
+}
+
+fn do_it_mut(obj: &mut Foo) {
+    let x = obj.bar();
+    let y = obj.foo();
+    assert_eq!(x, y);
+}
+
+fn do_it_imm(obj: &Foo, v: uint) {
+    let y = obj.foo();
+    assert_eq!(v, y);
+}
+
+fn main() {
+    let x = @mut 22u as @mut Foo;
+    do_it_mut(x);
+    do_it_imm(x, 23u);
+}
diff --git a/src/test/run-pass/repeat-expr-in-static.rs b/src/test/run-pass/repeat-expr-in-static.rs
new file mode 100644 (file)
index 0000000..d060db2
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static FOO: [int, ..4] = [32, ..4];
+static BAR: [int, ..4] = [32, 32, 32, 32];
+
+pub fn main() {
+    assert_eq!(FOO, BAR);
+}
diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs
deleted file mode 100644 (file)
index d971487..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// In this case, the code should compile and should
-// succeed at runtime
-
-use std::vec;
-
-fn enum_chars(start: u8, end: u8) -> ~[char] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i as char); i += 1u as u8; }
-    return r;
-}
-
-fn enum_uints(start: uint, end: uint) -> ~[uint] {
-    assert!(start < end);
-    let mut i = start;
-    let mut r = ~[];
-    while i <= end { r.push(i); i += 1u; }
-    return r;
-}
-
-pub fn main() {
-    let a = 'a' as u8;
-    let j = 'j' as u8;
-    let k = 1u;
-    let l = 10u;
-    let chars = enum_chars(a, j);
-    let ints = enum_uints(k, l);
-
-    let ps = vec::zip(chars, ints);
-
-    assert_eq!(ps.head(), &('a', 1u));
-    assert_eq!(ps.last(), &(j as char, 10u));
-}