]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #24171 - rillian:rustup, r=brson
authorManish Goregaokar <manishsmail@gmail.com>
Thu, 9 Apr 2015 10:23:36 +0000 (15:53 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Thu, 9 Apr 2015 10:23:36 +0000 (15:53 +0530)
 The idea here is if you don't want rust in /usr/local
you can put something like this is your .profile:

```
export RUSTUP_PREFIX=$HOME/.local/rust
export PATH=$PATH:${RUSTUP_PREFIX}/bin
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${RUSTUP_PREFIX}/lib
```
Then when you run rustup, it will update the install
in ${RUSTUP_PREFIX} without having to remember to pass
an explicit --prefix argument every time.

129 files changed:
AUTHORS.txt
src/compiletest/runtest.rs
src/doc/complement-design-faq.md
src/doc/intro.md
src/doc/trpl/SUMMARY.md
src/doc/trpl/advanced-macros.md [deleted file]
src/doc/trpl/advanced.md [deleted file]
src/doc/trpl/arrays-vectors-and-slices.md [deleted file]
src/doc/trpl/arrays.md [new file with mode: 0644]
src/doc/trpl/attributes.md [new file with mode: 0644]
src/doc/trpl/basic.md [deleted file]
src/doc/trpl/casting-between-types.md [new file with mode: 0644]
src/doc/trpl/compiler-plugins.md [new file with mode: 0644]
src/doc/trpl/compound-data-types.md [deleted file]
src/doc/trpl/conclusion.md [deleted file]
src/doc/trpl/conditional-compilation.md [new file with mode: 0644]
src/doc/trpl/const.md [new file with mode: 0644]
src/doc/trpl/debug-and-display.md [new file with mode: 0644]
src/doc/trpl/deref-coercions.md [new file with mode: 0644]
src/doc/trpl/drop.md [new file with mode: 0644]
src/doc/trpl/effective-rust.md [new file with mode: 0644]
src/doc/trpl/enums.md [new file with mode: 0644]
src/doc/trpl/for-loops.md [new file with mode: 0644]
src/doc/trpl/getting-started.md [new file with mode: 0644]
src/doc/trpl/hello-world.md
src/doc/trpl/if.md
src/doc/trpl/intermediate.md [deleted file]
src/doc/trpl/learn-rust.md [new file with mode: 0644]
src/doc/trpl/lifetimes.md [new file with mode: 0644]
src/doc/trpl/looping.md [deleted file]
src/doc/trpl/macros.md
src/doc/trpl/more-strings.md [deleted file]
src/doc/trpl/move-semantics.md [new file with mode: 0644]
src/doc/trpl/mutability.md [new file with mode: 0644]
src/doc/trpl/nightly-rust.md [new file with mode: 0644]
src/doc/trpl/operators-and-overloading.md [new file with mode: 0644]
src/doc/trpl/plugins.md [deleted file]
src/doc/trpl/pointers.md [deleted file]
src/doc/trpl/primitive-types.md [new file with mode: 0644]
src/doc/trpl/references-and-borrowing.md [new file with mode: 0644]
src/doc/trpl/slices.md [new file with mode: 0644]
src/doc/trpl/static-and-dynamic-dispatch.md [deleted file]
src/doc/trpl/static.md [new file with mode: 0644]
src/doc/trpl/structs.md [new file with mode: 0644]
src/doc/trpl/syntax-and-semantics.md [new file with mode: 0644]
src/doc/trpl/the-stack-and-the-heap.md [new file with mode: 0644]
src/doc/trpl/tracing-macros.md [deleted file]
src/doc/trpl/trait-objects.md [new file with mode: 0644]
src/doc/trpl/tuple-structs.md [new file with mode: 0644]
src/doc/trpl/tuples.md [new file with mode: 0644]
src/doc/trpl/type-aliases.md [new file with mode: 0644]
src/doc/trpl/ufcs.md [new file with mode: 0644]
src/doc/trpl/unsafe-code.md [new file with mode: 0644]
src/doc/trpl/unsafe.md [deleted file]
src/doc/trpl/unsized-types.md [new file with mode: 0644]
src/doc/trpl/unstable.md [deleted file]
src/doc/trpl/vectors.md [new file with mode: 0644]
src/doc/trpl/while-loops.md [new file with mode: 0644]
src/etc/unicode.py
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/rc.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollectionstest/str.rs
src/libcore/clone.rs
src/libcore/iter.rs
src/libcore/num/mod.rs
src/libcore/ptr.rs
src/libcoretest/iter.rs
src/librustc/diagnostics.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/check_match.rs
src/librustc/middle/def.rs
src/librustc/middle/region.rs
src/librustc/util/ppaux.rs
src/librustc_driver/lib.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/save/mod.rs
src/librustc_trans/trans/_match.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/cast.rs [new file with mode: 0644]
src/librustc_typeck/check/mod.rs
src/librustc_typeck/collect.rs
src/libstd/io/stdio.rs
src/libstd/old_path/posix.rs
src/libstd/old_path/windows.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mod.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mutex.rs
src/libstd/sync/poison.rs [deleted file]
src/libstd/sync/rwlock.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/common/poison.rs [new file with mode: 0644]
src/libstd/sys/common/remutex.rs [new file with mode: 0644]
src/libstd/sys/unix/mutex.rs
src/libstd/sys/unix/sync.rs
src/libstd/sys/windows/mutex.rs
src/libstd/sys/windows/sync.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ptr.rs
src/libunicode/tables.rs
src/libunicode/u_str.rs
src/rustbook/book.rs
src/test/bench/shootout-spectralnorm.rs
src/test/compile-fail/fat-ptr-cast.rs [new file with mode: 0644]
src/test/compile-fail/issue-22560.rs [new file with mode: 0644]
src/test/compile-fail/issue-23338-locals-die-before-temps-of-body.rs [new file with mode: 0644]
src/test/compile-fail/macro-incomplete-parse.rs
src/test/compile-fail/range-1.rs
src/test/compile-fail/self-impl.rs [new file with mode: 0644]
src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs
src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
src/test/compile-fail/unsupported-cast.rs
src/test/run-pass/atomic-print.rs [new file with mode: 0644]
src/test/run-pass/fmt-pointer-trait.rs [new file with mode: 0644]
src/test/run-pass/issue-15673.rs
src/test/run-pass/issue-23338-ensure-param-drop-order.rs [new file with mode: 0644]
src/test/run-pass/issue-23338-params-outlive-temps-of-body.rs [new file with mode: 0644]
src/test/run-pass/issue-24161.rs [new file with mode: 0644]
src/test/run-pass/iter-cloned-type-inference.rs
src/test/run-pass/self-impl.rs

index 7a800b70e4a381f7ce9b91c0ac59a5449310fe25..83d8d9ef0c8b515ff39249cd8b122742eb7580a9 100644 (file)
@@ -796,7 +796,7 @@ Tamir Duberstein <tamird@squareup.com>
 Taras Shpot <mrshpot@gmail.com>
 Taylor Hutchison <seanthutchison@gmail.com>
 Ted Horst <ted.horst@earthlink.net>
-Tero Hänninen <tejohann@kapsi.fi>
+Tero Hänninen <lgvz@users.noreply.github.com>
 Thad Guidry <thadguidry@gmail.com>
 Thiago Carvalho <thiago.carvalho@westwing.de>
 Thiago Pontes <email@thiago.me>
index d99f06bd853b71d0f6bf8e025abdf89b97906f2e..f387f83ad524635bd36eb570130495249816510d 100644 (file)
@@ -382,8 +382,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
 
             // write debugger script
             let mut script_str = String::with_capacity(2048);
-            let charset = if cfg!(target_os = "bitrig") { "auto" } else { "UTF-8" };
-            script_str.push_str(&format!("set charset {}\n", charset));
+            script_str.push_str(&format!("set charset {}\n", charset()));
             script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
             script_str.push_str("target remote :5039\n");
             script_str.push_str(&format!("set solib-search-path \
@@ -517,8 +516,7 @@ fn sleep() {
                                                        .to_string();
             // write debugger script
             let mut script_str = String::with_capacity(2048);
-            let charset = if cfg!(target_os = "bitrig") { "auto" } else { "UTF-8" };
-            script_str.push_str(&format!("set charset {}\n", charset));
+            script_str.push_str(&format!("set charset {}\n", charset()));
             script_str.push_str("show version\n");
 
             match config.gdb_version {
@@ -1791,3 +1789,11 @@ fn run_codegen_test(config: &Config, props: &TestProps,
                      (base_lines as f64) / (clang_lines as f64),
                      0.001);
 }
+
+fn charset() -> &'static str {
+    if cfg!(any(target_os = "bitrig", target_os = "freebsd")) {
+        "auto"
+    } else {
+        "UTF-8"
+    }
+}
index 3edbcbe62c51172ea225fa122e62add202f9657b..0f2c37a5abf8346b9c102262b20075adfe825efa 100644 (file)
@@ -163,13 +163,17 @@ This is to make the language easier to parse for humans, especially in the face
 of higher-order functions. `fn foo<T>(f: fn(int): int, fn(T): U): U` is not
 particularly easy to read.
 
-## `let` is used to introduce variables
+## Why is `let` used to introduce variables?
 
-`let` not only defines variables, but can do pattern matching. One can also
-redeclare immutable variables with `let`. This is useful to avoid unnecessary
-`mut` annotations. An interesting historical note is that Rust comes,
-syntactically, most closely from ML, which also uses `let` to introduce
-bindings.
+We don't use the term "variable", instead, we use "variable bindings". The
+simplest way for binding is the `let` syntax, other ways including `if let`,
+`while let` and `match`. Bindings also exist in function arguments positions.
+
+Bindings always happen in pattern matching positions, and it's also Rust's way
+to declare mutability. One can also redeclare mutability of a binding in
+pattern matching. This is useful to avoid unnecessary `mut` annotations. An
+interesting historical note is that Rust comes, syntactically, most closely
+from ML, which also uses `let` to introduce bindings.
 
 See also [a long thread][alt] on renaming `let mut` to `var`.
 
index 10e52a159dfa29704393d2453d5a6e8da72a3394..1dc9f09c220116965c5a19311e195fad4432ca17 100644 (file)
@@ -23,7 +23,7 @@ and safety.
 # Tools
 
 Getting started on a new Rust project is incredibly easy, thanks to Rust's
-package manager, [Cargo](http://crates.io).
+package manager, [Cargo](https://crates.io/).
 
 To start a new project with Cargo, use `cargo new`:
 
@@ -149,8 +149,8 @@ Enough about tools, let's talk code!
 Rust's defining feature is "memory safety without garbage collection". Let's
 take a moment to talk about what that means. *Memory safety* means that the
 programming language eliminates certain kinds of bugs, such as [buffer
-overflows](http://en.wikipedia.org/wiki/Buffer_overflow) and [dangling
-pointers](http://en.wikipedia.org/wiki/Dangling_pointer). These problems occur
+overflows](https://en.wikipedia.org/wiki/Buffer_overflow) and [dangling
+pointers](https://en.wikipedia.org/wiki/Dangling_pointer). These problems occur
 when you have unrestricted access to memory. As an example, here's some Ruby
 code:
 
index 11e62aff42f3fd6132c1d4df5280aaa74a134ba2..d894e1c47253b7d12c2740df13dc4958f2db3788 100644 (file)
@@ -1,42 +1,64 @@
 # Summary
 
-* [The Basics](basic.md)
+* [Getting Started](getting-started.md)
     * [Installing Rust](installing-rust.md)
     * [Hello, world!](hello-world.md)
     * [Hello, Cargo!](hello-cargo.md)
+* [Learn Rust](learn-rust.md)
+* [Effective Rust](effective-rust.md)
+    * [The Stack and the Heap](the-stack-and-the-heap.md)
+    * [`Debug` and `Display`](debug-and-display.md)
+    * [Testing](testing.md)
+    * [Documentation](documentation.md)
+    * [Iterators](iterators.md)
+    * [Concurrency](concurrency.md)
+    * [Error Handling](error-handling.md)
+    * [FFI](ffi.md)
+    * [`Deref` coercions](deref-coercions.md)
+* [Syntax and Semantics](syntax-and-semantics.md)
     * [Variable Bindings](variable-bindings.md)
-    * [If](if.md)
+    * [Primitive Types](primitive-types.md)
     * [Functions](functions.md)
     * [Comments](comments.md)
-    * [Compound Data Types](compound-data-types.md)
+    * [Structs](structs.md)
+    * [Mutability](mutability.md)
+    * [Method Syntax](method-syntax.md)
+    * [Enums](enums.md)
+    * [`if`](if.md)
     * [Match](match.md)
-    * [Looping](looping.md)
+    * [Patterns](patterns.md)
+    * [`for` loops](for-loops.md)
+    * [`while` loops](while-loops.md)
+    * [Ownership](ownership.md)
+    * [References and Borrowing](references-and-borrowing.md)
+    * [Lifetimes](lifetimes.md)
+    * [Move semantics](move-semantics.md)
+    * [Drop](drop.md)
+    * [Vectors](vectors.md)
+    * [Arrays](arrays.md)
+    * [Slices](slices.md)
     * [Strings](strings.md)
-    * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md)
-* [Intermediate Rust](intermediate.md)
+    * [Traits](traits.md)
+    * [Operators and Overloading](operators-and-overloading.md)
+    * [Generics](generics.md)
+    * [Trait Objects](trait-objects.md)
+    * [Closures](closures.md)
+    * [Universal Function Call Syntax](ufcs.md)
     * [Crates and Modules](crates-and-modules.md)
-    * [Testing](testing.md)
-    * [Pointers](pointers.md)
-    * [Ownership](ownership.md)
-    * [More Strings](more-strings.md)
-    * [Patterns](patterns.md)
-    * [Method Syntax](method-syntax.md)
+    * [`static`](static.md)
+    * [`const`](const.md)
+    * [Tuples](tuples.md)
+    * [Tuple Structs](tuple-structs.md)
+    * [Attributes](attributes.md)
+    * [Conditional Compilation](conditional-compilation.md)
+    * [`type` aliases](type-aliases.md)
+    * [Casting between types](casting-between-types.md)
     * [Associated Types](associated-types.md)
-    * [Closures](closures.md)
-    * [Iterators](iterators.md)
-    * [Generics](generics.md)
-    * [Traits](traits.md)
-    * [Static and Dynamic Dispatch](static-and-dynamic-dispatch.md)
+    * [Unsized Types](unsized-types.md)
     * [Macros](macros.md)
-    * [Concurrency](concurrency.md)
-    * [Error Handling](error-handling.md)
-    * [Documentation](documentation.md)
-* [Advanced Topics](advanced.md)
-    * [FFI](ffi.md)
-    * [Unsafe Code](unsafe.md)
-    * [Advanced Macros](advanced-macros.md)
-* [Unstable Rust](unstable.md)
-    * [Compiler Plugins](plugins.md)
+    * [`unsafe` Code](unsafe-code.md)
+* [Nightly Rust](nightly-rust.md)
+    * [Compiler Plugins](compiler-plugins.md)
     * [Inline Assembly](inline-assembly.md)
     * [No stdlib](no-stdlib.md)
     * [Intrinsics](intrinsics.md)
@@ -44,5 +66,4 @@
     * [Link args](link-args.md)
     * [Benchmark Tests](benchmark-tests.md)
     * [Box Syntax and Patterns](box-syntax-and-patterns.md)
-* [Conclusion](conclusion.md)
 * [Glossary](glossary.md)
diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md
deleted file mode 100644 (file)
index fef458c..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-% Advanced macros
-
-This chapter picks up where the [introductory macro chapter](macros.html) left
-off.
-
-# Syntactic requirements
-
-Even when Rust code contains un-expanded macros, it can be parsed as a full
-[syntax tree][ast]. This property can be very useful for editors and other
-tools that process code. It also has a few consequences for the design of
-Rust's macro system.
-
-[ast]: glossary.html#abstract-syntax-tree
-
-One consequence is that Rust must determine, when it parses a macro invocation,
-whether the macro stands in for
-
-* zero or more items,
-* zero or more methods,
-* an expression,
-* a statement, or
-* a pattern.
-
-A macro invocation within a block could stand for some items, or for an
-expression / statement. Rust uses a simple rule to resolve this ambiguity. A
-macro invocation that stands for items must be either
-
-* delimited by curly braces, e.g. `foo! { ... }`, or
-* terminated by a semicolon, e.g. `foo!(...);`
-
-Another consequence of pre-expansion parsing is that the macro invocation must
-consist of valid Rust tokens. Furthermore, parentheses, brackets, and braces
-must be balanced within a macro invocation. For example, `foo!([)` is
-forbidden. This allows Rust to know where the macro invocation ends.
-
-More formally, the macro invocation body must be a sequence of *token trees*.
-A token tree is defined recursively as either
-
-* a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or
-* any other single token.
-
-Within a matcher, each metavariable has a *fragment specifier*, identifying
-which syntactic form it matches.
-
-* `ident`: an identifier. Examples: `x`; `foo`.
-* `path`: a qualified name. Example: `T::SpecialA`.
-* `expr`: an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`.
-* `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`.
-* `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`.
-* `stmt`: a single statement. Example: `let x = 3`.
-* `block`: a brace-delimited sequence of statements. Example:
-  `{ log(error, "hi"); return 12; }`.
-* `item`: an [item][]. Examples: `fn foo() { }`; `struct Bar;`.
-* `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`.
-* `tt`: a single token tree.
-
-There are additional rules regarding the next token after a metavariable:
-
-* `expr` variables must be followed by one of: `=> , ;`
-* `ty` and `path` variables must be followed by one of: `=> , : = > as`
-* `pat` variables must be followed by one of: `=> , =`
-* Other variables may be followed by any token.
-
-These rules provide some flexibility for Rust's syntax to evolve without
-breaking existing macros.
-
-The macro system does not deal with parse ambiguity at all. For example, the
-grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would
-be forced to choose between parsing `$t` and parsing `$e`. Changing the
-invocation syntax to put a distinctive token in front can solve the problem. In
-this case, you can write `$(T $t:ty)* E $e:exp`.
-
-[item]: ../reference.html#items
-
-# Scoping and macro import/export
-
-Macros are expanded at an early stage in compilation, before name resolution.
-One downside is that scoping works differently for macros, compared to other
-constructs in the language.
-
-Definition and expansion of macros both happen in a single depth-first,
-lexical-order traversal of a crate's source. So a macro defined at module scope
-is visible to any subsequent code in the same module, which includes the body
-of any subsequent child `mod` items.
-
-A macro defined within the body of a single `fn`, or anywhere else not at
-module scope, is visible only within that item.
-
-If a module has the `macro_use` attribute, its macros are also visible in its
-parent module after the child's `mod` item. If the parent also has `macro_use`
-then the macros will be visible in the grandparent after the parent's `mod`
-item, and so forth.
-
-The `macro_use` attribute can also appear on `extern crate`. In this context
-it controls which macros are loaded from the external crate, e.g.
-
-```rust,ignore
-#[macro_use(foo, bar)]
-extern crate baz;
-```
-
-If the attribute is given simply as `#[macro_use]`, all macros are loaded. If
-there is no `#[macro_use]` attribute then no macros are loaded. Only macros
-defined with the `#[macro_export]` attribute may be loaded.
-
-To load a crate's macros *without* linking it into the output, use `#[no_link]`
-as well.
-
-An example:
-
-```rust
-macro_rules! m1 { () => (()) }
-
-// visible here: m1
-
-mod foo {
-    // visible here: m1
-
-    #[macro_export]
-    macro_rules! m2 { () => (()) }
-
-    // visible here: m1, m2
-}
-
-// visible here: m1
-
-macro_rules! m3 { () => (()) }
-
-// visible here: m1, m3
-
-#[macro_use]
-mod bar {
-    // visible here: m1, m3
-
-    macro_rules! m4 { () => (()) }
-
-    // visible here: m1, m3, m4
-}
-
-// visible here: m1, m3, m4
-# fn main() { }
-```
-
-When this library is loaded with `#[macro_use] extern crate`, only `m2` will
-be imported.
-
-The Rust Reference has a [listing of macro-related
-attributes](../reference.html#macro--and-plugin-related-attributes).
-
-# The variable `$crate`
-
-A further difficulty occurs when a macro is used in multiple crates. Say that
-`mylib` defines
-
-```rust
-pub fn increment(x: u32) -> u32 {
-    x + 1
-}
-
-#[macro_export]
-macro_rules! inc_a {
-    ($x:expr) => ( ::increment($x) )
-}
-
-#[macro_export]
-macro_rules! inc_b {
-    ($x:expr) => ( ::mylib::increment($x) )
-}
-# fn main() { }
-```
-
-`inc_a` only works within `mylib`, while `inc_b` only works outside the
-library. Furthermore, `inc_b` will break if the user imports `mylib` under
-another name.
-
-Rust does not (yet) have a hygiene system for crate references, but it does
-provide a simple workaround for this problem. Within a macro imported from a
-crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
-By contrast, when a macro is defined and then used in the same crate, `$crate`
-will expand to nothing. This means we can write
-
-```rust
-#[macro_export]
-macro_rules! inc {
-    ($x:expr) => ( $crate::increment($x) )
-}
-# fn main() { }
-```
-
-to define a single macro that works both inside and outside our library. The
-function name will expand to either `::increment` or `::mylib::increment`.
-
-To keep this system simple and correct, `#[macro_use] extern crate ...` may
-only appear at the root of your crate, not inside `mod`. This ensures that
-`$crate` is a single identifier.
-
-# The deep end
-
-The introductory chapter mentioned recursive macros, but it did not give the
-full story. Recursive macros are useful for another reason: Each recursive
-invocation gives you another opportunity to pattern-match the macro's
-arguments.
-
-As an extreme example, it is possible, though hardly advisable, to implement
-the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
-within Rust's macro system.
-
-```rust
-macro_rules! bct {
-    // cmd 0:  d ... => ...
-    (0, $($ps:tt),* ; $_d:tt)
-        => (bct!($($ps),*, 0 ; ));
-    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
-        => (bct!($($ps),*, 0 ; $($ds),*));
-
-    // cmd 1p:  1 ... => 1 ... p
-    (1, $p:tt, $($ps:tt),* ; 1)
-        => (bct!($($ps),*, 1, $p ; 1, $p));
-    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
-
-    // cmd 1p:  0 ... => 0 ...
-    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; $($ds),*));
-
-    // halt on empty data string
-    ( $($ps:tt),* ; )
-        => (());
-}
-```
-
-Exercise: use macros to reduce duplication in the above definition of the
-`bct!` macro.
-
-# Procedural macros
-
-If Rust's macro system can't do what you need, you may want to write a
-[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
-macros, this is significantly more work, the interfaces are much less stable,
-and bugs can be much harder to track down. In exchange you get the
-flexibility of running arbitrary Rust code within the compiler. Syntax
-extension plugins are sometimes called *procedural macros* for this reason.
diff --git a/src/doc/trpl/advanced.md b/src/doc/trpl/advanced.md
deleted file mode 100644 (file)
index 447a8a6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-% Advanced
-
-In a similar fashion to "Intermediate," this section is full of individual,
-deep-dive chapters, which stand alone and can be read in any order. These
-chapters focus on the most complex features, as well as some things that
-are only available in upcoming versions of Rust.
-
-After reading "Advanced," you'll be a Rust expert!
diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md
deleted file mode 100644 (file)
index 2916dca..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-% Arrays, Vectors, and Slices
-
-Like many programming languages, Rust has list types to represent a sequence of
-things. The most basic is the *array*, a fixed-size list of elements of the
-same type. By default, arrays are immutable.
-
-```{rust}
-let a = [1, 2, 3]; // a: [i32; 3]
-let mut m = [1, 2, 3]; // mut m: [i32; 3]
-```
-
-There's a shorthand for initializing each element of an array to the same
-value. In this example, each element of `a` will be initialized to `0`:
-
-```{rust}
-let a = [0; 20]; // a: [i32; 20]
-```
-
-Arrays have type `[T; N]`. We'll talk about this `T` notation later, when we
-cover generics.
-
-You can get the number of elements in an array `a` with `a.len()`, and use
-`a.iter()` to iterate over them with a for loop. This code will print each
-number in order:
-
-```{rust}
-let a = [1, 2, 3];
-
-println!("a has {} elements", a.len());
-for e in a.iter() {
-    println!("{}", e);
-}
-```
-
-You can access a particular element of an array with *subscript notation*:
-
-```{rust}
-let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]
-
-println!("The second name is: {}", names[1]);
-```
-
-Subscripts start at zero, like in most programming languages, so the first name
-is `names[0]` and the second name is `names[1]`. The above example prints
-`The second name is: Brian`. If you try to use a subscript that is not in the
-array, you will get an error: array access is bounds-checked at run-time. Such
-errant access is the source of many bugs in other systems programming
-languages.
-
-A *vector* is a dynamic or "growable" array, implemented as the standard
-library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means
-later). Vectors always allocate their data on the heap. Vectors are to slices
-what `String` is to `&str`. You can create them with the `vec!` macro:
-
-```{rust}
-let v = vec![1, 2, 3]; // v: Vec<i32>
-```
-
-(Notice that unlike the `println!` macro we've used in the past, we use square
-brackets `[]` with `vec!`. Rust allows you to use either in either situation,
-this is just convention.)
-
-There's an alternate form of `vec!` for repeating an initial value:
-
-```
-let v = vec![0; 10]; // ten zeroes
-```
-
-You can get the length of, iterate over, and subscript vectors just like
-arrays. In addition, (mutable) vectors can grow automatically:
-
-```{rust}
-let mut nums = vec![1, 2, 3]; // mut nums: Vec<i32>
-
-nums.push(4);
-
-println!("The length of nums is now {}", nums.len()); // Prints 4
-```
-
-Vectors have many more useful methods.
-
-A *slice* is a reference to (or "view" into) an array. They are useful for
-allowing safe, efficient access to a portion of an array without copying. For
-example, you might want to reference just one line of a file read into memory.
-By nature, a slice is not created directly, but from an existing variable.
-Slices have a length, can be mutable or not, and in many ways behave like
-arrays:
-
-```{rust}
-let a = [0, 1, 2, 3, 4];
-let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
-
-for e in middle.iter() {
-    println!("{}", e); // Prints 1, 2, 3
-}
-```
-
-You can also take a slice of a vector, `String`, or `&str`, because they are
-backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover
-generics.
-
-We have now learned all of the most basic Rust concepts.
diff --git a/src/doc/trpl/arrays.md b/src/doc/trpl/arrays.md
new file mode 100644 (file)
index 0000000..a6ecac9
--- /dev/null
@@ -0,0 +1,48 @@
+% Arrays
+
+Like many programming languages, Rust has list types to represent a sequence of
+things. The most basic is the *array*, a fixed-size list of elements of the
+same type. By default, arrays are immutable.
+
+```{rust}
+let a = [1, 2, 3]; // a: [i32; 3]
+let mut m = [1, 2, 3]; // mut m: [i32; 3]
+```
+
+There's a shorthand for initializing each element of an array to the same
+value. In this example, each element of `a` will be initialized to `0`:
+
+```{rust}
+let a = [0; 20]; // a: [i32; 20]
+```
+
+Arrays have type `[T; N]`. We'll talk about this `T` notation later, when we
+cover generics.
+
+You can get the number of elements in an array `a` with `a.len()`, and use
+`a.iter()` to iterate over them with a for loop. This code will print each
+number in order:
+
+```{rust}
+let a = [1, 2, 3];
+
+println!("a has {} elements", a.len());
+for e in a.iter() {
+    println!("{}", e);
+}
+```
+
+You can access a particular element of an array with *subscript notation*:
+
+```{rust}
+let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]
+
+println!("The second name is: {}", names[1]);
+```
+
+Subscripts start at zero, like in most programming languages, so the first name
+is `names[0]` and the second name is `names[1]`. The above example prints
+`The second name is: Brian`. If you try to use a subscript that is not in the
+array, you will get an error: array access is bounds-checked at run-time. Such
+errant access is the source of many bugs in other systems programming
+languages.
diff --git a/src/doc/trpl/attributes.md b/src/doc/trpl/attributes.md
new file mode 100644 (file)
index 0000000..e699bd8
--- /dev/null
@@ -0,0 +1,3 @@
+% Attributes
+
+Coming Soon!
diff --git a/src/doc/trpl/basic.md b/src/doc/trpl/basic.md
deleted file mode 100644 (file)
index c267830..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% Basics
-
-This section is a linear introduction to the basic syntax and semantics of
-Rust. It has individual sections on each part of Rust's syntax.
-
-After reading "Basics," you will have a good foundation to learn more about
-Rust, and can write very simple programs.
diff --git a/src/doc/trpl/casting-between-types.md b/src/doc/trpl/casting-between-types.md
new file mode 100644 (file)
index 0000000..8bb0ec6
--- /dev/null
@@ -0,0 +1,3 @@
+% Casting Between Types
+
+Coming Soon
diff --git a/src/doc/trpl/compiler-plugins.md b/src/doc/trpl/compiler-plugins.md
new file mode 100644 (file)
index 0000000..9eb22a7
--- /dev/null
@@ -0,0 +1,242 @@
+% Compiler Plugins
+
+# Introduction
+
+`rustc` can load compiler plugins, which are user-provided libraries that
+extend the compiler's behavior with new syntax extensions, lint checks, etc.
+
+A plugin is a dynamic library crate with a designated *registrar* function that
+registers extensions with `rustc`. Other crates can load these extensions using
+the crate attribute `#![plugin(...)]`.  See the
+[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
+mechanics of defining and loading a plugin.
+
+If present, arguments passed as `#![plugin(foo(... args ...))]` are not
+interpreted by rustc itself.  They are provided to the plugin through the
+`Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
+
+In the vast majority of cases, a plugin should *only* be used through
+`#![plugin]` and not through an `extern crate` item.  Linking a plugin would
+pull in all of libsyntax and librustc as dependencies of your crate.  This is
+generally unwanted unless you are building another plugin.  The
+`plugin_as_library` lint checks these guidelines.
+
+The usual practice is to put compiler plugins in their own crate, separate from
+any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
+of a library.
+
+# Syntax extensions
+
+Plugins can extend Rust's syntax in various ways. One kind of syntax extension
+is the procedural macro. These are invoked the same way as [ordinary
+macros](macros.html), but the expansion is performed by arbitrary Rust
+code that manipulates [syntax trees](../syntax/ast/index.html) at
+compile time.
+
+Let's write a plugin
+[`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs)
+that implements Roman numeral integer literals.
+
+```ignore
+#![crate_type="dylib"]
+#![feature(plugin_registrar, rustc_private)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::codemap::Span;
+use syntax::parse::token;
+use syntax::ast::{TokenTree, TtToken};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
+use syntax::ext::build::AstBuilder;  // trait for expr_usize
+use rustc::plugin::Registry;
+
+fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+        -> Box<MacResult + 'static> {
+
+    static NUMERALS: &'static [(&'static str, u32)] = &[
+        ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
+        ("C",  100), ("XC",  90), ("L",  50), ("XL",  40),
+        ("X",   10), ("IX",   9), ("V",   5), ("IV",   4),
+        ("I",    1)];
+
+    let text = match args {
+        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
+        _ => {
+            cx.span_err(sp, "argument should be a single identifier");
+            return DummyResult::any(sp);
+        }
+    };
+
+    let mut text = &*text;
+    let mut total = 0;
+    while !text.is_empty() {
+        match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
+            Some(&(rn, val)) => {
+                total += val;
+                text = &text[rn.len()..];
+            }
+            None => {
+                cx.span_err(sp, "invalid Roman numeral");
+                return DummyResult::any(sp);
+            }
+        }
+    }
+
+    MacEager::expr(cx.expr_u32(sp, total))
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("rn", expand_rn);
+}
+```
+
+Then we can use `rn!()` like any other macro:
+
+```ignore
+#![feature(plugin)]
+#![plugin(roman_numerals)]
+
+fn main() {
+    assert_eq!(rn!(MMXV), 2015);
+}
+```
+
+The advantages over a simple `fn(&str) -> u32` are:
+
+* The (arbitrarily complex) conversion is done at compile time.
+* Input validation is also performed at compile time.
+* It can be extended to allow use in patterns, which effectively gives
+  a way to define new literal syntax for any data type.
+
+In addition to procedural macros, you can define new
+[`derive`](../reference.html#derive)-like attributes and other kinds of
+extensions.  See
+[`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension)
+and the [`SyntaxExtension`
+enum](http://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html).  For
+a more involved macro example, see
+[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs).
+
+
+## Tips and tricks
+
+Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable.
+
+You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into
+higher-level syntax elements like expressions:
+
+```ignore
+fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+        -> Box<MacResult+'static> {
+
+    let mut parser = cx.new_parser_from_tts(args);
+
+    let expr: P<Expr> = parser.parse_expr();
+```
+
+Looking through [`libsyntax` parser
+code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs)
+will give you a feel for how the parsing infrastructure works.
+
+Keep the [`Span`s](../syntax/codemap/struct.Span.html) of
+everything you parse, for better error reporting. You can wrap
+[`Spanned`](../syntax/codemap/struct.Spanned.html) around
+your custom data structures.
+
+Calling
+[`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal)
+will immediately abort compilation. It's better to instead call
+[`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err)
+and return
+[`DummyResult`](../syntax/ext/base/struct.DummyResult.html),
+so that the compiler can continue and find further errors.
+
+To print syntax fragments for debugging, you can use
+[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together
+with
+[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions).
+
+The example above produced an integer literal using
+[`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize).
+As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
+[quasiquote macros](../syntax/ext/quote/index.html).  They are undocumented and
+very rough around the edges.  However, the implementation may be a good
+starting point for an improved quasiquote as an ordinary plugin library.
+
+
+# Lint plugins
+
+Plugins can extend [Rust's lint
+infrastructure](../reference.html#lint-check-attributes) with additional checks for
+code style, safety, etc. You can see
+[`src/test/auxiliary/lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs)
+for a full example, the core of which is reproduced here:
+
+```ignore
+declare_lint!(TEST_LINT, Warn,
+              "Warn about items named 'lintme'")
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        let name = token::get_ident(it.ident);
+        if name.get() == "lintme" {
+            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_lint_pass(box Pass as LintPassObject);
+}
+```
+
+Then code like
+
+```ignore
+#![plugin(lint_plugin_test)]
+
+fn lintme() { }
+```
+
+will produce a compiler warning:
+
+```txt
+foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
+foo.rs:4 fn lintme() { }
+         ^~~~~~~~~~~~~~~
+```
+
+The components of a lint plugin are:
+
+* one or more `declare_lint!` invocations, which define static
+  [`Lint`](../rustc/lint/struct.Lint.html) structs;
+
+* a struct holding any state needed by the lint pass (here, none);
+
+* a [`LintPass`](../rustc/lint/trait.LintPass.html)
+  implementation defining how to check each syntax element. A single
+  `LintPass` may call `span_lint` for several different `Lint`s, but should
+  register them all through the `get_lints` method.
+
+Lint passes are syntax traversals, but they run at a late stage of compilation
+where type information is available. `rustc`'s [built-in
+lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs)
+mostly use the same infrastructure as lint plugins, and provide examples of how
+to access type information.
+
+Lints defined by plugins are controlled by the usual [attributes and compiler
+flags](../reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or
+`-A test-lint`. These identifiers are derived from the first argument to
+`declare_lint!`, with appropriate case and punctuation conversion.
+
+You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
+including those provided by plugins loaded by `foo.rs`.
diff --git a/src/doc/trpl/compound-data-types.md b/src/doc/trpl/compound-data-types.md
deleted file mode 100644 (file)
index e44d2ed..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-% Compound Data Types
-
-Rust, like many programming languages, has a number of different data types
-that are built-in. You've already done some simple work with integers and
-strings, but next, let's talk about some more complicated ways of storing data.
-
-## Tuples
-
-The first compound data type we're going to talk about is called the *tuple*.
-A tuple is an ordered list of fixed size. Like this:
-
-```rust
-let x = (1, "hello");
-```
-
-The parentheses and commas form this two-length tuple. Here's the same code, but
-with the type annotated:
-
-```rust
-let x: (i32, &str) = (1, "hello");
-```
-
-As you can see, the type of a tuple looks just like the tuple, but with each
-position having a type name rather than the value. Careful readers will also
-note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple.
-You have briefly seen `&str` used as a type before, and we'll discuss the
-details of strings later. In systems programming languages, strings are a bit
-more complex than in other languages. For now, just read `&str` as a *string
-slice*, and we'll learn more soon.
-
-You can access the fields in a tuple through a *destructuring let*. Here's
-an example:
-
-```rust
-let (x, y, z) = (1, 2, 3);
-
-println!("x is {}", x);
-```
-
-Remember before when I said the left-hand side of a `let` statement was more
-powerful than just assigning a binding? Here we are. We can put a pattern on
-the left-hand side of the `let`, and if it matches up to the right-hand side,
-we can assign multiple bindings at once. In this case, `let` "destructures,"
-or "breaks up," the tuple, and assigns the bits to three bindings.
-
-This pattern is very powerful, and we'll see it repeated more later.
-
-There are also a few things you can do with a tuple as a whole, without
-destructuring. You can assign one tuple into another, if they have the same
-contained types and [arity]. Tuples have the same arity when they have the same
-length.
-
-```rust
-let mut x = (1, 2); // x: (i32, i32)
-let y = (2, 3); // y: (i32, i32)
-
-x = y;
-```
-
-You can also check for equality with `==`. Again, this will only compile if the
-tuples have the same type.
-
-```rust
-let x = (1, 2, 3);
-let y = (2, 2, 4);
-
-if x == y {
-    println!("yes");
-} else {
-    println!("no");
-}
-```
-
-This will print `no`, because some of the values aren't equal.
-
-Note that the order of the values is considered when checking for equality,
-so the following example will also print `no`.
-
-```rust
-let x = (1, 2, 3);
-let y = (2, 1, 3);
-
-if x == y {
-    println!("yes");
-} else {
-    println!("no");
-}
-```
-
-One other use of tuples is to return multiple values from a function:
-
-```rust
-fn next_two(x: i32) -> (i32, i32) { (x + 1, x + 2) }
-
-fn main() {
-    let (x, y) = next_two(5);
-    println!("x, y = {}, {}", x, y);
-}
-```
-
-Even though Rust functions can only return one value, a tuple *is* one value,
-that happens to be made up of more than one value. You can also see in this
-example how you can destructure a pattern returned by a function, as well.
-
-Tuples are a very simple data structure, and so are not often what you want.
-Let's move on to their bigger sibling, structs.
-
-## Structs
-
-A struct is another form of a *record type*, just like a tuple. There's a
-difference: structs give each element that they contain a name, called a
-*field* or a *member*. Check it out:
-
-```rust
-struct Point {
-    x: i32,
-    y: i32,
-}
-
-fn main() {
-    let origin = Point { x: 0, y: 0 }; // origin: Point
-
-    println!("The origin is at ({}, {})", origin.x, origin.y);
-}
-```
-
-There's a lot going on here, so let's break it down. We declare a struct with
-the `struct` keyword, and then with a name. By convention, structs begin with a
-capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
-
-We can create an instance of our struct via `let`, as usual, but we use a `key:
-value` style syntax to set each field. The order doesn't need to be the same as
-in the original declaration.
-
-Finally, because fields have names, we can access the field through dot
-notation: `origin.x`.
-
-The values in structs are immutable by default, like other bindings in Rust.
-Use `mut` to make them mutable:
-
-```{rust}
-struct Point {
-    x: i32,
-    y: i32,
-}
-
-fn main() {
-    let mut point = Point { x: 0, y: 0 };
-
-    point.x = 5;
-
-    println!("The point is at ({}, {})", point.x, point.y);
-}
-```
-
-This will print `The point is at (5, 0)`.
-
-## Tuple Structs and Newtypes
-
-Rust has another data type that's like a hybrid between a tuple and a struct,
-called a *tuple struct*. Tuple structs do have a name, but their fields don't:
-
-
-```{rust}
-struct Color(i32, i32, i32);
-struct Point(i32, i32, i32);
-```
-
-These two will not be equal, even if they have the same values:
-
-```{rust}
-# struct Color(i32, i32, i32);
-# struct Point(i32, i32, i32);
-let black = Color(0, 0, 0);
-let origin = Point(0, 0, 0);
-```
-
-It is almost always better to use a struct than a tuple struct. We would write
-`Color` and `Point` like this instead:
-
-```{rust}
-struct Color {
-    red: i32,
-    blue: i32,
-    green: i32,
-}
-
-struct Point {
-    x: i32,
-    y: i32,
-    z: i32,
-}
-```
-
-Now, we have actual names, rather than positions. Good names are important,
-and with a struct, we have actual names.
-
-There _is_ one case when a tuple struct is very useful, though, and that's a
-tuple struct with only one element. We call this the *newtype* pattern, because
-it allows you to create a new type, distinct from that of its contained value
-and expressing its own semantic meaning:
-
-```{rust}
-struct Inches(i32);
-
-let length = Inches(10);
-
-let Inches(integer_length) = length;
-println!("length is {} inches", integer_length);
-```
-
-As you can see here, you can extract the inner integer type through a
-destructuring `let`, as we discussed previously in 'tuples.' In this case, the
-`let Inches(integer_length)` assigns `10` to `integer_length`.
-
-## Enums
-
-Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
-feature of Rust, and are used throughout the standard library. An `enum` is
-a type which relates a set of alternates to a specific name. For example, below
-we define `Character` to be either a `Digit` or something else. These
-can be used via their fully scoped names: `Character::Other` (more about `::`
-below).
-
-```rust
-enum Character {
-    Digit(i32),
-    Other,
-}
-```
-
-Most normal types are allowed as the variant components of an `enum`. Here are
-some examples:
-
-```rust
-struct Empty;
-struct Color(i32, i32, i32);
-struct Length(i32);
-struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
-struct HeightDatabase(Vec<i32>);
-```
-
-You see that, depending on its type, an `enum` variant may or may not hold data.
-In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
-value, where `Other` is only a name. However, the fact that they represent
-distinct categories of `Character` is a very useful property.
-
-As with structures, the variants of an enum by default are not comparable with
-equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
-support other binary operations such as `*` and `+`. As such, the following code
-is invalid for the example `Character` type:
-
-```{rust,ignore}
-// These assignments both succeed
-let ten  = Character::Digit(10);
-let four = Character::Digit(4);
-
-// Error: `*` is not implemented for type `Character`
-let forty = ten * four;
-
-// Error: `<=` is not implemented for type `Character`
-let four_is_smaller = four <= ten;
-
-// Error: `==` is not implemented for type `Character`
-let four_equals_ten = four == ten;
-```
-
-This may seem rather limiting, but it's a limitation which we can overcome.
-There are two ways: by implementing equality ourselves, or by pattern matching
-variants with [`match`][match] expressions, which you'll learn in the next
-chapter. We don't know enough about Rust to implement equality yet, but we can
-use the `Ordering` enum from the standard library, which does:
-
-```
-enum Ordering {
-    Less,
-    Equal,
-    Greater,
-}
-```
-
-Because `Ordering` has already been defined for us, we will import it with the
-`use` keyword. Here's an example of how it is used:
-
-```{rust}
-use std::cmp::Ordering;
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    let ordering = cmp(x, y); // ordering: Ordering
-
-    if ordering == Ordering::Less {
-        println!("less");
-    } else if ordering == Ordering::Greater {
-        println!("greater");
-    } else if ordering == Ordering::Equal {
-        println!("equal");
-    }
-}
-```
-
-The `::` symbol is used to indicate a namespace. In this case, `Ordering` lives
-in the `cmp` submodule of the `std` module. We'll talk more about modules later
-in the guide. For now, all you need to know is that you can `use` things from
-the standard library if you need them.
-
-Okay, let's talk about the actual code in the example. `cmp` is a function that
-compares two things, and returns an `Ordering`. We return either
-`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
-whether the first value is less than, greater than, or equal to the second. Note
-that each variant of the `enum` is namespaced under the `enum` itself: it's
-`Ordering::Greater`, not `Greater`.
-
-The `ordering` variable has the type `Ordering`, and so contains one of the
-three values. We then do a bunch of `if`/`else` comparisons to check which
-one it is.
-
-This `Ordering::Greater` notation is too long. Let's use another form of `use`
-to import the `enum` variants instead. This will avoid full scoping:
-
-```{rust}
-use std::cmp::Ordering::{self, Equal, Less, Greater};
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    let ordering = cmp(x, y); // ordering: Ordering
-
-    if ordering == Less { println!("less"); }
-    else if ordering == Greater { println!("greater"); }
-    else if ordering == Equal { println!("equal"); }
-}
-```
-
-Importing variants is convenient and compact, but can also cause name conflicts,
-so do this with caution. For this reason, it's normally considered better style
-to `use` an enum rather than its variants directly.
-
-As you can see, `enum`s are quite a powerful tool for data representation, and
-are even more useful when they're [generic][generics] across types. Before we
-get to generics, though, let's talk about how to use enums with pattern
-matching, a tool that will let us deconstruct sum types (the type theory term
-for enums) like `Ordering` in a very elegant way that avoids all these messy
-and brittle `if`/`else`s.
-
-
-[arity]: ./glossary.html#arity
-[match]: ./match.html
-[generics]: ./generics.html
diff --git a/src/doc/trpl/conclusion.md b/src/doc/trpl/conclusion.md
deleted file mode 100644 (file)
index 9afddb1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-% Conclusion
-
-We covered a lot of ground here. When you've mastered everything in this Guide,
-you will have a firm grasp of Rust development. There's a whole lot more
-out there, though, we've just covered the surface. There's tons of topics that
-you can dig deeper into, e.g. by reading the API documentation of the
-[standard library](http://doc.rust-lang.org/std/), by discovering solutions for
-common problems on [Rust by Example](http://rustbyexample.com/), or by browsing
-crates written by the community on [crates.io](https://crates.io/).
-
-Happy hacking!
diff --git a/src/doc/trpl/conditional-compilation.md b/src/doc/trpl/conditional-compilation.md
new file mode 100644 (file)
index 0000000..40367fa
--- /dev/null
@@ -0,0 +1,3 @@
+% Conditional Compilation
+
+Coming Soon!
diff --git a/src/doc/trpl/const.md b/src/doc/trpl/const.md
new file mode 100644 (file)
index 0000000..9234c4f
--- /dev/null
@@ -0,0 +1,3 @@
+% `const`
+
+Coming soon!
diff --git a/src/doc/trpl/debug-and-display.md b/src/doc/trpl/debug-and-display.md
new file mode 100644 (file)
index 0000000..6c8d788
--- /dev/null
@@ -0,0 +1,3 @@
+% `Debug` and `Display`
+
+Coming soon!
diff --git a/src/doc/trpl/deref-coercions.md b/src/doc/trpl/deref-coercions.md
new file mode 100644 (file)
index 0000000..afacd30
--- /dev/null
@@ -0,0 +1,3 @@
+% `Deref` coercions
+
+Coming soon!
diff --git a/src/doc/trpl/drop.md b/src/doc/trpl/drop.md
new file mode 100644 (file)
index 0000000..af58e23
--- /dev/null
@@ -0,0 +1,3 @@
+% `Drop`
+
+Coming soon!
diff --git a/src/doc/trpl/effective-rust.md b/src/doc/trpl/effective-rust.md
new file mode 100644 (file)
index 0000000..6ea0759
--- /dev/null
@@ -0,0 +1 @@
+% Effective Rust
diff --git a/src/doc/trpl/enums.md b/src/doc/trpl/enums.md
new file mode 100644 (file)
index 0000000..cbb74d9
--- /dev/null
@@ -0,0 +1,149 @@
+% Enums
+
+Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
+feature of Rust, and are used throughout the standard library. An `enum` is
+a type which relates a set of alternates to a specific name. For example, below
+we define `Character` to be either a `Digit` or something else. These
+can be used via their fully scoped names: `Character::Other` (more about `::`
+below).
+
+```rust
+enum Character {
+    Digit(i32),
+    Other,
+}
+```
+
+Most normal types are allowed as the variant components of an `enum`. Here are
+some examples:
+
+```rust
+struct Empty;
+struct Color(i32, i32, i32);
+struct Length(i32);
+struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
+struct HeightDatabase(Vec<i32>);
+```
+
+You see that, depending on its type, an `enum` variant may or may not hold data.
+In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
+value, where `Other` is only a name. However, the fact that they represent
+distinct categories of `Character` is a very useful property.
+
+As with structures, the variants of an enum by default are not comparable with
+equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
+support other binary operations such as `*` and `+`. As such, the following code
+is invalid for the example `Character` type:
+
+```{rust,ignore}
+// These assignments both succeed
+let ten  = Character::Digit(10);
+let four = Character::Digit(4);
+
+// Error: `*` is not implemented for type `Character`
+let forty = ten * four;
+
+// Error: `<=` is not implemented for type `Character`
+let four_is_smaller = four <= ten;
+
+// Error: `==` is not implemented for type `Character`
+let four_equals_ten = four == ten;
+```
+
+This may seem rather limiting, but it's a limitation which we can overcome.
+There are two ways: by implementing equality ourselves, or by pattern matching
+variants with [`match`][match] expressions, which you'll learn in the next
+chapter. We don't know enough about Rust to implement equality yet, but we can
+use the `Ordering` enum from the standard library, which does:
+
+```
+enum Ordering {
+    Less,
+    Equal,
+    Greater,
+}
+```
+
+Because `Ordering` has already been defined for us, we will import it with the
+`use` keyword. Here's an example of how it is used:
+
+```{rust}
+use std::cmp::Ordering;
+
+fn cmp(a: i32, b: i32) -> Ordering {
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
+}
+
+fn main() {
+    let x = 5;
+    let y = 10;
+
+    let ordering = cmp(x, y); // ordering: Ordering
+
+    if ordering == Ordering::Less {
+        println!("less");
+    } else if ordering == Ordering::Greater {
+        println!("greater");
+    } else if ordering == Ordering::Equal {
+        println!("equal");
+    }
+}
+```
+
+The `::` symbol is used to indicate a namespace. In this case, `Ordering` lives
+in the `cmp` submodule of the `std` module. We'll talk more about modules later
+in the guide. For now, all you need to know is that you can `use` things from
+the standard library if you need them.
+
+Okay, let's talk about the actual code in the example. `cmp` is a function that
+compares two things, and returns an `Ordering`. We return either
+`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
+whether the first value is less than, greater than, or equal to the second. Note
+that each variant of the `enum` is namespaced under the `enum` itself: it's
+`Ordering::Greater`, not `Greater`.
+
+The `ordering` variable has the type `Ordering`, and so contains one of the
+three values. We then do a bunch of `if`/`else` comparisons to check which
+one it is.
+
+This `Ordering::Greater` notation is too long. Let's use another form of `use`
+to import the `enum` variants instead. This will avoid full scoping:
+
+```{rust}
+use std::cmp::Ordering::{self, Equal, Less, Greater};
+
+fn cmp(a: i32, b: i32) -> Ordering {
+    if a < b { Less }
+    else if a > b { Greater }
+    else { Equal }
+}
+
+fn main() {
+    let x = 5;
+    let y = 10;
+
+    let ordering = cmp(x, y); // ordering: Ordering
+
+    if ordering == Less { println!("less"); }
+    else if ordering == Greater { println!("greater"); }
+    else if ordering == Equal { println!("equal"); }
+}
+```
+
+Importing variants is convenient and compact, but can also cause name conflicts,
+so do this with caution. For this reason, it's normally considered better style
+to `use` an enum rather than its variants directly.
+
+As you can see, `enum`s are quite a powerful tool for data representation, and
+are even more useful when they're [generic][generics] across types. Before we
+get to generics, though, let's talk about how to use enums with pattern
+matching, a tool that will let us deconstruct sum types (the type theory term
+for enums) like `Ordering` in a very elegant way that avoids all these messy
+and brittle `if`/`else`s.
+
+
+[arity]: ./glossary.html#arity
+[match]: ./match.html
+[generics]: ./generics.html
diff --git a/src/doc/trpl/for-loops.md b/src/doc/trpl/for-loops.md
new file mode 100644 (file)
index 0000000..45ae5a2
--- /dev/null
@@ -0,0 +1,44 @@
+% `for` Loops
+
+The `for` loop is used to loop a particular number of times. Rust's `for` loops
+work a bit differently than in other systems languages, however. Rust's `for`
+loop doesn't look like this "C-style" `for` loop:
+
+```{c}
+for (x = 0; x < 10; x++) {
+    printf( "%d\n", x );
+}
+```
+
+Instead, it looks like this:
+
+```{rust}
+for x in 0..10 {
+    println!("{}", x); // x: i32
+}
+```
+
+In slightly more abstract terms,
+
+```{ignore}
+for var in expression {
+    code
+}
+```
+
+The expression is an iterator, which we will discuss in more depth later in the
+guide. The iterator gives back a series of elements. Each element is one
+iteration of the loop. That value is then bound to the name `var`, which is
+valid for the loop body. Once the body is over, the next value is fetched from
+the iterator, and we loop another time. When there are no more values, the
+`for` loop is over.
+
+In our example, `0..10` is an expression that takes a start and an end position,
+and gives an iterator over those values. The upper bound is exclusive, though,
+so our loop will print `0` through `9`, not `10`.
+
+Rust does not have the "C-style" `for` loop on purpose. Manually controlling
+each element of the loop is complicated and error prone, even for experienced C
+developers.
+
+We'll talk more about `for` when we cover *iterators*, later in the Guide.
diff --git a/src/doc/trpl/getting-started.md b/src/doc/trpl/getting-started.md
new file mode 100644 (file)
index 0000000..a164def
--- /dev/null
@@ -0,0 +1 @@
+% Getting Started
index a3b5d655fa78bb5ee41ff5bd4e44709690cfdbe5..f726f8627c929d24cf240f4b5a4b00e6f5bed732 100644 (file)
@@ -149,10 +149,10 @@ If you come from a dynamically typed language like Ruby, Python, or JavaScript,
 you may not be used to these two steps being separate. Rust is an
 *ahead-of-time compiled language*, which means that you can compile a
 program, give it to someone else, and they don't need to have Rust installed.
-If you give someone a `.rb` or `.py` or `.js` file, they need to have
-Ruby/Python/JavaScript installed, but you just need one command to both compile
-and run your program. Everything is a tradeoff in language design, and Rust has
-made its choice.
+If you give someone a `.rb` or `.py` or `.js` file, they need to have a
+Ruby/Python/JavaScript implementation installed, but you just need one command
+to both compile and run your program. Everything is a tradeoff in language design,
+and Rust has made its choice.
 
 Congratulations! You have officially written a Rust program. That makes you a
 Rust programmer! Welcome.
index 7dac49987d84908ac37dd4ce6cce80fdabfa3c6c..92f95341f814940fde7d73a72e4c8e22a9ae2862 100644 (file)
@@ -1,4 +1,4 @@
-% If
+% `if`
 
 Rust's take on `if` is not particularly complex, but it's much more like the
 `if` you'll find in a dynamically typed language than in a more traditional
@@ -153,3 +153,5 @@ instead.
 
 There's one more time in which you won't see a semicolon at the end of a line
 of Rust code. For that, we'll need our next concept: functions.
+
+TODO: `if let`
diff --git a/src/doc/trpl/intermediate.md b/src/doc/trpl/intermediate.md
deleted file mode 100644 (file)
index 73370a3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-% Intermediate
-
-This section contains individual chapters, which are self-contained. They focus
-on specific topics, and can be read in any order.
-
-After reading "Intermediate," you will have a solid understanding of Rust,
-and will be able to understand most Rust code and write more complex programs.
diff --git a/src/doc/trpl/learn-rust.md b/src/doc/trpl/learn-rust.md
new file mode 100644 (file)
index 0000000..e5482d3
--- /dev/null
@@ -0,0 +1 @@
+% Learn Rust
diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md
new file mode 100644 (file)
index 0000000..c6eee97
--- /dev/null
@@ -0,0 +1,3 @@
+% Lifetimes
+
+Coming soon!
diff --git a/src/doc/trpl/looping.md b/src/doc/trpl/looping.md
deleted file mode 100644 (file)
index 28f02b1..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-% Looping
-
-Looping is the last basic construct that we haven't learned yet in Rust. Rust has
-two main looping constructs: `for` and `while`.
-
-## `for`
-
-The `for` loop is used to loop a particular number of times. Rust's `for` loops
-work a bit differently than in other systems languages, however. Rust's `for`
-loop doesn't look like this "C-style" `for` loop:
-
-```{c}
-for (x = 0; x < 10; x++) {
-    printf( "%d\n", x );
-}
-```
-
-Instead, it looks like this:
-
-```{rust}
-for x in 0..10 {
-    println!("{}", x); // x: i32
-}
-```
-
-In slightly more abstract terms,
-
-```{ignore}
-for var in expression {
-    code
-}
-```
-
-The expression is an iterator, which we will discuss in more depth later in the
-guide. The iterator gives back a series of elements. Each element is one
-iteration of the loop. That value is then bound to the name `var`, which is
-valid for the loop body. Once the body is over, the next value is fetched from
-the iterator, and we loop another time. When there are no more values, the
-`for` loop is over.
-
-In our example, `0..10` is an expression that takes a start and an end position,
-and gives an iterator over those values. The upper bound is exclusive, though,
-so our loop will print `0` through `9`, not `10`.
-
-Rust does not have the "C-style" `for` loop on purpose. Manually controlling
-each element of the loop is complicated and error prone, even for experienced C
-developers.
-
-We'll talk more about `for` when we cover *iterators*, later in the Guide.
-
-## `while`
-
-The other kind of looping construct in Rust is the `while` loop. It looks like
-this:
-
-```{rust}
-let mut x = 5; // mut x: u32
-let mut done = false; // mut done: bool
-
-while !done {
-    x += x - 3;
-    println!("{}", x);
-    if x % 5 == 0 { done = true; }
-}
-```
-
-`while` loops are the correct choice when you're not sure how many times
-you need to loop.
-
-If you need an infinite loop, you may be tempted to write this:
-
-```{rust,ignore}
-while true {
-```
-
-However, Rust has a dedicated keyword, `loop`, to handle this case:
-
-```{rust,ignore}
-loop {
-```
-
-Rust's control-flow analysis treats this construct differently than a
-`while true`, since we know that it will always loop. The details of what
-that _means_ aren't super important to understand at this stage, but in
-general, the more information we can give to the compiler, the better it
-can do with safety and code generation, so you should always prefer
-`loop` when you plan to loop infinitely.
-
-## Ending iteration early
-
-Let's take a look at that `while` loop we had earlier:
-
-```{rust}
-let mut x = 5;
-let mut done = false;
-
-while !done {
-    x += x - 3;
-    println!("{}", x);
-    if x % 5 == 0 { done = true; }
-}
-```
-
-We had to keep a dedicated `mut` boolean variable binding, `done`, to know
-when we should exit out of the loop. Rust has two keywords to help us with
-modifying iteration: `break` and `continue`.
-
-In this case, we can write the loop in a better way with `break`:
-
-```{rust}
-let mut x = 5;
-
-loop {
-    x += x - 3;
-    println!("{}", x);
-    if x % 5 == 0 { break; }
-}
-```
-
-We now loop forever with `loop` and use `break` to break out early.
-
-`continue` is similar, but instead of ending the loop, goes to the next
-iteration. This will only print the odd numbers:
-
-```{rust}
-for x in 0..10 {
-    if x % 2 == 0 { continue; }
-
-    println!("{}", x);
-}
-```
-
-Both `continue` and `break` are valid in both kinds of loops.
index 7e19ec94ee745160e4fe01ecbcb47e056b43b81d..6d21cb59383c73beb6bfd62e34f81f9c9717ee71 100644 (file)
@@ -424,9 +424,240 @@ they are unstable and require feature gates.
 * `trace_macros!(true)` will enable a compiler message every time a macro is
   expanded. Use `trace_macros!(false)` later in expansion to turn it off.
 
-# Further reading
+# Syntactic requirements
 
-The [advanced macros chapter][] goes into more detail about macro syntax. It
-also describes how to share macros between different modules or crates.
+Even when Rust code contains un-expanded macros, it can be parsed as a full
+[syntax tree][ast]. This property can be very useful for editors and other
+tools that process code. It also has a few consequences for the design of
+Rust's macro system.
 
-[advanced macros chapter]: advanced-macros.html
+[ast]: glossary.html#abstract-syntax-tree
+
+One consequence is that Rust must determine, when it parses a macro invocation,
+whether the macro stands in for
+
+* zero or more items,
+* zero or more methods,
+* an expression,
+* a statement, or
+* a pattern.
+
+A macro invocation within a block could stand for some items, or for an
+expression / statement. Rust uses a simple rule to resolve this ambiguity. A
+macro invocation that stands for items must be either
+
+* delimited by curly braces, e.g. `foo! { ... }`, or
+* terminated by a semicolon, e.g. `foo!(...);`
+
+Another consequence of pre-expansion parsing is that the macro invocation must
+consist of valid Rust tokens. Furthermore, parentheses, brackets, and braces
+must be balanced within a macro invocation. For example, `foo!([)` is
+forbidden. This allows Rust to know where the macro invocation ends.
+
+More formally, the macro invocation body must be a sequence of *token trees*.
+A token tree is defined recursively as either
+
+* a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or
+* any other single token.
+
+Within a matcher, each metavariable has a *fragment specifier*, identifying
+which syntactic form it matches.
+
+* `ident`: an identifier. Examples: `x`; `foo`.
+* `path`: a qualified name. Example: `T::SpecialA`.
+* `expr`: an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`.
+* `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`.
+* `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`.
+* `stmt`: a single statement. Example: `let x = 3`.
+* `block`: a brace-delimited sequence of statements. Example:
+  `{ log(error, "hi"); return 12; }`.
+* `item`: an [item][]. Examples: `fn foo() { }`; `struct Bar;`.
+* `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`.
+* `tt`: a single token tree.
+
+There are additional rules regarding the next token after a metavariable:
+
+* `expr` variables must be followed by one of: `=> , ;`
+* `ty` and `path` variables must be followed by one of: `=> , : = > as`
+* `pat` variables must be followed by one of: `=> , =`
+* Other variables may be followed by any token.
+
+These rules provide some flexibility for Rust's syntax to evolve without
+breaking existing macros.
+
+The macro system does not deal with parse ambiguity at all. For example, the
+grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would
+be forced to choose between parsing `$t` and parsing `$e`. Changing the
+invocation syntax to put a distinctive token in front can solve the problem. In
+this case, you can write `$(T $t:ty)* E $e:exp`.
+
+[item]: ../reference.html#items
+
+# Scoping and macro import/export
+
+Macros are expanded at an early stage in compilation, before name resolution.
+One downside is that scoping works differently for macros, compared to other
+constructs in the language.
+
+Definition and expansion of macros both happen in a single depth-first,
+lexical-order traversal of a crate's source. So a macro defined at module scope
+is visible to any subsequent code in the same module, which includes the body
+of any subsequent child `mod` items.
+
+A macro defined within the body of a single `fn`, or anywhere else not at
+module scope, is visible only within that item.
+
+If a module has the `macro_use` attribute, its macros are also visible in its
+parent module after the child's `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parent's `mod`
+item, and so forth.
+
+The `macro_use` attribute can also appear on `extern crate`. In this context
+it controls which macros are loaded from the external crate, e.g.
+
+```rust,ignore
+#[macro_use(foo, bar)]
+extern crate baz;
+```
+
+If the attribute is given simply as `#[macro_use]`, all macros are loaded. If
+there is no `#[macro_use]` attribute then no macros are loaded. Only macros
+defined with the `#[macro_export]` attribute may be loaded.
+
+To load a crate's macros *without* linking it into the output, use `#[no_link]`
+as well.
+
+An example:
+
+```rust
+macro_rules! m1 { () => (()) }
+
+// visible here: m1
+
+mod foo {
+    // visible here: m1
+
+    #[macro_export]
+    macro_rules! m2 { () => (()) }
+
+    // visible here: m1, m2
+}
+
+// visible here: m1
+
+macro_rules! m3 { () => (()) }
+
+// visible here: m1, m3
+
+#[macro_use]
+mod bar {
+    // visible here: m1, m3
+
+    macro_rules! m4 { () => (()) }
+
+    // visible here: m1, m3, m4
+}
+
+// visible here: m1, m3, m4
+# fn main() { }
+```
+
+When this library is loaded with `#[macro_use] extern crate`, only `m2` will
+be imported.
+
+The Rust Reference has a [listing of macro-related
+attributes](../reference.html#macro--and-plugin-related-attributes).
+
+# The variable `$crate`
+
+A further difficulty occurs when a macro is used in multiple crates. Say that
+`mylib` defines
+
+```rust
+pub fn increment(x: u32) -> u32 {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! inc_a {
+    ($x:expr) => ( ::increment($x) )
+}
+
+#[macro_export]
+macro_rules! inc_b {
+    ($x:expr) => ( ::mylib::increment($x) )
+}
+# fn main() { }
+```
+
+`inc_a` only works within `mylib`, while `inc_b` only works outside the
+library. Furthermore, `inc_b` will break if the user imports `mylib` under
+another name.
+
+Rust does not (yet) have a hygiene system for crate references, but it does
+provide a simple workaround for this problem. Within a macro imported from a
+crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
+By contrast, when a macro is defined and then used in the same crate, `$crate`
+will expand to nothing. This means we can write
+
+```rust
+#[macro_export]
+macro_rules! inc {
+    ($x:expr) => ( $crate::increment($x) )
+}
+# fn main() { }
+```
+
+to define a single macro that works both inside and outside our library. The
+function name will expand to either `::increment` or `::mylib::increment`.
+
+To keep this system simple and correct, `#[macro_use] extern crate ...` may
+only appear at the root of your crate, not inside `mod`. This ensures that
+`$crate` is a single identifier.
+
+# The deep end
+
+The introductory chapter mentioned recursive macros, but it did not give the
+full story. Recursive macros are useful for another reason: Each recursive
+invocation gives you another opportunity to pattern-match the macro's
+arguments.
+
+As an extreme example, it is possible, though hardly advisable, to implement
+the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
+within Rust's macro system.
+
+```rust
+macro_rules! bct {
+    // cmd 0:  d ... => ...
+    (0, $($ps:tt),* ; $_d:tt)
+        => (bct!($($ps),*, 0 ; ));
+    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+        => (bct!($($ps),*, 0 ; $($ds),*));
+
+    // cmd 1p:  1 ... => 1 ... p
+    (1, $p:tt, $($ps:tt),* ; 1)
+        => (bct!($($ps),*, 1, $p ; 1, $p));
+    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+    // cmd 1p:  0 ... => 0 ...
+    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+    // halt on empty data string
+    ( $($ps:tt),* ; )
+        => (());
+}
+```
+
+Exercise: use macros to reduce duplication in the above definition of the
+`bct!` macro.
+
+# Procedural macros
+
+If Rust's macro system can't do what you need, you may want to write a
+[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
+macros, this is significantly more work, the interfaces are much less stable,
+and bugs can be much harder to track down. In exchange you get the
+flexibility of running arbitrary Rust code within the compiler. Syntax
+extension plugins are sometimes called *procedural macros* for this reason.
diff --git a/src/doc/trpl/more-strings.md b/src/doc/trpl/more-strings.md
deleted file mode 100644 (file)
index 17a4638..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-% More Strings
-
-Strings are an important concept to master in any programming language. If you
-come from a managed language background, you may be surprised at the complexity
-of string handling in a systems programming language. Efficient access and
-allocation of memory for a dynamically sized structure involves a lot of
-details. Luckily, Rust has lots of tools to help us here.
-
-A **string** is a sequence of unicode scalar values encoded as a stream of
-UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences.
-Additionally, strings are not null-terminated and can contain null bytes.
-
-Rust has two main types of strings: `&str` and `String`.
-
-# `&str`
-
-The first kind is a `&str`. This is pronounced a 'string slice'.
-String literals are of the type `&str`:
-
-```
-let string = "Hello there.";
-```
-
-Like any Rust reference, string slices have an associated lifetime. A string
-literal is a `&'static str`.  A string slice can be written without an explicit
-lifetime in many cases, such as in function arguments. In these cases the
-lifetime will be inferred:
-
-```
-fn takes_slice(slice: &str) {
-    println!("Got: {}", slice);
-}
-```
-
-Like vector slices, string slices are simply a pointer plus a length. This
-means that they're a 'view' into an already-allocated string, such as a
-string literal or a `String`.
-
-## `str`
-
-You may occasionally see references to a `str` type, without the `&`. While
-this type does exist, it’s not something you want to use yourself. Sometimes,
-people confuse `str` for `String`, and write this:
-
-```rust
-struct S {
-    s: str,
-}
-```
-
-This leads to ugly errors:
-
-```text
-error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
-note: `str` does not have a constant size known at compile-time
-```
-
-Instead, this `struct` should be
-
-```rust
-struct S {
-    s: String,
-}
-```
-
-So let’s talk about `String`s.
-
-# `String`
-
-A `String` is a heap-allocated string. This string is growable, and is
-also guaranteed to be UTF-8. `String`s are commonly created by
-converting from a string slice using the `to_string` method.
-
-```
-let mut s = "Hello".to_string();
-println!("{}", s);
-
-s.push_str(", world.");
-println!("{}", s);
-```
-
-A reference to a `String` will automatically coerce to a string slice:
-
-```
-fn takes_slice(slice: &str) {
-    println!("Got: {}", slice);
-}
-
-fn main() {
-    let s = "Hello".to_string();
-    takes_slice(&s);
-}
-```
-
-You can also get a `&str` from a stack-allocated array of bytes:
-
-```
-use std::str;
-
-let x: &[u8] = &[b'a', b'b'];
-let stack_str: &str = str::from_utf8(x).unwrap();
-```
-
-# Best Practices
-
-## `String` vs. `&str`
-
-In general, you should prefer `String` when you need ownership, and `&str` when
-you just need to borrow a string. This is very similar to using `Vec<T>` vs. `&[T]`,
-and `T` vs `&T` in general.
-
-This means starting off with this:
-
-```{rust,ignore}
-fn foo(s: &str) {
-```
-
-and only moving to this:
-
-```{rust,ignore}
-fn foo(s: String) {
-```
-
-if you have good reason. It's not polite to hold on to ownership you don't
-need, and it can make your lifetimes more complex.
-
-## Generic functions
-
-To write a function that's generic over types of strings, use `&str`.
-
-```
-fn some_string_length(x: &str) -> usize {
-    x.len()
-}
-
-fn main() {
-    let s = "Hello, world";
-
-    println!("{}", some_string_length(s));
-
-    let s = "Hello, world".to_string();
-
-    println!("{}", some_string_length(&s));
-}
-```
-
-Both of these lines will print `12`.
-
-## Indexing strings
-
-You may be tempted to try to access a certain character of a `String`, like
-this:
-
-```{rust,ignore}
-let s = "hello".to_string();
-
-println!("{}", s[0]);
-```
-
-This does not compile. This is on purpose. In the world of UTF-8, direct
-indexing is basically never what you want to do. The reason is that each
-character can be a variable number of bytes. This means that you have to iterate
-through the characters anyway, which is an O(n) operation.
-
-There's 3 basic levels of unicode (and its encodings):
-
-- code units, the underlying data type used to store everything
-- code points/unicode scalar values (char)
-- graphemes (visible characters)
-
-Rust provides iterators for each of these situations:
-
-- `.bytes()` will iterate over the underlying bytes
-- `.chars()` will iterate over the code points
-- `.graphemes()` will iterate over each grapheme
-
-Usually, the `graphemes()` method on `&str` is what you want:
-
-```
-# #![feature(unicode)]
-let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé";
-
-for l in s.graphemes(true) {
-    println!("{}", l);
-}
-```
-
-This prints:
-
-```text
-u͔
-n͈̰̎
-i̙̮͚̦
-c͚̉
-o̼̩̰͗
-d͔̆̓ͥ
-é
-```
-
-Note that `l` has the type `&str` here, since a single grapheme can consist of
-multiple codepoints, so a `char` wouldn't be appropriate.
-
-This will print out each visible character in turn, as you'd expect: first `u͔`, then
-`n͈̰̎`, etc. If you wanted each individual codepoint of each grapheme, you can use `.chars()`:
-
-```
-let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé";
-
-for l in s.chars() {
-    println!("{}", l);
-}
-```
-
-This prints:
-
-```text
-u
-n
-i
-c
-o
-d
-e
-```
-
-You can see how some of them are combining characters, and therefore the output
-looks a bit odd.
-
-If you want the individual byte representation of each codepoint, you can use
-`.bytes()`:
-
-```
-let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé";
-
-for l in s.bytes() {
-    println!("{}", l);
-}
-```
-
-This will print:
-
-```text
-117
-205
-148
-110
-204
-142
-205
-136
-204
-176
-105
-204
-153
-204
-174
-205
-154
-204
-166
-99
-204
-137
-205
-154
-111
-205
-151
-204
-188
-204
-169
-204
-176
-100
-204
-134
-205
-131
-205
-165
-205
-148
-101
-204
-129
-```
-
-Many more bytes than graphemes!
-
-# `Deref` coercions
-
-References to `String`s will automatically coerce into `&str`s. Like this:
-
-```
-fn hello(s: &str) {
-   println!("Hello, {}!", s);
-}
-
-let slice = "Steve";
-let string = "Steve".to_string();
-
-hello(slice);
-hello(&string);
-```
diff --git a/src/doc/trpl/move-semantics.md b/src/doc/trpl/move-semantics.md
new file mode 100644 (file)
index 0000000..6917d7f
--- /dev/null
@@ -0,0 +1,3 @@
+% Move Semantics
+
+Coming Soon
diff --git a/src/doc/trpl/mutability.md b/src/doc/trpl/mutability.md
new file mode 100644 (file)
index 0000000..ccb03c7
--- /dev/null
@@ -0,0 +1,3 @@
+% Mutability
+
+Coming Soon
diff --git a/src/doc/trpl/nightly-rust.md b/src/doc/trpl/nightly-rust.md
new file mode 100644 (file)
index 0000000..1b58b73
--- /dev/null
@@ -0,0 +1,51 @@
+% Nightly Rust
+
+Rust provides three distribution channels for Rust: nightly, beta, and stable.
+Unstable features are only available on nightly Rust. For more details on this
+process, see [this post](http://blog.rust-lang.org/2014/10/30/Stability.html).
+
+To install nightly Rust, you can use `rustup.sh`:
+
+```bash
+$ curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly
+```
+
+If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
+please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
+
+```bash
+$ curl -f -L https://static.rust-lang.org/rustup.sh -O
+$ sudo sh rustup.sh --channel=nightly
+```
+
+If you're on Windows, please download either the [32-bit
+installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe)
+or the [64-bit
+installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe)
+and run it.
+
+If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
+Not every programming language is great for everyone. Just run the uninstall
+script:
+
+```bash
+$ sudo /usr/local/lib/rustlib/uninstall.sh
+```
+
+If you used the Windows installer, just re-run the `.exe` and it will give you
+an uninstall option.
+
+You can re-run this script any time you want to update Rust. Which, at this
+point, is often. Rust is still pre-1.0, and so people assume that you're using
+a very recent Rust.
+
+This brings me to one other point: some people, and somewhat rightfully so, get
+very upset when we tell you to `curl | sudo sh`. And they should be! Basically,
+when you do this, you are trusting that the good people who maintain Rust
+aren't going to hack your computer and do bad things. That's a good instinct!
+If you're one of those people, please check out the documentation on [building
+Rust from Source](https://github.com/rust-lang/rust#building-from-source), or
+[the official binary downloads](http://www.rust-lang.org/install.html). And we
+promise that this method will not be the way to install Rust forever: it's just
+the easiest way to keep people updated while Rust is in its alpha state.
+
diff --git a/src/doc/trpl/operators-and-overloading.md b/src/doc/trpl/operators-and-overloading.md
new file mode 100644 (file)
index 0000000..f6f9d5c
--- /dev/null
@@ -0,0 +1,3 @@
+% Operators and Overloading
+
+Coming soon!
diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md
deleted file mode 100644 (file)
index 9eb22a7..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-% Compiler Plugins
-
-# Introduction
-
-`rustc` can load compiler plugins, which are user-provided libraries that
-extend the compiler's behavior with new syntax extensions, lint checks, etc.
-
-A plugin is a dynamic library crate with a designated *registrar* function that
-registers extensions with `rustc`. Other crates can load these extensions using
-the crate attribute `#![plugin(...)]`.  See the
-[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
-mechanics of defining and loading a plugin.
-
-If present, arguments passed as `#![plugin(foo(... args ...))]` are not
-interpreted by rustc itself.  They are provided to the plugin through the
-`Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
-
-In the vast majority of cases, a plugin should *only* be used through
-`#![plugin]` and not through an `extern crate` item.  Linking a plugin would
-pull in all of libsyntax and librustc as dependencies of your crate.  This is
-generally unwanted unless you are building another plugin.  The
-`plugin_as_library` lint checks these guidelines.
-
-The usual practice is to put compiler plugins in their own crate, separate from
-any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
-of a library.
-
-# Syntax extensions
-
-Plugins can extend Rust's syntax in various ways. One kind of syntax extension
-is the procedural macro. These are invoked the same way as [ordinary
-macros](macros.html), but the expansion is performed by arbitrary Rust
-code that manipulates [syntax trees](../syntax/ast/index.html) at
-compile time.
-
-Let's write a plugin
-[`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs)
-that implements Roman numeral integer literals.
-
-```ignore
-#![crate_type="dylib"]
-#![feature(plugin_registrar, rustc_private)]
-
-extern crate syntax;
-extern crate rustc;
-
-use syntax::codemap::Span;
-use syntax::parse::token;
-use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
-use syntax::ext::build::AstBuilder;  // trait for expr_usize
-use rustc::plugin::Registry;
-
-fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
-        -> Box<MacResult + 'static> {
-
-    static NUMERALS: &'static [(&'static str, u32)] = &[
-        ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
-        ("C",  100), ("XC",  90), ("L",  50), ("XL",  40),
-        ("X",   10), ("IX",   9), ("V",   5), ("IV",   4),
-        ("I",    1)];
-
-    let text = match args {
-        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
-        _ => {
-            cx.span_err(sp, "argument should be a single identifier");
-            return DummyResult::any(sp);
-        }
-    };
-
-    let mut text = &*text;
-    let mut total = 0;
-    while !text.is_empty() {
-        match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
-            Some(&(rn, val)) => {
-                total += val;
-                text = &text[rn.len()..];
-            }
-            None => {
-                cx.span_err(sp, "invalid Roman numeral");
-                return DummyResult::any(sp);
-            }
-        }
-    }
-
-    MacEager::expr(cx.expr_u32(sp, total))
-}
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_macro("rn", expand_rn);
-}
-```
-
-Then we can use `rn!()` like any other macro:
-
-```ignore
-#![feature(plugin)]
-#![plugin(roman_numerals)]
-
-fn main() {
-    assert_eq!(rn!(MMXV), 2015);
-}
-```
-
-The advantages over a simple `fn(&str) -> u32` are:
-
-* The (arbitrarily complex) conversion is done at compile time.
-* Input validation is also performed at compile time.
-* It can be extended to allow use in patterns, which effectively gives
-  a way to define new literal syntax for any data type.
-
-In addition to procedural macros, you can define new
-[`derive`](../reference.html#derive)-like attributes and other kinds of
-extensions.  See
-[`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension)
-and the [`SyntaxExtension`
-enum](http://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html).  For
-a more involved macro example, see
-[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs).
-
-
-## Tips and tricks
-
-Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable.
-
-You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into
-higher-level syntax elements like expressions:
-
-```ignore
-fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
-        -> Box<MacResult+'static> {
-
-    let mut parser = cx.new_parser_from_tts(args);
-
-    let expr: P<Expr> = parser.parse_expr();
-```
-
-Looking through [`libsyntax` parser
-code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs)
-will give you a feel for how the parsing infrastructure works.
-
-Keep the [`Span`s](../syntax/codemap/struct.Span.html) of
-everything you parse, for better error reporting. You can wrap
-[`Spanned`](../syntax/codemap/struct.Spanned.html) around
-your custom data structures.
-
-Calling
-[`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal)
-will immediately abort compilation. It's better to instead call
-[`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err)
-and return
-[`DummyResult`](../syntax/ext/base/struct.DummyResult.html),
-so that the compiler can continue and find further errors.
-
-To print syntax fragments for debugging, you can use
-[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together
-with
-[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions).
-
-The example above produced an integer literal using
-[`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize).
-As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
-[quasiquote macros](../syntax/ext/quote/index.html).  They are undocumented and
-very rough around the edges.  However, the implementation may be a good
-starting point for an improved quasiquote as an ordinary plugin library.
-
-
-# Lint plugins
-
-Plugins can extend [Rust's lint
-infrastructure](../reference.html#lint-check-attributes) with additional checks for
-code style, safety, etc. You can see
-[`src/test/auxiliary/lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs)
-for a full example, the core of which is reproduced here:
-
-```ignore
-declare_lint!(TEST_LINT, Warn,
-              "Warn about items named 'lintme'")
-
-struct Pass;
-
-impl LintPass for Pass {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(TEST_LINT)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let name = token::get_ident(it.ident);
-        if name.get() == "lintme" {
-            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
-        }
-    }
-}
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_lint_pass(box Pass as LintPassObject);
-}
-```
-
-Then code like
-
-```ignore
-#![plugin(lint_plugin_test)]
-
-fn lintme() { }
-```
-
-will produce a compiler warning:
-
-```txt
-foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
-foo.rs:4 fn lintme() { }
-         ^~~~~~~~~~~~~~~
-```
-
-The components of a lint plugin are:
-
-* one or more `declare_lint!` invocations, which define static
-  [`Lint`](../rustc/lint/struct.Lint.html) structs;
-
-* a struct holding any state needed by the lint pass (here, none);
-
-* a [`LintPass`](../rustc/lint/trait.LintPass.html)
-  implementation defining how to check each syntax element. A single
-  `LintPass` may call `span_lint` for several different `Lint`s, but should
-  register them all through the `get_lints` method.
-
-Lint passes are syntax traversals, but they run at a late stage of compilation
-where type information is available. `rustc`'s [built-in
-lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs)
-mostly use the same infrastructure as lint plugins, and provide examples of how
-to access type information.
-
-Lints defined by plugins are controlled by the usual [attributes and compiler
-flags](../reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or
-`-A test-lint`. These identifiers are derived from the first argument to
-`declare_lint!`, with appropriate case and punctuation conversion.
-
-You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
-including those provided by plugins loaded by `foo.rs`.
diff --git a/src/doc/trpl/pointers.md b/src/doc/trpl/pointers.md
deleted file mode 100644 (file)
index 1b3f2a5..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-% Pointers
-
-Rust's pointers are one of its more unique and compelling features. Pointers
-are also one of the more confusing topics for newcomers to Rust. They can also
-be confusing for people coming from other languages that support pointers, such
-as C++. This guide will help you understand this important topic.
-
-Be sceptical of non-reference pointers in Rust: use them for a deliberate
-purpose, not just to make the compiler happy. Each pointer type comes with an
-explanation about when they are appropriate to use. Default to references
-unless you're in one of those specific situations.
-
-You may be interested in the [cheat sheet](#cheat-sheet), which gives a quick
-overview of the types, names, and purpose of the various pointers.
-
-# An introduction
-
-If you aren't familiar with the concept of pointers, here's a short
-introduction.  Pointers are a very fundamental concept in systems programming
-languages, so it's important to understand them.
-
-## Pointer Basics
-
-When you create a new variable binding, you're giving a name to a value that's
-stored at a particular location on the stack. (If you're not familiar with the
-*heap* vs. *stack*, please check out [this Stack Overflow
-question](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap),
-as the rest of this guide assumes you know the difference.) Like this:
-
-```{rust}
-let x = 5;
-let y = 8;
-```
-
-| location | value |
-|----------|-------|
-| 0xd3e030 | 5    |
-| 0xd3e028 | 8     |
-
-We're making up memory locations here, they're just sample values. Anyway, the
-point is that `x`, the name we're using for our variable, corresponds to the
-memory location `0xd3e030`, and the value at that location is `5`. When we
-refer to `x`, we get the corresponding value. Hence, `x` is `5`.
-
-Let's introduce a pointer. In some languages, there is just one type of
-'pointer,' but in Rust, we have many types. In this case, we'll use a Rust
-*reference*, which is the simplest kind of pointer.
-
-```{rust}
-let x = 5;
-let y = 8;
-let z = &y;
-```
-
-|location | value    |
-|-------- |----------|
-|0xd3e030 | 5        |
-|0xd3e028 | 8        |
-|0xd3e020 | 0xd3e028 |
-
-See the difference? Rather than contain a value, the value of a pointer is a
-location in memory. In this case, the location of `y`. `x` and `y` have the
-type `i32`, but `z` has the type `&i32`. We can print this location using the
-`{:p}` format string:
-
-```{rust}
-let x = 5;
-let y = 8;
-let z = &y;
-
-println!("{:p}", z);
-```
-
-This would print `0xd3e028`, with our fictional memory addresses.
-
-Because `i32` and `&i32` are different types, we can't, for example, add them
-together:
-
-```{rust,ignore}
-let x = 5;
-let y = 8;
-let z = &y;
-
-println!("{}", x + z);
-```
-
-This gives us an error:
-
-```text
-hello.rs:6:24: 6:25 error: mismatched types: expected `_`, found `&_` (expected integral variable, found &-ptr)
-hello.rs:6     println!("{}", x + z);
-                                  ^
-```
-
-We can *dereference* the pointer by using the `*` operator. Dereferencing a
-pointer means accessing the value at the location stored in the pointer. This
-will work:
-
-```{rust}
-let x = 5;
-let y = 8;
-let z = &y;
-
-println!("{}", x + *z);
-```
-
-It prints `13`.
-
-That's it! That's all pointers are: they point to some memory location. Not
-much else to them. Now that we've discussed the *what* of pointers, let's
-talk about the *why*.
-
-## Pointer uses
-
-Rust's pointers are quite useful, but in different ways than in other systems
-languages. We'll talk about best practices for Rust pointers later in
-the guide, but here are some ways that pointers are useful in other languages:
-
-In C, strings are a pointer to a list of `char`s, ending with a null byte.
-The only way to use strings is to get quite familiar with pointers.
-
-Pointers are useful to point to memory locations that are not on the stack. For
-example, our example used two stack variables, so we were able to give them
-names. But if we allocated some heap memory, we wouldn't have that name
-available.  In C, `malloc` is used to allocate heap memory, and it returns a
-pointer.
-
-As a more general variant of the previous two points, any time you have a
-structure that can change in size, you need a pointer. You can't tell at
-compile time how much memory to allocate, so you've gotta use a pointer to
-point at the memory where it will be allocated, and deal with it at run time.
-
-Pointers are useful in languages that are pass-by-value, rather than
-pass-by-reference. Basically, languages can make two choices (this is made
-up syntax, it's not Rust):
-
-```text
-func foo(x) {
-    x = 5
-}
-
-func main() {
-    i = 1
-    foo(i)
-    // what is the value of i here?
-}
-```
-
-In languages that are pass-by-value, `foo` will get a copy of `i`, and so
-the original version of `i` is not modified. At the comment, `i` will still be
-`1`. In a language that is pass-by-reference, `foo` will get a reference to `i`,
-and therefore, can change its value. At the comment, `i` will be `5`.
-
-So what do pointers have to do with this? Well, since pointers point to a
-location in memory...
-
-```text
-func foo(&i32 x) {
-    *x = 5
-}
-
-func main() {
-    i = 1
-    foo(&i)
-    // what is the value of i here?
-}
-```
-
-Even in a language which is pass by value, `i` will be `5` at the comment. You
-see, because the argument `x` is a pointer, we do send a copy over to `foo`,
-but because it points at a memory location, which we then assign to, the
-original value is still changed. This pattern is called
-*pass-reference-by-value*. Tricky!
-
-## Common pointer problems
-
-We've talked about pointers, and we've sung their praises. So what's the
-downside? Well, Rust attempts to mitigate each of these kinds of problems,
-but here are problems with pointers in other languages:
-
-Uninitialized pointers can cause a problem. For example, what does this program
-do?
-
-```{ignore}
-&int x;
-*x = 5; // whoops!
-```
-
-Who knows? We just declare a pointer, but don't point it at anything, and then
-set the memory location that it points at to be `5`. But which location? Nobody
-knows. This might be harmless, and it might be catastrophic.
-
-When you combine pointers and functions, it's easy to accidentally invalidate
-the memory the pointer is pointing to. For example:
-
-```text
-func make_pointer(): &int {
-    x = 5;
-
-    return &x;
-}
-
-func main() {
-    &int i = make_pointer();
-    *i = 5; // uh oh!
-}
-```
-
-`x` is local to the `make_pointer` function, and therefore, is invalid as soon
-as `make_pointer` returns. But we return a pointer to its memory location, and
-so back in `main`, we try to use that pointer, and it's a very similar
-situation to our first one. Setting invalid memory locations is bad.
-
-As one last example of a big problem with pointers, *aliasing* can be an
-issue. Two pointers are said to alias when they point at the same location
-in memory. Like this:
-
-```text
-func mutate(&int i, int j) {
-    *i = j;
-}
-
-func main() {
-  x = 5;
-  y = &x;
-  z = &x; //y and z are aliased
-
-
-  run_in_new_thread(mutate, y, 1);
-  run_in_new_thread(mutate, z, 100);
-
-  // what is the value of x here?
-}
-```
-
-In this made-up example, `run_in_new_thread` spins up a new thread, and calls
-the given function name with its arguments. Since we have two threads, and
-they're both operating on aliases to `x`, we can't tell which one finishes
-first, and therefore, the value of `x` is actually non-deterministic. Worse,
-what if one of them had invalidated the memory location they pointed to? We'd
-have the same problem as before, where we'd be setting an invalid location.
-
-## Conclusion
-
-That's a basic overview of pointers as a general concept. As we alluded to
-before, Rust has different kinds of pointers, rather than just one, and
-mitigates all of the problems that we talked about, too. This does mean that
-Rust pointers are slightly more complicated than in other languages, but
-it's worth it to not have the problems that simple pointers have.
-
-# References
-
-The most basic type of pointer that Rust has is called a *reference*. Rust
-references look like this:
-
-```{rust}
-let x = 5;
-let y = &x;
-
-println!("{}", *y);
-println!("{:p}", y);
-println!("{}", y);
-```
-
-We'd say "`y` is a reference to `x`." The first `println!` prints out the
-value of `y`'s referent by using the dereference operator, `*`. The second
-one prints out the memory location that `y` points to, by using the pointer
-format string. The third `println!` *also* prints out the value of `y`'s
-referent, because `println!` will automatically dereference it for us.
-
-Here's a function that takes a reference:
-
-```{rust}
-fn succ(x: &i32) -> i32 { *x + 1 }
-```
-
-You can also use `&` as an operator to create a reference, so we can
-call this function in two different ways:
-
-```{rust}
-fn succ(x: &i32) -> i32 { *x + 1 }
-
-fn main() {
-
-    let x = 5;
-    let y = &x;
-
-    println!("{}", succ(y));
-    println!("{}", succ(&x));
-}
-```
-
-Both of these `println!`s will print out `6`.
-
-Of course, if this were real code, we wouldn't bother with the reference, and
-just write:
-
-```{rust}
-fn succ(x: i32) -> i32 { x + 1 }
-```
-
-References are immutable by default:
-
-```{rust,ignore}
-let x = 5;
-let y = &x;
-
-*y = 5; // error: cannot assign to immutable borrowed content `*y`
-```
-
-They can be made mutable with `mut`, but only if its referent is also mutable.
-This works:
-
-```{rust}
-let mut x = 5;
-let y = &mut x;
-```
-
-This does not:
-
-```{rust,ignore}
-let x = 5;
-let y = &mut x; // error: cannot borrow immutable local variable `x` as mutable
-```
-
-Immutable pointers are allowed to alias:
-
-```{rust}
-let x = 5;
-let y = &x;
-let z = &x;
-```
-
-Mutable ones, however, are not:
-
-```{rust,ignore}
-let mut x = 5;
-let y = &mut x;
-let z = &mut x; // error: cannot borrow `x` as mutable more than once at a time
-```
-
-Despite their complete safety, a reference'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. The theory that
-allows for this was originally called *region pointers*. Region pointers
-evolved into what we know today as *lifetimes*.
-
-Here's the simple explanation: would you expect this code to compile?
-
-```{rust,ignore}
-fn main() {
-    println!("{}", x);
-    let x = 5;
-}
-```
-
-Probably not. That's because you know that the name `x` is valid from where
-it's declared to when it goes out of scope. In this case, that's the end of
-the `main` function. So you know this code will cause an error. We call this
-duration a *lifetime*. Let's try a more complex example:
-
-```{rust}
-fn main() {
-    let mut x = 5;
-
-    if x < 10 {
-        let y = &x;
-
-        println!("Oh no: {}", y);
-        return;
-    }
-
-    x -= 1;
-
-    println!("Oh no: {}", x);
-}
-```
-
-Here, we're borrowing a pointer to `x` inside of the `if`. The compiler, however,
-is able to determine that that pointer will go out of scope without `x` being
-mutated, and therefore, lets us pass. This wouldn't work:
-
-```{rust,ignore}
-fn main() {
-    let mut x = 5;
-
-    if x < 10 {
-        let y = &x;
-
-        x -= 1;
-
-        println!("Oh no: {}", y);
-        return;
-    }
-
-    x -= 1;
-
-    println!("Oh no: {}", x);
-}
-```
-
-It gives this error:
-
-```text
-test.rs:7:9: 7:15 error: cannot assign to `x` because it is borrowed
-test.rs:7         x -= 1;
-                  ^~~~~~
-test.rs:5:18: 5:19 note: borrow of `x` occurs here
-test.rs:5         let y = &x;
-                           ^
-```
-
-As you might guess, this kind of analysis is complex for a human, and therefore
-hard for a computer, too! There is an entire [guide devoted to references, ownership,
-and lifetimes](ownership.html) that goes into this topic in
-great detail, so if you want the full details, check that out.
-
-## Best practices
-
-In general, prefer stack allocation over heap allocation. Using references to
-stack allocated information is preferred whenever possible. Therefore,
-references are the default pointer type you should use, unless you have a
-specific reason to use a different type. The other types of pointers cover when
-they're appropriate to use in their own best practices sections.
-
-Use references when you want to use a pointer, but do not want to take ownership.
-References just borrow ownership, which is more polite if you don't need the
-ownership. In other words, prefer:
-
-```{rust}
-fn succ(x: &i32) -> i32 { *x + 1 }
-```
-
-to
-
-```{rust}
-fn succ(x: Box<i32>) -> i32 { *x + 1 }
-```
-
-As a corollary to that rule, references allow you to accept a wide variety of
-other pointers, and so are useful so that you don't have to write a number
-of variants per pointer. In other words, prefer:
-
-```{rust}
-fn succ(x: &i32) -> i32 { *x + 1 }
-```
-
-to
-
-```{rust}
-use std::rc::Rc;
-
-fn box_succ(x: Box<i32>) -> i32 { *x + 1 }
-
-fn rc_succ(x: Rc<i32>) -> i32 { *x + 1 }
-```
-
-Note that the caller of your function will have to modify their calls slightly:
-
-```{rust}
-use std::rc::Rc;
-
-fn succ(x: &i32) -> i32 { *x + 1 }
-
-let ref_x = &5;
-let box_x = Box::new(5);
-let rc_x = Rc::new(5);
-
-succ(ref_x);
-succ(&*box_x);
-succ(&*rc_x);
-```
-
-The initial `*` dereferences the pointer, and then `&` takes a reference to
-those contents.
-
-# Boxes
-
-`Box<T>` is Rust's *boxed pointer* type. Boxes provide the simplest form of
-heap allocation in Rust. Creating a box looks like this:
-
-```{rust}
-let x = Box::new(5);
-```
-
-Boxes are heap allocated and they are deallocated automatically by Rust when
-they go out of scope:
-
-```{rust}
-{
-    let x = Box::new(5);
-
-    // stuff happens
-
-} // x is destructed and its memory is free'd here
-```
-
-However, boxes do _not_ use reference counting or garbage collection. Boxes are
-what's called an *affine type*. This means that the Rust compiler, at compile
-time, determines when the box comes into and goes out of scope, and inserts the
-appropriate calls there.
-
-You don't need to fully grok the theory of affine types to grok boxes, though.
-As a rough approximation, you can treat this Rust code:
-
-```{rust}
-{
-    let x = Box::new(5);
-
-    // stuff happens
-}
-```
-
-As being similar to this C code:
-
-```c
-{
-    int *x;
-    x = (int *)malloc(sizeof(int));
-    *x = 5;
-
-    // stuff happens
-
-    free(x);
-}
-```
-
-Of course, this is a 10,000 foot view. It leaves out destructors, for example.
-But the general idea is correct: you get the semantics of `malloc`/`free`, but
-with some improvements:
-
-1. It's impossible to allocate the incorrect amount of memory, because Rust
-   figures it out from the types.
-2. You cannot forget to `free` memory you've allocated, because Rust does it
-   for you.
-3. Rust ensures that this `free` happens at the right time, when it is truly
-   not used. Use-after-free is not possible.
-4. Rust enforces that no other writeable pointers alias to this heap memory,
-   which means writing to an invalid pointer is not possible.
-
-See the section on references or the [ownership guide](ownership.html)
-for more detail on how lifetimes work.
-
-Using boxes and references together is very common. For example:
-
-```{rust}
-fn add_one(x: &i32) -> i32 {
-    *x + 1
-}
-
-fn main() {
-    let x = Box::new(5);
-
-    println!("{}", add_one(&*x));
-}
-```
-
-In this case, Rust knows that `x` is being *borrowed* by the `add_one()`
-function, and since it's only reading the value, allows it.
-
-We can borrow `x` as read-only multiple times, even simultaneously:
-
-```{rust}
-fn add(x: &i32, y: &i32) -> i32 {
-    *x + *y
-}
-
-fn main() {
-    let x = Box::new(5);
-
-    println!("{}", add(&*x, &*x));
-    println!("{}", add(&*x, &*x));
-}
-```
-
-We can mutably borrow `x` multiple times, but only if x itself is mutable, and
-it may not be *simultaneously* borrowed:
-
-```{rust,ignore}
-fn increment(x: &mut i32) {
-    *x += 1;
-}
-
-fn main() {
-    // If variable x is not "mut", this will not compile
-    let mut x = Box::new(5);
-
-    increment(&mut x);
-    increment(&mut x);
-    println!("{}", x);
-}
-```
-
-Notice the signature of `increment()` requests a mutable reference.
-
-## Best practices
-
-Boxes are most appropriate to use when defining recursive data structures.
-
-### Recursive data structures
-
-Sometimes, you need a recursive data structure. The simplest is known as a
-*cons list*:
-
-
-```{rust}
-#[derive(Debug)]
-enum List<T> {
-    Cons(T, Box<List<T>>),
-    Nil,
-}
-
-fn main() {
-    let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
-    println!("{:?}", list);
-}
-```
-
-This prints:
-
-```text
-Cons(1, Box(Cons(2, Box(Cons(3, Box(Nil))))))
-```
-
-The reference to another `List` inside of the `Cons` enum variant must be a box,
-because we don't know the length of the list. Because we don't know the length,
-we don't know the size, and therefore, we need to heap allocate our list.
-
-Working with recursive or other unknown-sized data structures is the primary
-use-case for boxes.
-
-# Rc and Arc
-
-This part is coming soon.
-
-## Best practices
-
-This part is coming soon.
-
-# Raw Pointers
-
-This part is coming soon.
-
-## Best practices
-
-This part is coming soon.
-
-# Creating your own Pointers
-
-This part is coming soon.
-
-## Best practices
-
-This part is coming soon.
-
-# Patterns and `ref`
-
-When you're trying to match something that's stored in a pointer, there may be
-a situation where matching directly isn't the best option available. Let's see
-how to properly handle this:
-
-```{rust,ignore}
-fn possibly_print(x: &Option<String>) {
-    match *x {
-        // BAD: cannot move out of a `&`
-        Some(s) => println!("{}", s)
-
-        // GOOD: instead take a reference into the memory of the `Option`
-        Some(ref s) => println!("{}", *s),
-        None => {}
-    }
-}
-```
-
-The `ref s` here means that `s` will be of type `&String`, rather than type
-`String`.
-
-This is important when the type you're trying to get access to has a destructor
-and you don't want to move it, you just want a reference to it.
-
-# Cheat Sheet
-
-Here's a quick rundown of Rust's pointer types:
-
-| Type         | Name                | Summary                                                             |
-|--------------|---------------------|---------------------------------------------------------------------|
-| `&T`         | Reference           | Allows one or more references to read `T`                           |
-| `&mut T`     | Mutable Reference   | Allows a single reference to read and write `T`                     |
-| `Box<T>`     | Box                 | Heap allocated `T` with a single owner that may read and write `T`. |
-| `Rc<T>`      | "arr cee" pointer   | Heap allocated `T` with many readers                                |
-| `Arc<T>`     | Arc pointer         | Same as above, but safe sharing across threads                      |
-| `*const T`   | Raw pointer         | Unsafe read access to `T`                                           |
-| `*mut T`     | Mutable raw pointer | Unsafe read and write access to `T`                                 |
-
-# Related resources
-
-* [API documentation for Box](../std/boxed/index.html)
-* [Ownership guide](ownership.html)
-* [Cyclone paper on regions](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf), which inspired Rust's lifetime system
diff --git a/src/doc/trpl/primitive-types.md b/src/doc/trpl/primitive-types.md
new file mode 100644 (file)
index 0000000..2878e7c
--- /dev/null
@@ -0,0 +1,3 @@
+% Primitive Types
+
+Coming Soon!
diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md
new file mode 100644 (file)
index 0000000..6acb326
--- /dev/null
@@ -0,0 +1,3 @@
+% References and Borrowing
+
+Coming Soon!
diff --git a/src/doc/trpl/slices.md b/src/doc/trpl/slices.md
new file mode 100644 (file)
index 0000000..a31c0ac
--- /dev/null
@@ -0,0 +1,21 @@
+% Slices
+
+A *slice* is a reference to (or "view" into) an array. They are useful for
+allowing safe, efficient access to a portion of an array without copying. For
+example, you might want to reference just one line of a file read into memory.
+By nature, a slice is not created directly, but from an existing variable.
+Slices have a length, can be mutable or not, and in many ways behave like
+arrays:
+
+```{rust}
+let a = [0, 1, 2, 3, 4];
+let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
+
+for e in middle.iter() {
+    println!("{}", e); // Prints 1, 2, 3
+}
+```
+
+You can also take a slice of a vector, `String`, or `&str`, because they are
+backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover
+generics.
diff --git a/src/doc/trpl/static-and-dynamic-dispatch.md b/src/doc/trpl/static-and-dynamic-dispatch.md
deleted file mode 100644 (file)
index a779481..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-% Static and Dynamic Dispatch
-
-When code involves polymorphism, there needs to be a mechanism to determine
-which specific version is actually run. This is called 'dispatch.' There are
-two major forms of dispatch: static dispatch and dynamic dispatch. While Rust
-favors static dispatch, it also supports dynamic dispatch through a mechanism
-called 'trait objects.'
-
-## Background
-
-For the rest of this chapter, we'll need a trait and some implementations.
-Let's make a simple one, `Foo`. It has one method that is expected to return a
-`String`.
-
-```rust
-trait Foo {
-    fn method(&self) -> String;
-}
-```
-
-We'll also implement this trait for `u8` and `String`:
-
-```rust
-# trait Foo { fn method(&self) -> String; }
-impl Foo for u8 {
-    fn method(&self) -> String { format!("u8: {}", *self) }
-}
-
-impl Foo for String {
-    fn method(&self) -> String { format!("string: {}", *self) }
-}
-```
-
-
-## Static dispatch
-
-We can use this trait to perform static dispatch with trait bounds:
-
-```rust
-# trait Foo { fn method(&self) -> String; }
-# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
-# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
-fn do_something<T: Foo>(x: T) {
-    x.method();
-}
-
-fn main() {
-    let x = 5u8;
-    let y = "Hello".to_string();
-
-    do_something(x);
-    do_something(y);
-}
-```
-
-Rust uses 'monomorphization' to perform static dispatch here. This means that
-Rust will create a special version of `do_something()` for both `u8` and
-`String`, and then replace the call sites with calls to these specialized
-functions. In other words, Rust generates something like this:
-
-```rust
-# trait Foo { fn method(&self) -> String; }
-# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
-# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
-fn do_something_u8(x: u8) {
-    x.method();
-}
-
-fn do_something_string(x: String) {
-    x.method();
-}
-
-fn main() {
-    let x = 5u8;
-    let y = "Hello".to_string();
-
-    do_something_u8(x);
-    do_something_string(y);
-}
-```
-
-This has a great upside: static dispatch allows function calls to be
-inlined because the callee is known at compile time, and inlining is
-the key to good optimization. Static dispatch is fast, but it comes at
-a tradeoff: 'code bloat', due to many copies of the same function
-existing in the binary, one for each type.
-
-Furthermore, compilers aren’t perfect and may “optimize” code to become slower.
-For example, functions inlined too eagerly will bloat the instruction cache
-(cache rules everything around us). This is part of the reason that `#[inline]`
-and `#[inline(always)]` should be used carefully, and one reason why using a
-dynamic dispatch is sometimes more efficient.
-
-However, the common case is that it is more efficient to use static dispatch,
-and one can always have a thin statically-dispatched wrapper function that does
-a dynamic dispatch, but not vice versa, meaning static calls are more flexible.
-The standard library tries to be statically dispatched where possible for this
-reason.
-
-## Dynamic dispatch
-
-Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
-objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
-*any* type that implements the given trait, where the precise type can only be
-known at runtime.
-
-A trait object can be obtained from a pointer to a concrete type that
-implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it
-(e.g. using `&x` as an argument to a function that takes `&Foo`).
-
-These trait object coercions and casts also work for pointers like `&mut T` to
-`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
-and casts are identical.
-
-This operation can be seen as "erasing" the compiler's knowledge about the
-specific type of the pointer, and hence trait objects are sometimes referred to
-as "type erasure".
-
-Coming back to the example above, we can use the same trait to perform dynamic
-dispatch with trait objects by casting:
-
-```rust
-# trait Foo { fn method(&self) -> String; }
-# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
-# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
-
-fn do_something(x: &Foo) {
-    x.method();
-}
-
-fn main() {
-    let x = 5u8;
-    do_something(&x as &Foo);
-}
-```
-
-or by coercing:
-
-```rust
-# trait Foo { fn method(&self) -> String; }
-# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
-# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
-
-fn do_something(x: &Foo) {
-    x.method();
-}
-
-fn main() {
-    let x = "Hello".to_string();
-    do_something(&x);
-}
-```
-
-A function that takes a trait object is not specialized to each of the types
-that implements `Foo`: only one copy is generated, often (but not always)
-resulting in less code bloat. However, this comes at the cost of requiring
-slower virtual function calls, and effectively inhibiting any chance of
-inlining and related optimisations from occurring.
-
-### Why pointers?
-
-Rust does not put things behind a pointer by default, unlike many managed
-languages, so types can have different sizes. Knowing the size of the value at
-compile time is important for things like passing it as an argument to a
-function, moving it about on the stack and allocating (and deallocating) space
-on the heap to store it.
-
-For `Foo`, we would need to have a value that could be at least either a
-`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
-dependent crates may implement `Foo` (any number of bytes at all). There's no
-way to guarantee that this last point can work if the values are stored without
-a pointer, because those other types can be arbitrarily large.
-
-Putting the value behind a pointer means the size of the value is not relevant
-when we are tossing a trait object around, only the size of the pointer itself.
-
-### Representation
-
-The methods of the trait can be called on a trait object via a special record
-of function pointers traditionally called a 'vtable' (created and managed by
-the compiler).
-
-Trait objects are both simple and complicated: their core representation and
-layout is quite straight-forward, but there are some curly error messages and
-surprising behaviors to discover.
-
-Let's start simple, with the runtime representation of a trait object. The
-`std::raw` module contains structs with layouts that are the same as the
-complicated built-in types, [including trait objects][stdraw]:
-
-```rust
-# mod foo {
-pub struct TraitObject {
-    pub data: *mut (),
-    pub vtable: *mut (),
-}
-# }
-```
-
-[stdraw]: ../std/raw/struct.TraitObject.html
-
-That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable"
-pointer.
-
-The data pointer addresses the data (of some unknown type `T`) that the trait
-object is storing, and the vtable pointer points to the vtable ("virtual method
-table") corresponding to the implementation of `Foo` for `T`.
-
-
-A vtable is essentially a struct of function pointers, pointing to the concrete
-piece of machine code for each method in the implementation. A method call like
-`trait_object.method()` will retrieve the correct pointer out of the vtable and
-then do a dynamic call of it. For example:
-
-```{rust,ignore}
-struct FooVtable {
-    destructor: fn(*mut ()),
-    size: usize,
-    align: usize,
-    method: fn(*const ()) -> String,
-}
-
-// u8:
-
-fn call_method_on_u8(x: *const ()) -> String {
-    // the compiler guarantees that this function is only called
-    // with `x` pointing to a u8
-    let byte: &u8 = unsafe { &*(x as *const u8) };
-
-    byte.method()
-}
-
-static Foo_for_u8_vtable: FooVtable = FooVtable {
-    destructor: /* compiler magic */,
-    size: 1,
-    align: 1,
-
-    // cast to a function pointer
-    method: call_method_on_u8 as fn(*const ()) -> String,
-};
-
-
-// String:
-
-fn call_method_on_String(x: *const ()) -> String {
-    // the compiler guarantees that this function is only called
-    // with `x` pointing to a String
-    let string: &String = unsafe { &*(x as *const String) };
-
-    string.method()
-}
-
-static Foo_for_String_vtable: FooVtable = FooVtable {
-    destructor: /* compiler magic */,
-    // values for a 64-bit computer, halve them for 32-bit ones
-    size: 24,
-    align: 8,
-
-    method: call_method_on_String as fn(*const ()) -> String,
-};
-```
-
-The `destructor` field in each vtable points to a function that will clean up
-any resources of the vtable's type, for `u8` it is trivial, but for `String` it
-will free the memory. This is necessary for owning trait objects like
-`Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
-internal type when they go out of scope. The `size` and `align` fields store
-the size of the erased type, and its alignment requirements; these are
-essentially unused at the moment since the information is embedded in the
-destructor, but will be used in the future, as trait objects are progressively
-made more flexible.
-
-Suppose we've got some values that implement `Foo`, then the explicit form of
-construction and use of `Foo` trait objects might look a bit like (ignoring the
-type mismatches: they're all just pointers anyway):
-
-```{rust,ignore}
-let a: String = "foo".to_string();
-let x: u8 = 1;
-
-// let b: &Foo = &a;
-let b = TraitObject {
-    // store the data
-    data: &a,
-    // store the methods
-    vtable: &Foo_for_String_vtable
-};
-
-// let y: &Foo = x;
-let y = TraitObject {
-    // store the data
-    data: &x,
-    // store the methods
-    vtable: &Foo_for_u8_vtable
-};
-
-// b.method();
-(b.vtable.method)(b.data);
-
-// y.method();
-(y.vtable.method)(y.data);
-```
-
-If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
-`(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
-scope.
diff --git a/src/doc/trpl/static.md b/src/doc/trpl/static.md
new file mode 100644 (file)
index 0000000..b29c495
--- /dev/null
@@ -0,0 +1,3 @@
+% `static`
+
+Coming soon!
diff --git a/src/doc/trpl/structs.md b/src/doc/trpl/structs.md
new file mode 100644 (file)
index 0000000..eff1a47
--- /dev/null
@@ -0,0 +1,49 @@
+% Structs
+
+A struct is another form of a *record type*, just like a tuple. There's a
+difference: structs give each element that they contain a name, called a
+*field* or a *member*. Check it out:
+
+```rust
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let origin = Point { x: 0, y: 0 }; // origin: Point
+
+    println!("The origin is at ({}, {})", origin.x, origin.y);
+}
+```
+
+There's a lot going on here, so let's break it down. We declare a struct with
+the `struct` keyword, and then with a name. By convention, structs begin with a
+capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
+
+We can create an instance of our struct via `let`, as usual, but we use a `key:
+value` style syntax to set each field. The order doesn't need to be the same as
+in the original declaration.
+
+Finally, because fields have names, we can access the field through dot
+notation: `origin.x`.
+
+The values in structs are immutable by default, like other bindings in Rust.
+Use `mut` to make them mutable:
+
+```{rust}
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn main() {
+    let mut point = Point { x: 0, y: 0 };
+
+    point.x = 5;
+
+    println!("The point is at ({}, {})", point.x, point.y);
+}
+```
+
+This will print `The point is at (5, 0)`.
diff --git a/src/doc/trpl/syntax-and-semantics.md b/src/doc/trpl/syntax-and-semantics.md
new file mode 100644 (file)
index 0000000..6f992cf
--- /dev/null
@@ -0,0 +1 @@
+% Syntax and Semantics
diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md
new file mode 100644 (file)
index 0000000..cc0941b
--- /dev/null
@@ -0,0 +1,3 @@
+% The Stack and the Heap
+
+Coming Soon
diff --git a/src/doc/trpl/tracing-macros.md b/src/doc/trpl/tracing-macros.md
deleted file mode 100644 (file)
index 6226ea9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-% Tracing Macros
-
-The `trace_macros` feature allows you to use a special feature: tracing macro
-invocations.
-
-In the advanced macros chapter, we defined a `bct` macro:
-
-```rust
-macro_rules! bct {
-    // cmd 0:  d ... => ...
-    (0, $($ps:tt),* ; $_d:tt)
-        => (bct!($($ps),*, 0 ; ));
-    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
-        => (bct!($($ps),*, 0 ; $($ds),*));
-
-    // cmd 1p:  1 ... => 1 ... p
-    (1, $p:tt, $($ps:tt),* ; 1)
-        => (bct!($($ps),*, 1, $p ; 1, $p));
-    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
-
-    // cmd 1p:  0 ... => 0 ...
-    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; $($ds),*));
-
-    // halt on empty data string
-    ( $($ps:tt),* ; )
-        => (());
-}
-```
-
-This is pretty complex! we can see the output
-
-```rust,ignore
-#![feature(trace_macros)]
-
-macro_rules! bct {
-    // cmd 0:  d ... => ...
-    (0, $($ps:tt),* ; $_d:tt)
-        => (bct!($($ps),*, 0 ; ));
-    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
-        => (bct!($($ps),*, 0 ; $($ds),*));
-
-    // cmd 1p:  1 ... => 1 ... p
-    (1, $p:tt, $($ps:tt),* ; 1)
-        => (bct!($($ps),*, 1, $p ; 1, $p));
-    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
-
-    // cmd 1p:  0 ... => 0 ...
-    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
-        => (bct!($($ps),*, 1, $p ; $($ds),*));
-
-    // halt on empty data string
-    ( $($ps:tt),* ; )
-        => (());
-}
-
-fn main() {
-    trace_macros!(true);
-
-    bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
-}
-```
-
-This will print out a wall of text:
-
-```text
-bct! { 0 , 0 , 1 , 1 , 1 ; 1 , 0 , 1 }
-bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 }
-bct! { 1 , 1 , 1 , 0 , 0 ; 1 }
-bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 1 }
-bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 1 , 0 }
-bct! { 1 , 1 , 1 , 0 , 0 ; 1 , 0 }
-bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 0 , 1 }
-bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 0 , 1 , 0 }
-bct! { 1 , 1 , 1 , 0 , 0 ; 0 , 1 , 0 }
-bct! { 1 , 0 , 0 , 1 , 1 ; 0 , 1 , 0 }
-bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 , 0 }
-```
-
-And eventually, error:
-
-```text
-18:45 error: recursion limit reached while expanding the macro `bct`
-    => (bct!($($ps),*, 1, $p ; $($ds),*));
-        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-```
-
-The `trace_macros!` call is what produces this output, showing how we match
-each time.
diff --git a/src/doc/trpl/trait-objects.md b/src/doc/trpl/trait-objects.md
new file mode 100644 (file)
index 0000000..d008d30
--- /dev/null
@@ -0,0 +1,306 @@
+% Trait Objects
+
+When code involves polymorphism, there needs to be a mechanism to determine
+which specific version is actually run. This is called 'dispatch.' There are
+two major forms of dispatch: static dispatch and dynamic dispatch. While Rust
+favors static dispatch, it also supports dynamic dispatch through a mechanism
+called 'trait objects.'
+
+## Background
+
+For the rest of this chapter, we'll need a trait and some implementations.
+Let's make a simple one, `Foo`. It has one method that is expected to return a
+`String`.
+
+```rust
+trait Foo {
+    fn method(&self) -> String;
+}
+```
+
+We'll also implement this trait for `u8` and `String`:
+
+```rust
+# trait Foo { fn method(&self) -> String; }
+impl Foo for u8 {
+    fn method(&self) -> String { format!("u8: {}", *self) }
+}
+
+impl Foo for String {
+    fn method(&self) -> String { format!("string: {}", *self) }
+}
+```
+
+
+## Static dispatch
+
+We can use this trait to perform static dispatch with trait bounds:
+
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
+fn do_something<T: Foo>(x: T) {
+    x.method();
+}
+
+fn main() {
+    let x = 5u8;
+    let y = "Hello".to_string();
+
+    do_something(x);
+    do_something(y);
+}
+```
+
+Rust uses 'monomorphization' to perform static dispatch here. This means that
+Rust will create a special version of `do_something()` for both `u8` and
+`String`, and then replace the call sites with calls to these specialized
+functions. In other words, Rust generates something like this:
+
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
+fn do_something_u8(x: u8) {
+    x.method();
+}
+
+fn do_something_string(x: String) {
+    x.method();
+}
+
+fn main() {
+    let x = 5u8;
+    let y = "Hello".to_string();
+
+    do_something_u8(x);
+    do_something_string(y);
+}
+```
+
+This has a great upside: static dispatch allows function calls to be
+inlined because the callee is known at compile time, and inlining is
+the key to good optimization. Static dispatch is fast, but it comes at
+a tradeoff: 'code bloat', due to many copies of the same function
+existing in the binary, one for each type.
+
+Furthermore, compilers aren’t perfect and may “optimize” code to become slower.
+For example, functions inlined too eagerly will bloat the instruction cache
+(cache rules everything around us). This is part of the reason that `#[inline]`
+and `#[inline(always)]` should be used carefully, and one reason why using a
+dynamic dispatch is sometimes more efficient.
+
+However, the common case is that it is more efficient to use static dispatch,
+and one can always have a thin statically-dispatched wrapper function that does
+a dynamic dispatch, but not vice versa, meaning static calls are more flexible.
+The standard library tries to be statically dispatched where possible for this
+reason.
+
+## Dynamic dispatch
+
+Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
+objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
+*any* type that implements the given trait, where the precise type can only be
+known at runtime.
+
+A trait object can be obtained from a pointer to a concrete type that
+implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it
+(e.g. using `&x` as an argument to a function that takes `&Foo`).
+
+These trait object coercions and casts also work for pointers like `&mut T` to
+`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
+and casts are identical.
+
+This operation can be seen as "erasing" the compiler's knowledge about the
+specific type of the pointer, and hence trait objects are sometimes referred to
+as "type erasure".
+
+Coming back to the example above, we can use the same trait to perform dynamic
+dispatch with trait objects by casting:
+
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
+
+fn do_something(x: &Foo) {
+    x.method();
+}
+
+fn main() {
+    let x = 5u8;
+    do_something(&x as &Foo);
+}
+```
+
+or by coercing:
+
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
+
+fn do_something(x: &Foo) {
+    x.method();
+}
+
+fn main() {
+    let x = "Hello".to_string();
+    do_something(&x);
+}
+```
+
+A function that takes a trait object is not specialized to each of the types
+that implements `Foo`: only one copy is generated, often (but not always)
+resulting in less code bloat. However, this comes at the cost of requiring
+slower virtual function calls, and effectively inhibiting any chance of
+inlining and related optimisations from occurring.
+
+### Why pointers?
+
+Rust does not put things behind a pointer by default, unlike many managed
+languages, so types can have different sizes. Knowing the size of the value at
+compile time is important for things like passing it as an argument to a
+function, moving it about on the stack and allocating (and deallocating) space
+on the heap to store it.
+
+For `Foo`, we would need to have a value that could be at least either a
+`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
+dependent crates may implement `Foo` (any number of bytes at all). There's no
+way to guarantee that this last point can work if the values are stored without
+a pointer, because those other types can be arbitrarily large.
+
+Putting the value behind a pointer means the size of the value is not relevant
+when we are tossing a trait object around, only the size of the pointer itself.
+
+### Representation
+
+The methods of the trait can be called on a trait object via a special record
+of function pointers traditionally called a 'vtable' (created and managed by
+the compiler).
+
+Trait objects are both simple and complicated: their core representation and
+layout is quite straight-forward, but there are some curly error messages and
+surprising behaviors to discover.
+
+Let's start simple, with the runtime representation of a trait object. The
+`std::raw` module contains structs with layouts that are the same as the
+complicated built-in types, [including trait objects][stdraw]:
+
+```rust
+# mod foo {
+pub struct TraitObject {
+    pub data: *mut (),
+    pub vtable: *mut (),
+}
+# }
+```
+
+[stdraw]: ../std/raw/struct.TraitObject.html
+
+That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable"
+pointer.
+
+The data pointer addresses the data (of some unknown type `T`) that the trait
+object is storing, and the vtable pointer points to the vtable ("virtual method
+table") corresponding to the implementation of `Foo` for `T`.
+
+
+A vtable is essentially a struct of function pointers, pointing to the concrete
+piece of machine code for each method in the implementation. A method call like
+`trait_object.method()` will retrieve the correct pointer out of the vtable and
+then do a dynamic call of it. For example:
+
+```{rust,ignore}
+struct FooVtable {
+    destructor: fn(*mut ()),
+    size: usize,
+    align: usize,
+    method: fn(*const ()) -> String,
+}
+
+// u8:
+
+fn call_method_on_u8(x: *const ()) -> String {
+    // the compiler guarantees that this function is only called
+    // with `x` pointing to a u8
+    let byte: &u8 = unsafe { &*(x as *const u8) };
+
+    byte.method()
+}
+
+static Foo_for_u8_vtable: FooVtable = FooVtable {
+    destructor: /* compiler magic */,
+    size: 1,
+    align: 1,
+
+    // cast to a function pointer
+    method: call_method_on_u8 as fn(*const ()) -> String,
+};
+
+
+// String:
+
+fn call_method_on_String(x: *const ()) -> String {
+    // the compiler guarantees that this function is only called
+    // with `x` pointing to a String
+    let string: &String = unsafe { &*(x as *const String) };
+
+    string.method()
+}
+
+static Foo_for_String_vtable: FooVtable = FooVtable {
+    destructor: /* compiler magic */,
+    // values for a 64-bit computer, halve them for 32-bit ones
+    size: 24,
+    align: 8,
+
+    method: call_method_on_String as fn(*const ()) -> String,
+};
+```
+
+The `destructor` field in each vtable points to a function that will clean up
+any resources of the vtable's type, for `u8` it is trivial, but for `String` it
+will free the memory. This is necessary for owning trait objects like
+`Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
+internal type when they go out of scope. The `size` and `align` fields store
+the size of the erased type, and its alignment requirements; these are
+essentially unused at the moment since the information is embedded in the
+destructor, but will be used in the future, as trait objects are progressively
+made more flexible.
+
+Suppose we've got some values that implement `Foo`, then the explicit form of
+construction and use of `Foo` trait objects might look a bit like (ignoring the
+type mismatches: they're all just pointers anyway):
+
+```{rust,ignore}
+let a: String = "foo".to_string();
+let x: u8 = 1;
+
+// let b: &Foo = &a;
+let b = TraitObject {
+    // store the data
+    data: &a,
+    // store the methods
+    vtable: &Foo_for_String_vtable
+};
+
+// let y: &Foo = x;
+let y = TraitObject {
+    // store the data
+    data: &x,
+    // store the methods
+    vtable: &Foo_for_u8_vtable
+};
+
+// b.method();
+(b.vtable.method)(b.data);
+
+// y.method();
+(y.vtable.method)(y.data);
+```
+
+If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
+`(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
+scope.
diff --git a/src/doc/trpl/tuple-structs.md b/src/doc/trpl/tuple-structs.md
new file mode 100644 (file)
index 0000000..8fba658
--- /dev/null
@@ -0,0 +1,56 @@
+% Tuple Structs
+
+Rust has another data type that's like a hybrid between a tuple and a struct,
+called a *tuple struct*. Tuple structs do have a name, but their fields don't:
+
+```{rust}
+struct Color(i32, i32, i32);
+struct Point(i32, i32, i32);
+```
+
+These two will not be equal, even if they have the same values:
+
+```{rust}
+# struct Color(i32, i32, i32);
+# struct Point(i32, i32, i32);
+let black = Color(0, 0, 0);
+let origin = Point(0, 0, 0);
+```
+
+It is almost always better to use a struct than a tuple struct. We would write
+`Color` and `Point` like this instead:
+
+```{rust}
+struct Color {
+    red: i32,
+    blue: i32,
+    green: i32,
+}
+
+struct Point {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+```
+
+Now, we have actual names, rather than positions. Good names are important,
+and with a struct, we have actual names.
+
+There _is_ one case when a tuple struct is very useful, though, and that's a
+tuple struct with only one element. We call this the *newtype* pattern, because
+it allows you to create a new type, distinct from that of its contained value
+and expressing its own semantic meaning:
+
+```{rust}
+struct Inches(i32);
+
+let length = Inches(10);
+
+let Inches(integer_length) = length;
+println!("length is {} inches", integer_length);
+```
+
+As you can see here, you can extract the inner integer type through a
+destructuring `let`, as we discussed previously in 'tuples.' In this case, the
+`let Inches(integer_length)` assigns `10` to `integer_length`.
diff --git a/src/doc/trpl/tuples.md b/src/doc/trpl/tuples.md
new file mode 100644 (file)
index 0000000..dd526d0
--- /dev/null
@@ -0,0 +1,97 @@
+% Tuples
+
+The first compound data type we're going to talk about is called the *tuple*.
+A tuple is an ordered list of fixed size. Like this:
+
+```rust
+let x = (1, "hello");
+```
+
+The parentheses and commas form this two-length tuple. Here's the same code, but
+with the type annotated:
+
+```rust
+let x: (i32, &str) = (1, "hello");
+```
+
+As you can see, the type of a tuple looks just like the tuple, but with each
+position having a type name rather than the value. Careful readers will also
+note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple.
+You have briefly seen `&str` used as a type before, and we'll discuss the
+details of strings later. In systems programming languages, strings are a bit
+more complex than in other languages. For now, just read `&str` as a *string
+slice*, and we'll learn more soon.
+
+You can access the fields in a tuple through a *destructuring let*. Here's
+an example:
+
+```rust
+let (x, y, z) = (1, 2, 3);
+
+println!("x is {}", x);
+```
+
+Remember before when I said the left-hand side of a `let` statement was more
+powerful than just assigning a binding? Here we are. We can put a pattern on
+the left-hand side of the `let`, and if it matches up to the right-hand side,
+we can assign multiple bindings at once. In this case, `let` "destructures,"
+or "breaks up," the tuple, and assigns the bits to three bindings.
+
+This pattern is very powerful, and we'll see it repeated more later.
+
+There are also a few things you can do with a tuple as a whole, without
+destructuring. You can assign one tuple into another, if they have the same
+contained types and [arity]. Tuples have the same arity when they have the same
+length.
+
+```rust
+let mut x = (1, 2); // x: (i32, i32)
+let y = (2, 3); // y: (i32, i32)
+
+x = y;
+```
+
+You can also check for equality with `==`. Again, this will only compile if the
+tuples have the same type.
+
+```rust
+let x = (1, 2, 3);
+let y = (2, 2, 4);
+
+if x == y {
+    println!("yes");
+} else {
+    println!("no");
+}
+```
+
+This will print `no`, because some of the values aren't equal.
+
+Note that the order of the values is considered when checking for equality,
+so the following example will also print `no`.
+
+```rust
+let x = (1, 2, 3);
+let y = (2, 1, 3);
+
+if x == y {
+    println!("yes");
+} else {
+    println!("no");
+}
+```
+
+One other use of tuples is to return multiple values from a function:
+
+```rust
+fn next_two(x: i32) -> (i32, i32) { (x + 1, x + 2) }
+
+fn main() {
+    let (x, y) = next_two(5);
+    println!("x, y = {}, {}", x, y);
+}
+```
+
+Even though Rust functions can only return one value, a tuple *is* one value,
+that happens to be made up of more than one value. You can also see in this
+example how you can destructure a pattern returned by a function, as well.
diff --git a/src/doc/trpl/type-aliases.md b/src/doc/trpl/type-aliases.md
new file mode 100644 (file)
index 0000000..fffa0ae
--- /dev/null
@@ -0,0 +1,3 @@
+% `type` Aliases
+
+Coming soon
diff --git a/src/doc/trpl/ufcs.md b/src/doc/trpl/ufcs.md
new file mode 100644 (file)
index 0000000..6b9a417
--- /dev/null
@@ -0,0 +1,3 @@
+% Universal Function Call Syntax
+
+Coming soon
diff --git a/src/doc/trpl/unsafe-code.md b/src/doc/trpl/unsafe-code.md
new file mode 100644 (file)
index 0000000..b641f2b
--- /dev/null
@@ -0,0 +1,183 @@
+% Unsafe Code
+
+# Introduction
+
+Rust aims to provide safe abstractions over the low-level details of
+the CPU and operating system, but sometimes one needs to drop down and
+write code at that level. This guide aims to provide an overview of
+the dangers and power one gets with Rust's unsafe subset.
+
+Rust provides an escape hatch in the form of the `unsafe { ... }`
+block which allows the programmer to dodge some of the compiler's
+checks and do a wide range of operations, such as:
+
+- dereferencing [raw pointers](#raw-pointers)
+- calling a function via FFI ([covered by the FFI guide](ffi.html))
+- casting between types bitwise (`transmute`, aka "reinterpret cast")
+- [inline assembly](#inline-assembly)
+
+Note that an `unsafe` block does not relax the rules about lifetimes
+of `&` and the freezing of borrowed data.
+
+Any use of `unsafe` is the programmer saying "I know more than you" to
+the compiler, and, as such, the programmer should be very sure that
+they actually do know more about why that piece of code is valid.  In
+general, one should try to minimize the amount of unsafe code in a
+code base; preferably by using the bare minimum `unsafe` blocks to
+build safe interfaces.
+
+> **Note**: the low-level details of the Rust language are still in
+> flux, and there is no guarantee of stability or backwards
+> compatibility. In particular, there may be changes that do not cause
+> compilation errors, but do cause semantic changes (such as invoking
+> undefined behaviour). As such, extreme care is required.
+
+# Pointers
+
+## References
+
+One of Rust's biggest features is memory safety.  This is achieved in
+part via [the ownership system](ownership.html), which is how the
+compiler can guarantee that every `&` reference is always valid, and,
+for example, never pointing to freed memory.
+
+These restrictions on `&` have huge advantages. However, they also
+constrain how we can use them. For example, `&` doesn't behave
+identically to C's pointers, and so cannot be used for pointers in
+foreign function interfaces (FFI). Additionally, both immutable (`&`)
+and mutable (`&mut`) references have some aliasing and freezing
+guarantees, required for memory safety.
+
+In particular, if you have an `&T` reference, then the `T` must not be
+modified through that reference or any other reference. There are some
+standard library types, e.g. `Cell` and `RefCell`, that provide inner
+mutability by replacing compile time guarantees with dynamic checks at
+runtime.
+
+An `&mut` reference has a different constraint: when an object has an
+`&mut T` pointing into it, then that `&mut` reference must be the only
+such usable path to that object in the whole program. That is, an
+`&mut` cannot alias with any other references.
+
+Using `unsafe` code to incorrectly circumvent and violate these
+restrictions is undefined behaviour. For example, the following
+creates two aliasing `&mut` pointers, and is invalid.
+
+```
+use std::mem;
+let mut x: u8 = 1;
+
+let ref_1: &mut u8 = &mut x;
+let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
+
+// oops, ref_1 and ref_2 point to the same piece of data (x) and are
+// both usable
+*ref_1 = 10;
+*ref_2 = 20;
+```
+
+## Raw pointers
+
+Rust offers two additional pointer types (*raw pointers*), written as
+`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
+respectively; indeed, one of their most common uses is for FFI,
+interfacing with external C libraries.
+
+Raw pointers have much fewer guarantees than other pointer types
+offered by the Rust language and libraries. For example, they
+
+- are not guaranteed to point to valid memory and are not even
+  guaranteed to be non-null (unlike both `Box` and `&`);
+- do not have any automatic clean-up, unlike `Box`, and so require
+  manual resource management;
+- are plain-old-data, that is, they don't move ownership, again unlike
+  `Box`, hence the Rust compiler cannot protect against bugs like
+  use-after-free;
+- lack any form of lifetimes, unlike `&`, and so the compiler cannot
+  reason about dangling pointers; and
+- have no guarantees about aliasing or mutability other than mutation
+  not being allowed directly through a `*const T`.
+
+Fortunately, they come with a redeeming feature: the weaker guarantees
+mean weaker restrictions. The missing restrictions make raw pointers
+appropriate as a building block for implementing things like smart
+pointers and vectors inside libraries. For example, `*` pointers are
+allowed to alias, allowing them to be used to write shared-ownership
+types like reference counted and garbage collected pointers, and even
+thread-safe shared memory types (`Rc` and the `Arc` types are both
+implemented entirely in Rust).
+
+There are two things that you are required to be careful about
+(i.e. require an `unsafe { ... }` block) with raw pointers:
+
+- dereferencing: they can have any value: so possible results include
+  a crash, a read of uninitialised memory, a use-after-free, or
+  reading data as normal.
+- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
+  `.offset` method): this intrinsic uses so-called "in-bounds"
+  arithmetic, that is, it is only defined behaviour if the result is
+  inside (or one-byte-past-the-end) of the object from which the
+  original pointer came.
+
+The latter assumption allows the compiler to optimize more
+effectively. As can be seen, actually *creating* a raw pointer is not
+unsafe, and neither is converting to an integer.
+
+### References and raw pointers
+
+At runtime, a raw pointer `*` and a reference pointing to the same
+piece of data have an identical representation. In fact, an `&T`
+reference will implicitly coerce to an `*const T` raw pointer in safe code
+and similarly for the `mut` variants (both coercions can be performed
+explicitly with, respectively, `value as *const T` and `value as *mut T`).
+
+Going the opposite direction, from `*const` to a reference `&`, is not
+safe. A `&T` is always valid, and so, at a minimum, the raw pointer
+`*const T` has to point to a valid instance of type `T`. Furthermore,
+the resulting pointer must satisfy the aliasing and mutability laws of
+references. The compiler assumes these properties are true for any
+references, no matter how they are created, and so any conversion from
+raw pointers is asserting that they hold. The programmer *must*
+guarantee this.
+
+The recommended method for the conversion is
+
+```
+let i: u32 = 1;
+// explicit cast
+let p_imm: *const u32 = &i as *const u32;
+let mut m: u32 = 2;
+// implicit coercion
+let p_mut: *mut u32 = &mut m;
+
+unsafe {
+    let ref_imm: &u32 = &*p_imm;
+    let ref_mut: &mut u32 = &mut *p_mut;
+}
+```
+
+The `&*x` dereferencing style is preferred to using a `transmute`.
+The latter is far more powerful than necessary, and the more
+restricted operation is harder to use incorrectly; for example, it
+requires that `x` is a pointer (unlike `transmute`).
+
+
+
+## Making the unsafe safe(r)
+
+There are various ways to expose a safe interface around some unsafe
+code:
+
+- store pointers privately (i.e. not in public fields of public
+  structs), so that you can see and control all reads and writes to
+  the pointer in one place.
+- use `assert!()` a lot: since you can't rely on the protection of the
+  compiler & type-system to ensure that your `unsafe` code is correct
+  at compile-time, use `assert!()` to verify that it is doing the
+  right thing at run-time.
+- implement the `Drop` for resource clean-up via a destructor, and use
+  RAII (Resource Acquisition Is Initialization). This reduces the need
+  for any manual memory management by users, and automatically ensures
+  that clean-up is always run, even when the thread panics.
+- ensure that any data stored behind a raw pointer is destroyed at the
+  appropriate time.
diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md
deleted file mode 100644 (file)
index 3ca3cfd..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-% Unsafe and Low-Level Code
-
-# Introduction
-
-Rust aims to provide safe abstractions over the low-level details of
-the CPU and operating system, but sometimes one needs to drop down and
-write code at that level. This guide aims to provide an overview of
-the dangers and power one gets with Rust's unsafe subset.
-
-Rust provides an escape hatch in the form of the `unsafe { ... }`
-block which allows the programmer to dodge some of the compiler's
-checks and do a wide range of operations, such as:
-
-- dereferencing [raw pointers](#raw-pointers)
-- calling a function via FFI ([covered by the FFI guide](ffi.html))
-- casting between types bitwise (`transmute`, aka "reinterpret cast")
-- [inline assembly](#inline-assembly)
-
-Note that an `unsafe` block does not relax the rules about lifetimes
-of `&` and the freezing of borrowed data.
-
-Any use of `unsafe` is the programmer saying "I know more than you" to
-the compiler, and, as such, the programmer should be very sure that
-they actually do know more about why that piece of code is valid.  In
-general, one should try to minimize the amount of unsafe code in a
-code base; preferably by using the bare minimum `unsafe` blocks to
-build safe interfaces.
-
-> **Note**: the low-level details of the Rust language are still in
-> flux, and there is no guarantee of stability or backwards
-> compatibility. In particular, there may be changes that do not cause
-> compilation errors, but do cause semantic changes (such as invoking
-> undefined behaviour). As such, extreme care is required.
-
-# Pointers
-
-## References
-
-One of Rust's biggest features is memory safety.  This is achieved in
-part via [the ownership system](ownership.html), which is how the
-compiler can guarantee that every `&` reference is always valid, and,
-for example, never pointing to freed memory.
-
-These restrictions on `&` have huge advantages. However, they also
-constrain how we can use them. For example, `&` doesn't behave
-identically to C's pointers, and so cannot be used for pointers in
-foreign function interfaces (FFI). Additionally, both immutable (`&`)
-and mutable (`&mut`) references have some aliasing and freezing
-guarantees, required for memory safety.
-
-In particular, if you have an `&T` reference, then the `T` must not be
-modified through that reference or any other reference. There are some
-standard library types, e.g. `Cell` and `RefCell`, that provide inner
-mutability by replacing compile time guarantees with dynamic checks at
-runtime.
-
-An `&mut` reference has a different constraint: when an object has an
-`&mut T` pointing into it, then that `&mut` reference must be the only
-such usable path to that object in the whole program. That is, an
-`&mut` cannot alias with any other references.
-
-Using `unsafe` code to incorrectly circumvent and violate these
-restrictions is undefined behaviour. For example, the following
-creates two aliasing `&mut` pointers, and is invalid.
-
-```
-use std::mem;
-let mut x: u8 = 1;
-
-let ref_1: &mut u8 = &mut x;
-let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
-
-// oops, ref_1 and ref_2 point to the same piece of data (x) and are
-// both usable
-*ref_1 = 10;
-*ref_2 = 20;
-```
-
-## Raw pointers
-
-Rust offers two additional pointer types (*raw pointers*), written as
-`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
-respectively; indeed, one of their most common uses is for FFI,
-interfacing with external C libraries.
-
-Raw pointers have much fewer guarantees than other pointer types
-offered by the Rust language and libraries. For example, they
-
-- are not guaranteed to point to valid memory and are not even
-  guaranteed to be non-null (unlike both `Box` and `&`);
-- do not have any automatic clean-up, unlike `Box`, and so require
-  manual resource management;
-- are plain-old-data, that is, they don't move ownership, again unlike
-  `Box`, hence the Rust compiler cannot protect against bugs like
-  use-after-free;
-- lack any form of lifetimes, unlike `&`, and so the compiler cannot
-  reason about dangling pointers; and
-- have no guarantees about aliasing or mutability other than mutation
-  not being allowed directly through a `*const T`.
-
-Fortunately, they come with a redeeming feature: the weaker guarantees
-mean weaker restrictions. The missing restrictions make raw pointers
-appropriate as a building block for implementing things like smart
-pointers and vectors inside libraries. For example, `*` pointers are
-allowed to alias, allowing them to be used to write shared-ownership
-types like reference counted and garbage collected pointers, and even
-thread-safe shared memory types (`Rc` and the `Arc` types are both
-implemented entirely in Rust).
-
-There are two things that you are required to be careful about
-(i.e. require an `unsafe { ... }` block) with raw pointers:
-
-- dereferencing: they can have any value: so possible results include
-  a crash, a read of uninitialised memory, a use-after-free, or
-  reading data as normal.
-- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
-  `.offset` method): this intrinsic uses so-called "in-bounds"
-  arithmetic, that is, it is only defined behaviour if the result is
-  inside (or one-byte-past-the-end) of the object from which the
-  original pointer came.
-
-The latter assumption allows the compiler to optimize more
-effectively. As can be seen, actually *creating* a raw pointer is not
-unsafe, and neither is converting to an integer.
-
-### References and raw pointers
-
-At runtime, a raw pointer `*` and a reference pointing to the same
-piece of data have an identical representation. In fact, an `&T`
-reference will implicitly coerce to an `*const T` raw pointer in safe code
-and similarly for the `mut` variants (both coercions can be performed
-explicitly with, respectively, `value as *const T` and `value as *mut T`).
-
-Going the opposite direction, from `*const` to a reference `&`, is not
-safe. A `&T` is always valid, and so, at a minimum, the raw pointer
-`*const T` has to point to a valid instance of type `T`. Furthermore,
-the resulting pointer must satisfy the aliasing and mutability laws of
-references. The compiler assumes these properties are true for any
-references, no matter how they are created, and so any conversion from
-raw pointers is asserting that they hold. The programmer *must*
-guarantee this.
-
-The recommended method for the conversion is
-
-```
-let i: u32 = 1;
-// explicit cast
-let p_imm: *const u32 = &i as *const u32;
-let mut m: u32 = 2;
-// implicit coercion
-let p_mut: *mut u32 = &mut m;
-
-unsafe {
-    let ref_imm: &u32 = &*p_imm;
-    let ref_mut: &mut u32 = &mut *p_mut;
-}
-```
-
-The `&*x` dereferencing style is preferred to using a `transmute`.
-The latter is far more powerful than necessary, and the more
-restricted operation is harder to use incorrectly; for example, it
-requires that `x` is a pointer (unlike `transmute`).
-
-
-
-## Making the unsafe safe(r)
-
-There are various ways to expose a safe interface around some unsafe
-code:
-
-- store pointers privately (i.e. not in public fields of public
-  structs), so that you can see and control all reads and writes to
-  the pointer in one place.
-- use `assert!()` a lot: since you can't rely on the protection of the
-  compiler & type-system to ensure that your `unsafe` code is correct
-  at compile-time, use `assert!()` to verify that it is doing the
-  right thing at run-time.
-- implement the `Drop` for resource clean-up via a destructor, and use
-  RAII (Resource Acquisition Is Initialization). This reduces the need
-  for any manual memory management by users, and automatically ensures
-  that clean-up is always run, even when the thread panics.
-- ensure that any data stored behind a raw pointer is destroyed at the
-  appropriate time.
diff --git a/src/doc/trpl/unsized-types.md b/src/doc/trpl/unsized-types.md
new file mode 100644 (file)
index 0000000..f307f23
--- /dev/null
@@ -0,0 +1,3 @@
+% Unsized Types
+
+Coming Soon!
diff --git a/src/doc/trpl/unstable.md b/src/doc/trpl/unstable.md
deleted file mode 100644 (file)
index d69831c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-% Unstable Rust
-
-Rust provides three distribution channels for Rust: nightly, beta, and stable.
-Unstable features are only available on nightly Rust. For more details on this
-process, see [this post](http://blog.rust-lang.org/2014/10/30/Stability.html).
-
-To install nightly Rust, you can use `rustup.sh`:
-
-```bash
-$ curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly
-```
-
-If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
-please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
-
-```bash
-$ curl -f -L https://static.rust-lang.org/rustup.sh -O
-$ sudo sh rustup.sh --channel=nightly
-```
-
-If you're on Windows, please download either the [32-bit
-installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe)
-or the [64-bit
-installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe)
-and run it.
-
-If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
-Not every programming language is great for everyone. Just run the uninstall
-script:
-
-```bash
-$ sudo /usr/local/lib/rustlib/uninstall.sh
-```
-
-If you used the Windows installer, just re-run the `.exe` and it will give you
-an uninstall option.
-
-You can re-run this script any time you want to update Rust. Which, at this
-point, is often. Rust is still pre-1.0, and so people assume that you're using
-a very recent Rust.
-
-This brings me to one other point: some people, and somewhat rightfully so, get
-very upset when we tell you to `curl | sudo sh`. And they should be! Basically,
-when you do this, you are trusting that the good people who maintain Rust
-aren't going to hack your computer and do bad things. That's a good instinct!
-If you're one of those people, please check out the documentation on [building
-Rust from Source](https://github.com/rust-lang/rust#building-from-source), or
-[the official binary downloads](http://www.rust-lang.org/install.html). And we
-promise that this method will not be the way to install Rust forever: it's just
-the easiest way to keep people updated while Rust is in its alpha state.
-
diff --git a/src/doc/trpl/vectors.md b/src/doc/trpl/vectors.md
new file mode 100644 (file)
index 0000000..cba4352
--- /dev/null
@@ -0,0 +1,33 @@
+% Vectors
+
+A *vector* is a dynamic or "growable" array, implemented as the standard
+library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means
+later). Vectors always allocate their data on the heap. Vectors are to slices
+what `String` is to `&str`. You can create them with the `vec!` macro:
+
+```{rust}
+let v = vec![1, 2, 3]; // v: Vec<i32>
+```
+
+(Notice that unlike the `println!` macro we've used in the past, we use square
+brackets `[]` with `vec!`. Rust allows you to use either in either situation,
+this is just convention.)
+
+There's an alternate form of `vec!` for repeating an initial value:
+
+```
+let v = vec![0; 10]; // ten zeroes
+```
+
+You can get the length of, iterate over, and subscript vectors just like
+arrays. In addition, (mutable) vectors can grow automatically:
+
+```{rust}
+let mut nums = vec![1, 2, 3]; // mut nums: Vec<i32>
+
+nums.push(4);
+
+println!("The length of nums is now {}", nums.len()); // Prints 4
+```
+
+Vectors have many more useful methods.
diff --git a/src/doc/trpl/while-loops.md b/src/doc/trpl/while-loops.md
new file mode 100644 (file)
index 0000000..508c4ee
--- /dev/null
@@ -0,0 +1,83 @@
+% `while` loops
+
+The other kind of looping construct in Rust is the `while` loop. It looks like
+this:
+
+```{rust}
+let mut x = 5; // mut x: u32
+let mut done = false; // mut done: bool
+
+while !done {
+    x += x - 3;
+    println!("{}", x);
+    if x % 5 == 0 { done = true; }
+}
+```
+
+`while` loops are the correct choice when you're not sure how many times
+you need to loop.
+
+If you need an infinite loop, you may be tempted to write this:
+
+```{rust,ignore}
+while true {
+```
+
+However, Rust has a dedicated keyword, `loop`, to handle this case:
+
+```{rust,ignore}
+loop {
+```
+
+Rust's control-flow analysis treats this construct differently than a
+`while true`, since we know that it will always loop. The details of what
+that _means_ aren't super important to understand at this stage, but in
+general, the more information we can give to the compiler, the better it
+can do with safety and code generation, so you should always prefer
+`loop` when you plan to loop infinitely.
+
+## Ending iteration early
+
+Let's take a look at that `while` loop we had earlier:
+
+```{rust}
+let mut x = 5;
+let mut done = false;
+
+while !done {
+    x += x - 3;
+    println!("{}", x);
+    if x % 5 == 0 { done = true; }
+}
+```
+
+We had to keep a dedicated `mut` boolean variable binding, `done`, to know
+when we should exit out of the loop. Rust has two keywords to help us with
+modifying iteration: `break` and `continue`.
+
+In this case, we can write the loop in a better way with `break`:
+
+```{rust}
+let mut x = 5;
+
+loop {
+    x += x - 3;
+    println!("{}", x);
+    if x % 5 == 0 { break; }
+}
+```
+
+We now loop forever with `loop` and use `break` to break out early.
+
+`continue` is similar, but instead of ending the loop, goes to the next
+iteration. This will only print the odd numbers:
+
+```{rust}
+for x in 0..10 {
+    if x % 2 == 0 { continue; }
+
+    println!("{}", x);
+}
+```
+
+Both `continue` and `break` are valid in both kinds of loops.
index 312076b1b13b2818d43480b32ffea2c96a097ef4..a8a60cc0eb9a318264b990ed0c97f1b07646ef84 100755 (executable)
 
 # This script uses the following Unicode tables:
 # - DerivedCoreProperties.txt
+# - DerivedNormalizationProps.txt
 # - EastAsianWidth.txt
+# - auxiliary/GraphemeBreakProperty.txt
 # - PropList.txt
+# - ReadMe.txt
 # - Scripts.txt
 # - UnicodeData.txt
 #
@@ -51,41 +54,20 @@ expanded_categories = {
     'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
 }
 
-
-# Grapheme cluster data
-# taken from UAX29, http://www.unicode.org/reports/tr29/
-# these code points are excluded from the Control category
-# NOTE: CR and LF are also technically excluded, but for
-# the sake of convenience we leave them in the Control group
-# and manually check them in the appropriate place. This is
-# still compliant with the implementation requirements.
-grapheme_control_exceptions = set([0x200c, 0x200d])
-
-# the Regional_Indicator category
-grapheme_regional_indicator = [(0x1f1e6, 0x1f1ff)]
-
-# "The following ... are specifically excluded" from the SpacingMark category
-# http://www.unicode.org/reports/tr29/#SpacingMark
-grapheme_spacingmark_exceptions = [(0x102b, 0x102c), (0x1038, 0x1038),
-    (0x1062, 0x1064), (0x1067, 0x106d), (0x1083, 0x1083), (0x1087, 0x108c),
-    (0x108f, 0x108f), (0x109a, 0x109c), (0x19b0, 0x19b4), (0x19b8, 0x19b9),
-    (0x19bb, 0x19c0), (0x19c8, 0x19c9), (0x1a61, 0x1a61), (0x1a63, 0x1a64),
-    (0xaa7b, 0xaa7b), (0xaa7d, 0xaa7d)]
-
-# these are included in the SpacingMark category
-grapheme_spacingmark_extra = set([0xe33, 0xeb3])
+# these are the surrogate codepoints, which are not valid rust characters
+surrogate_codepoints = (0xd800, 0xdfff)
 
 def fetch(f):
-    if not os.path.exists(f):
+    if not os.path.exists(os.path.basename(f)):
         os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
                   % f)
 
-    if not os.path.exists(f):
+    if not os.path.exists(os.path.basename(f)):
         sys.stderr.write("cannot load %s" % f)
         exit(1)
 
 def is_surrogate(n):
-    return 0xD800 <= n <= 0xDFFF
+    return surrogate_codepoints[0] <= n <= surrogate_codepoints[1]
 
 def load_unicode_data(f):
     fetch(f)
@@ -228,7 +210,7 @@ def load_properties(f, interestingprops):
     re1 = re.compile("^([0-9A-F]+) +; (\w+)")
     re2 = re.compile("^([0-9A-F]+)\.\.([0-9A-F]+) +; (\w+)")
 
-    for line in fileinput.input(f):
+    for line in fileinput.input(os.path.basename(f)):
         prop = None
         d_lo = 0
         d_hi = 0
@@ -623,7 +605,7 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
         (canon_decomp, compat_decomp, gencats, combines,
                 lowerupper, upperlower) = load_unicode_data("UnicodeData.txt")
         want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase"]
-        other_derived = ["Default_Ignorable_Code_Point", "Grapheme_Extend"]
+        other_derived = ["Default_Ignorable_Code_Point"]
         derived = load_properties("DerivedCoreProperties.txt", want_derived + other_derived)
         scripts = load_properties("Scripts.txt", [])
         props = load_properties("PropList.txt",
@@ -631,12 +613,6 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
         norm_props = load_properties("DerivedNormalizationProps.txt",
                      ["Full_Composition_Exclusion"])
 
-        # grapheme cluster category from DerivedCoreProperties
-        # the rest are defined below
-        grapheme_cats = {}
-        grapheme_cats["Extend"] = derived["Grapheme_Extend"]
-        del(derived["Grapheme_Extend"])
-
         # bsearch_range_table is used in all the property modules below
         emit_bsearch_range_table(rf)
 
@@ -691,34 +667,24 @@ pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
 
         ### grapheme cluster module
         # from http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Break_Property_Values
-        # Hangul syllable categories
-        want_hangul = ["L", "V", "T", "LV", "LVT"]
-        grapheme_cats.update(load_properties("HangulSyllableType.txt", want_hangul))
+        grapheme_cats = load_properties("auxiliary/GraphemeBreakProperty.txt", [])
 
         # Control
+        #  Note 1:
         # This category also includes Cs (surrogate codepoints), but Rust's `char`s are
         # Unicode Scalar Values only, and surrogates are thus invalid `char`s.
-        grapheme_cats["Control"] = set()
-        for cat in ["Zl", "Zp", "Cc", "Cf"]:
-            grapheme_cats["Control"] |= set(ungroup_cat(gencats[cat]))
+        # Thus, we have to remove Cs from the Control category
+        #  Note 2:
+        # 0x0a and 0x0d (CR and LF) are not in the Control category for Graphemes.
+        # However, the Graphemes iterator treats these as a special case, so they
+        # should be included in grapheme_cats["Control"] for our implementation.
         grapheme_cats["Control"] = group_cat(list(
-            grapheme_cats["Control"]
-            - grapheme_control_exceptions
-            | (set(ungroup_cat(gencats["Cn"]))
-               & set(ungroup_cat(derived["Default_Ignorable_Code_Point"])))))
-
-        # Regional Indicator
-        grapheme_cats["RegionalIndicator"] = grapheme_regional_indicator
-
-        # Prepend - "Currently there are no characters with this value"
-        # (from UAX#29, Unicode 7.0)
-
-        # SpacingMark
-        grapheme_cats["SpacingMark"] = group_cat(list(
-            set(ungroup_cat(gencats["Mc"]))
-            - set(ungroup_cat(grapheme_cats["Extend"]))
-            | grapheme_spacingmark_extra
-            - set(ungroup_cat(grapheme_spacingmark_exceptions))))
+            (set(ungroup_cat(grapheme_cats["Control"]))
+             | set(ungroup_cat(grapheme_cats["CR"]))
+             | set(ungroup_cat(grapheme_cats["LF"])))
+            - set(ungroup_cat([surrogate_codepoints]))))
+        del(grapheme_cats["CR"])
+        del(grapheme_cats["LF"])
 
         grapheme_table = []
         for cat in grapheme_cats:
index 68bde1476118d79108a11112d905dd61ee376237..ff176d815916bd8dfe5a928261d61dd16b346a3e 100644 (file)
@@ -668,6 +668,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Pointer for Arc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&*self._ptr, f)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default + Sync + Send> Default for Arc<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
index 2801cf38cb75529d94912551a60a5eab51597235..4468e425a852da07088bd0aca40667c98c05546b 100644 (file)
@@ -275,6 +275,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Pointer for Box<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // It's not possible to extract the inner Uniq directly from the Box,
+        // instead we cast it to a *const which aliases the Unique
+        let ptr: *const T = &**self;
+        fmt::Pointer::fmt(&ptr, f)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Deref for Box<T> {
     type Target = T;
index 56822cfe28a3588296bba06b899ab749969c3235..67805d10a4a6313736b37bf4eb548cb82f26f3fb 100644 (file)
@@ -634,6 +634,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Pointer for Rc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&*self._ptr, f)
+    }
+}
+
 /// A weak version of `Rc<T>`.
 ///
 /// Weak references do not count when determining if the inner value should be
index ff923fb19068fb0a8187ea5684d561fac6bfd182..8622b8cd93568d8a42c3d909311002720852f9d0 100644 (file)
@@ -85,7 +85,6 @@
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
 use core::iter::Iterator;
-use core::iter::MultiplicativeIterator;
 use core::marker::Sized;
 use core::mem::size_of;
 use core::mem;
@@ -1182,7 +1181,7 @@ fn new_pos(i: usize, s: Direction) -> usize {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         // For a vector of size n, there are exactly n! permutations.
-        let n = (2..self.sdir.len() + 1).product();
+        let n: usize = (2..self.sdir.len() + 1).product();
         (n - self.swaps_made, Some(n - self.swaps_made))
     }
 }
index 28ba7369d52a3ffac26418334130ce0f0d5032bb..98f2933effc2cf94667a5c87a9d372ba19625b0c 100644 (file)
@@ -53,7 +53,6 @@
 use self::DecompositionType::*;
 
 use core::clone::Clone;
-use core::iter::AdditiveIterator;
 use core::iter::{Iterator, Extend};
 use core::option::Option::{self, Some, None};
 use core::result::Result;
@@ -116,7 +115,7 @@ fn connect(&self, sep: &str) -> String {
         // this is wrong without the guarantee that `self` is non-empty
         // `len` calculation may overflow but push_str but will check boundaries
         let len = sep.len() * (self.len() - 1)
-            + self.iter().map(|s| s.as_ref().len()).sum();
+            + self.iter().map(|s| s.as_ref().len()).sum::<usize>();
         let mut result = String::with_capacity(len);
         let mut first = true;
 
index bc07c9b65a5886f49ef714432ebfa9770981f80d..15f15900e783038a82859c10d37eca83f8839d82 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::cmp::Ordering::{Equal, Greater, Less};
-use std::iter::AdditiveIterator;
 use std::str::{Utf8Error, from_utf8};
 
 #[test]
index 85e5bde48598eee8bde8ee706fc365e60f19104c..91747d7405ff6fe12cd9f31f758c5d616e60e0a1 100644 (file)
@@ -97,6 +97,27 @@ impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
             #[inline]
             fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
         }
+
+        #[unstable(feature = "core", reason = "brand new")]
+        impl<$($A,)* ReturnType> Clone for extern "C" fn($($A),*) -> ReturnType {
+            /// Return a copy of a function pointer
+            #[inline]
+            fn clone(&self) -> extern "C" fn($($A),*) -> ReturnType { *self }
+        }
+
+        #[unstable(feature = "core", reason = "brand new")]
+        impl<$($A,)* ReturnType> Clone for unsafe extern "Rust" fn($($A),*) -> ReturnType {
+            /// Return a copy of a function pointer
+            #[inline]
+            fn clone(&self) -> unsafe extern "Rust" fn($($A),*) -> ReturnType { *self }
+        }
+
+        #[unstable(feature = "core", reason = "brand new")]
+        impl<$($A,)* ReturnType> Clone for unsafe extern "C" fn($($A),*) -> ReturnType {
+            /// Return a copy of a function pointer
+            #[inline]
+            fn clone(&self) -> unsafe extern "C" fn($($A),*) -> ReturnType { *self }
+        }
     )
 }
 
index 939d9b4ab0ec4c34c3038fb8a4591bbce494db2a..ffe49a25a0d2f5002d63c012c25bd1187f3a3e28 100644 (file)
 
 use clone::Clone;
 use cmp;
-use cmp::Ord;
+use cmp::{Ord, PartialOrd, PartialEq};
 use default::Default;
 use marker;
 use mem;
 use num::{Int, Zero, One};
-use ops::{self, Add, Sub, FnMut, RangeFrom};
+use ops::{self, Add, Sub, FnMut, Mul, RangeFrom};
 use option::Option::{self, Some, None};
 use marker::Sized;
 use usize;
@@ -489,15 +489,14 @@ fn fuse(self) -> Fuse<Self> where Self: Sized {
     ///
     /// ```
     /// # #![feature(core)]
-    /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
-    /// let sum = a.iter()
-    ///            .map(|x| *x)
-    ///            .inspect(|&x| println!("filtering {}", x))
-    ///            .filter(|&x| x % 2 == 0)
-    ///            .inspect(|&x| println!("{} made it through", x))
-    ///            .sum();
+    /// let sum: i32 = a.iter()
+    ///                 .map(|x| *x)
+    ///                 .inspect(|&x| println!("filtering {}", x))
+    ///                 .filter(|&x| x % 2 == 0)
+    ///                 .inspect(|&x| println!("{} made it through", x))
+    ///                 .sum();
     /// println!("{}", sum);
     /// ```
     #[inline]
@@ -1022,6 +1021,47 @@ fn reverse_in_place<'a, T: 'a>(&mut self) where
             }
         }
     }
+
+    /// Iterates over the entire iterator, summing up all the elements
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(core)]
+    ///
+    /// let a = [1, 2, 3, 4, 5];
+    /// let mut it = a.iter().cloned();
+    /// assert!(it.sum::<i32>() == 15);
+    /// ```
+    #[unstable(feature="core")]
+    fn sum<S=<Self as Iterator>::Item>(self) -> S where
+        S: Add<Self::Item, Output=S> + Zero,
+        Self: Sized,
+    {
+        self.fold(Zero::zero(), |s, e| s + e)
+    }
+
+    /// Iterates over the entire iterator, multiplying all the elements
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(core)]
+    ///
+    /// fn factorial(n: u32) -> u32 {
+    ///     (1..).take_while(|&i| i <= n).product()
+    /// }
+    /// assert!(factorial(0) == 1);
+    /// assert!(factorial(1) == 1);
+    /// assert!(factorial(5) == 120);
+    /// ```
+    #[unstable(feature="core")]
+    fn product<P=<Self as Iterator>::Item>(self) -> P where
+        P: Mul<Self::Item, Output=P> + One,
+        Self: Sized,
+    {
+        self.fold(One::one(), |p, e| p * e)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1222,95 +1262,6 @@ fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
     }
 }
 
-/// A trait for iterators over elements which can be added together
-#[unstable(feature = "core",
-           reason = "needs to be re-evaluated as part of numerics reform")]
-pub trait AdditiveIterator<A> {
-    /// Iterates over the entire iterator, summing up all the elements
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::iter::AdditiveIterator;
-    ///
-    /// let a = [1, 2, 3, 4, 5];
-    /// let mut it = a.iter().cloned();
-    /// assert!(it.sum() == 15);
-    /// ```
-    fn sum(self) -> A;
-}
-
-macro_rules! impl_additive {
-    ($A:ty, $init:expr) => {
-        #[unstable(feature = "core", reason = "trait is experimental")]
-        impl<T: Iterator<Item=$A>> AdditiveIterator<$A> for T {
-            #[inline]
-            fn sum(self) -> $A {
-                self.fold($init, |acc, x| acc + x)
-            }
-        }
-    };
-}
-impl_additive! { i8,   0 }
-impl_additive! { i16,  0 }
-impl_additive! { i32,  0 }
-impl_additive! { i64,  0 }
-impl_additive! { isize,  0 }
-impl_additive! { u8,   0 }
-impl_additive! { u16,  0 }
-impl_additive! { u32,  0 }
-impl_additive! { u64,  0 }
-impl_additive! { usize, 0 }
-impl_additive! { f32,  0.0 }
-impl_additive! { f64,  0.0 }
-
-/// A trait for iterators over elements which can be multiplied together.
-#[unstable(feature = "core",
-           reason = "needs to be re-evaluated as part of numerics reform")]
-pub trait MultiplicativeIterator<A> {
-    /// Iterates over the entire iterator, multiplying all the elements
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::iter::MultiplicativeIterator;
-    ///
-    /// fn factorial(n: usize) -> usize {
-    ///     (1..).take_while(|&i| i <= n).product()
-    /// }
-    /// assert!(factorial(0) == 1);
-    /// assert!(factorial(1) == 1);
-    /// assert!(factorial(5) == 120);
-    /// ```
-    fn product(self) -> A;
-}
-
-macro_rules! impl_multiplicative {
-    ($A:ty, $init:expr) => {
-        #[unstable(feature = "core", reason = "trait is experimental")]
-        impl<T: Iterator<Item=$A>> MultiplicativeIterator<$A> for T {
-            #[inline]
-            fn product(self) -> $A {
-                self.fold($init, |acc, x| acc * x)
-            }
-        }
-    };
-}
-impl_multiplicative! { i8,   1 }
-impl_multiplicative! { i16,  1 }
-impl_multiplicative! { i32,  1 }
-impl_multiplicative! { i64,  1 }
-impl_multiplicative! { isize,  1 }
-impl_multiplicative! { u8,   1 }
-impl_multiplicative! { u16,  1 }
-impl_multiplicative! { u32,  1 }
-impl_multiplicative! { u64,  1 }
-impl_multiplicative! { usize, 1 }
-impl_multiplicative! { f32,  1.0 }
-impl_multiplicative! { f64,  1.0 }
-
 /// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
 /// more detail.
 #[derive(Clone, PartialEq, Debug)]
@@ -2431,7 +2382,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 /// two `Step` objects.
 #[unstable(feature = "step_trait",
            reason = "likely to be replaced by finer-grained traits")]
-pub trait Step: Ord {
+pub trait Step: PartialOrd {
     /// Steps `self` if possible.
     fn step(&self, by: &Self) -> Option<Self>;
 
@@ -2598,7 +2549,10 @@ pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-impl<A: Step + One + Clone> Iterator for RangeInclusive<A> {
+impl<A> Iterator for RangeInclusive<A> where
+    A: PartialEq + Step + One + Clone,
+    for<'a> &'a A: Add<&'a A, Output = A>
+{
     type Item = A;
 
     #[inline]
@@ -2628,9 +2582,10 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-impl<A> DoubleEndedIterator for RangeInclusive<A>
-    where A: Step + One + Clone,
-          for<'a> &'a A: Sub<Output=A>
+impl<A> DoubleEndedIterator for RangeInclusive<A> where
+    A: PartialEq + Step + One + Clone,
+    for<'a> &'a A: Add<&'a A, Output = A>,
+    for<'a> &'a A: Sub<Output=A>
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2758,24 +2713,17 @@ impl ExactSizeIterator for ops::Range<$t> { }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
-impl<A: Step + One + Clone> Iterator for ops::Range<A> {
+impl<A: Step + One> Iterator for ops::Range<A> where
+    for<'a> &'a A: Add<&'a A, Output = A>
+{
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.start < self.end {
-            match self.start.step(&A::one()) {
-                Some(mut n) => {
-                    mem::swap(&mut n, &mut self.start);
-                    Some(n)
-                },
-                None => {
-                    let mut n = self.end.clone();
-                    mem::swap(&mut n, &mut self.start);
-                    Some(n)
-
-                }
-            }
+            let mut n = &self.start + &A::one();
+            mem::swap(&mut n, &mut self.start);
+            Some(n)
         } else {
             None
         }
@@ -2797,6 +2745,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
 impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
+    for<'a> &'a A: Add<&'a A, Output = A>,
     for<'a> &'a A: Sub<&'a A, Output = A>
 {
     #[inline]
@@ -2812,15 +2761,16 @@ fn next_back(&mut self) -> Option<A> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
-impl<A: Step + One> Iterator for ops::RangeFrom<A> {
+impl<A: Step + One> Iterator for ops::RangeFrom<A> where
+    for<'a> &'a A: Add<&'a A, Output = A>
+{
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        self.start.step(&A::one()).map(|mut n| {
-            mem::swap(&mut n, &mut self.start);
-            n
-        })
+        let mut n = &self.start + &A::one();
+        mem::swap(&mut n, &mut self.start);
+        Some(n)
     }
 }
 
index 28e0bcf13dd0911132938784bd5096d264a55a71..7868e299cfcad4413c3f3c97e0995cee590e7a03 100644 (file)
@@ -86,6 +86,20 @@ fn one() -> $t { 1 }
 }
 zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 
+macro_rules! zero_one_impl_float {
+    ($($t:ty)*) => ($(
+        impl Zero for $t {
+            #[inline]
+            fn zero() -> $t { 0.0 }
+        }
+        impl One for $t {
+            #[inline]
+            fn one() -> $t { 1.0 }
+        }
+    )*)
+}
+zero_one_impl_float! { f32 f64 }
+
 /// A built-in signed or unsigned integer.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[deprecated(since = "1.0.0",
index ff51e25fcbf2535f9cf81a3d0129c7dc7aa556c3..36b33e7581dd98fb5a3d12a3c0f6380b56e70999 100644 (file)
@@ -94,6 +94,7 @@
 use clone::Clone;
 use intrinsics;
 use ops::Deref;
+use core::fmt;
 use option::Option::{self, Some, None};
 use marker::{PhantomData, Send, Sized, Sync};
 use nonzero::NonZero;
@@ -570,3 +571,10 @@ fn deref<'a>(&'a self) -> &'a *mut T {
         unsafe { mem::transmute(&*self.pointer) }
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Pointer for Unique<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&*self.pointer, f)
+    }
+}
index af80d347f028e02b66d4b8c572993c9b4d5edda4..bfa9c798d357951782e4ea973fb0ad467741dd51 100644 (file)
@@ -329,17 +329,17 @@ fn test_iterator_len() {
 #[test]
 fn test_iterator_sum() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().sum(), 6);
-    assert_eq!(v.iter().cloned().sum(), 55);
-    assert_eq!(v[..0].iter().cloned().sum(), 0);
+    assert_eq!(v[..4].iter().cloned().sum::<i32>(), 6);
+    assert_eq!(v.iter().cloned().sum::<i32>(), 55);
+    assert_eq!(v[..0].iter().cloned().sum::<i32>(), 0);
 }
 
 #[test]
 fn test_iterator_product() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().product(), 0);
-    assert_eq!(v[1..5].iter().cloned().product(), 24);
-    assert_eq!(v[..0].iter().cloned().product(), 1);
+    assert_eq!(v[..4].iter().cloned().product::<i32>(), 0);
+    assert_eq!(v[1..5].iter().cloned().product::<i32>(), 24);
+    assert_eq!(v[..0].iter().cloned().product::<i32>(), 1);
 }
 
 #[test]
index 0a29ed90ad46100d863d69a2e799c34000632a69..b15304d6dc50c5c5ce646efff5a4700306e39c35 100644 (file)
 
 #![allow(non_snake_case)]
 
+// Error messages for EXXXX errors.
+// Each message should start and end with a new line, and be wrapped to 80 characters.
+// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
 register_long_diagnostics! {
-    E0001: r##"
-    This error suggests that the expression arm corresponding to the noted pattern
-    will never be reached as for all possible values of the expression being matched,
-    one of the preceding patterns will match.
 
-    This means that perhaps some of the preceding patterns are too general, this
-    one is too specific or the ordering is incorrect.
+E0001: r##"
+This error suggests that the expression arm corresponding to the noted pattern
+will never be reached as for all possible values of the expression being
+matched, one of the preceding patterns will match.
+
+This means that perhaps some of the preceding patterns are too general, this one
+is too specific or the ordering is incorrect.
+"##,
+
+E0002: r##"
+This error indicates that an empty match expression is illegal because the type
+it is matching on is non-empty (there exist values of this type). In safe code
+it is impossible to create an instance of an empty type, so empty match
+expressions are almost never desired.  This error is typically fixed by adding
+one or more cases to the match expression.
+
+An example of an empty type is `enum Empty { }`.
 "##,
 
-    E0003: r##"
-    Not-a-Number (NaN) values can not be compared for equality and hence can never match
-    the input to a match expression. To match against NaN values, you should instead use
-    the `is_nan` method in a guard, as in: x if x.is_nan() => ...
+E0003: r##"
+Not-a-Number (NaN) values cannot be compared for equality and hence can never
+match the input to a match expression. To match against NaN values, you should
+instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
 "##,
 
-    E0004: r##"
-    This error indicates that the compiler can not guarantee a matching pattern for one
-    or more possible inputs to a match expression. Guaranteed matches are required in order
-    to assign values to match expressions, or alternatively, determine the flow of execution.
+E0004: r##"
+This error indicates that the compiler cannot guarantee a matching pattern for
+one or more possible inputs to a match expression. Guaranteed matches are
+required in order to assign values to match expressions, or alternatively,
+determine the flow of execution.
 
-    If you encounter this error you must alter your patterns so that every possible value of
-    the input type is matched. For types with a small number of variants (like enums) you
-    should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard
-    pattern can be added after all other patterns to match "anything else".
+If you encounter this error you must alter your patterns so that every possible
+value of the input type is matched. For types with a small number of variants
+(like enums) you should probably cover all cases explicitly. Alternatively, the
+underscore `_` wildcard pattern can be added after all other patterns to match
+"anything else".
 "##,
 
-    // FIXME: Remove duplication here?
-    E0005: r##"
-    Patterns used to bind names must be irrefutable, that is, they must guarantee that a
-    name will be extracted in all cases. If you encounter this error you probably need
-    to use a `match` or `if let` to deal with the possibility of failure.
+// FIXME: Remove duplication here?
+E0005: r##"
+Patterns used to bind names must be irrefutable, that is, they must guarantee that a
+name will be extracted in all cases. If you encounter this error you probably need
+to use a `match` or `if let` to deal with the possibility of failure.
 "##,
 
-    E0006: r##"
-    Patterns used to bind names must be irrefutable, that is, they must guarantee that a
-    name will be extracted in all cases. If you encounter this error you probably need
-    to use a `match` or `if let` to deal with the possibility of failure.
+E0006: r##"
+Patterns used to bind names must be irrefutable, that is, they must guarantee that a
+name will be extracted in all cases. If you encounter this error you probably need
+to use a `match` or `if let` to deal with the possibility of failure.
+"##,
+
+E0007: r##"
+This error indicates that the bindings in a match arm would require a value to
+be moved into more than one location, thus violating unique ownership. Code like
+the following is invalid as it requires the entire Option<String> to be moved
+into a variable called `op_string` while simultaneously requiring the inner
+String to be moved into a variable called `s`.
+
+let x = Some("s".to_string());
+match x {
+    op_string @ Some(s) => ...
+    None => ...
+}
+
+See also Error 303.
+"##,
+
+E0008: r##"
+Names bound in match arms retain their type in pattern guards. As such, if a
+name is bound by move in a pattern, it should also be moved to wherever it is
+referenced in the pattern guard code. Doing so however would prevent the name
+from being available in the body of the match arm. Consider the following:
+
+match Some("hi".to_string()) {
+    Some(s) if s.len() == 0 => // use s.
+    ...
+}
+
+The variable `s` has type String, and its use in the guard is as a variable of
+type String. The guard code effectively executes in a separate scope to the body
+of the arm, so the value would be moved into this anonymous scope and therefore
+become unavailable in the body of the arm. Although this example seems
+innocuous, the problem is most clear when considering functions that take their
+argument by value.
+
+match Some("hi".to_string()) {
+    Some(s) if { drop(s); false } => (),
+    Some(s) => // use s.
+    ...
+}
+
+The value would be dropped in the guard then become unavailable not only in the
+body of that arm but also in all subsequent arms! The solution is to bind by
+reference when using guards or refactor the entire expression, perhaps by
+putting the condition inside the body of the arm.
+"##,
+
+E0303: r##"
+In certain cases it is possible for sub-bindings to violate memory safety.
+Updates to the borrow checker in a future version of Rust may remove this
+restriction, but for now patterns must be rewritten without sub-bindings.
+
+// Code like this...
+match Some(5) {
+    ref op_num @ Some(num) => ...
+    None => ...
+}
+
+// ... should be updated to code like this.
+match Some(5) {
+    Some(num) => {
+        let op_num = &Some(num);
+        ...
+    }
+    None => ...
+}
+
+See also https://github.com/rust-lang/rust/issues/14587
 "##
+
 }
 
 register_diagnostics! {
-    E0002,
-    E0007,
-    E0008,
     E0009,
     E0010,
     E0011,
     E0300, // unexpanded macro
     E0301, // cannot mutable borrow in a pattern guard
     E0302, // cannot assign in a pattern guard
-    E0303, // pattern bindings are not allowed after an `@`
     E0304, // expected signed integer constant
     E0305, // expected constant
     E0306, // expected positive integer for repeat count
index 9836f8d7991df37b4387f2b711e84311b367c2b1..cce31b1f4c249fb5aaa89758adae6428947cdfeb 100644 (file)
@@ -369,6 +369,16 @@ fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
 
 fn parse_scope(st: &mut PState) -> region::CodeExtent {
     match next(st) {
+        'P' => {
+            assert_eq!(next(st), '[');
+            let fn_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), '|');
+            let body_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), ']');
+            region::CodeExtent::ParameterScope {
+                fn_id: fn_id, body_id: body_id
+            }
+        }
         'M' => {
             let node_id = parse_uint(st) as ast::NodeId;
             region::CodeExtent::Misc(node_id)
@@ -378,8 +388,11 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent {
             region::CodeExtent::DestructionScope(node_id)
         }
         'B' => {
+            assert_eq!(next(st), '[');
             let node_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), '|');
             let first_stmt_index = parse_uint(st);
+            assert_eq!(next(st), ']');
             let block_remainder = region::BlockRemainder {
                 block: node_id, first_statement_index: first_stmt_index,
             };
index 7a2df4966283a6d7339d3040e2e312fa927a32c5..90a905f1840714401c9cfe4ec1c36b5ffe5ed7c9 100644 (file)
@@ -275,9 +275,11 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
 
 fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
     match scope {
+        region::CodeExtent::ParameterScope {
+            fn_id, body_id } => mywrite!(w, "P[{}|{}]", fn_id, body_id),
         region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
         region::CodeExtent::Remainder(region::BlockRemainder {
-            block: b, first_statement_index: i }) => mywrite!(w, "B{}{}", b, i),
+            block: b, first_statement_index: i }) => mywrite!(w, "B[{}|{}]", b, i),
         region::CodeExtent::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
     }
 }
index b6061f39233d20b26d2f7a11535223310f67c192..998ce0cac47003c496ba85c3369743bb86f61888 100644 (file)
@@ -457,7 +457,11 @@ fn tr(&self, dcx: &DecodeContext) -> def::Def {
           def::DefMethod(did, p) => {
             def::DefMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
           }
-          def::DefSelfTy(nid) => { def::DefSelfTy(dcx.tr_id(nid)) }
+          def::DefSelfTy(opt_did, impl_ids) => { def::DefSelfTy(opt_did.map(|did| did.tr(dcx)),
+                                                                impl_ids.map(|(nid1, nid2)| {
+                                                                    (dcx.tr_id(nid1),
+                                                                     dcx.tr_id(nid2))
+                                                                })) }
           def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
           def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
           def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
index 79f4d62b45e75fb41740fada747d1a5274163cc4..14df040fb79edc02c958da53eaf0d64cdbb44220 100644 (file)
@@ -26,7 +26,7 @@
 use middle::ty;
 use std::cmp::Ordering;
 use std::fmt;
-use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat};
+use std::iter::{range_inclusive, FromIterator, IntoIterator, repeat};
 use std::slice;
 use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
 use syntax::ast_util;
@@ -76,7 +76,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
         }).collect();
 
-        let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1;
+        let total_width = column_widths.iter().cloned().sum::<usize>() + column_count * 3 + 1;
         let br = repeat('+').take(total_width).collect::<String>();
         try!(write!(f, "{}\n", br));
         for row in pretty_printed_matrix {
index 6707a4d3fd775454ca0d9a109469a08c6cf3c9a9..f0b359088549b05333b2e01efba7ed1e9c5820ea 100644 (file)
@@ -22,7 +22,8 @@
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Def {
     DefFn(ast::DefId, bool /* is_ctor */),
-    DefSelfTy(/* trait id */ ast::NodeId),
+    DefSelfTy(Option<ast::DefId>,                    // trait id
+              Option<(ast::NodeId, ast::NodeId)>),   // (impl id, self type id)
     DefMod(ast::DefId),
     DefForeignMod(ast::DefId),
     DefStatic(ast::DefId, bool /* is_mutbl */),
@@ -139,18 +140,19 @@ pub fn def_id(&self) -> ast::DefId {
             DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
-            DefMethod(id, _) | DefConst(id) => {
+            DefMethod(id, _) | DefConst(id) | DefSelfTy(Some(id), None)=> {
                 id
             }
             DefLocal(id) |
-            DefSelfTy(id) |
             DefUpvar(id, _) |
             DefRegion(id) |
-            DefLabel(id) => {
+            DefLabel(id)  |
+            DefSelfTy(_, Some((_, id))) => {
                 local_def(id)
             }
 
-            DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
+            DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy"),
+            DefSelfTy(..) => panic!("attempted .def_id() on invalid DefSelfTy"),
         }
     }
 
index 652f661325206fdf89ba15fc839c8e3780fc21c7..5131322dc41ea701b3b4b25bb03d69623d50826d 100644 (file)
            RustcDecodable, Debug, Copy)]
 pub enum CodeExtent {
     Misc(ast::NodeId),
-    DestructionScope(ast::NodeId), // extent of destructors for temporaries of node-id
+
+    // extent of parameters passed to a function or closure (they
+    // outlive its body)
+    ParameterScope { fn_id: ast::NodeId, body_id: ast::NodeId },
+
+    // extent of destructors for temporaries of node-id
+    DestructionScope(ast::NodeId),
+
+    // extent of code following a `let id = expr;` binding in a block
     Remainder(BlockRemainder)
 }
 
@@ -153,15 +161,19 @@ pub fn from_node_id(node_id: ast::NodeId) -> CodeExtent {
     pub fn node_id(&self) -> ast::NodeId {
         match *self {
             CodeExtent::Misc(node_id) => node_id,
+
+            // These cases all return rough approximations to the
+            // precise extent denoted by `self`.
             CodeExtent::Remainder(br) => br.block,
             CodeExtent::DestructionScope(node_id) => node_id,
+            CodeExtent::ParameterScope { fn_id: _, body_id } => body_id,
         }
     }
 
     /// Maps this scope to a potentially new one according to the
     /// NodeId transformer `f_id`.
-    pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
-        F: FnOnce(ast::NodeId) -> ast::NodeId,
+    pub fn map_id<F>(&self, mut f_id: F) -> CodeExtent where
+        F: FnMut(ast::NodeId) -> ast::NodeId,
     {
         match *self {
             CodeExtent::Misc(node_id) => CodeExtent::Misc(f_id(node_id)),
@@ -170,6 +182,8 @@ pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
                     block: f_id(br.block), first_statement_index: br.first_statement_index }),
             CodeExtent::DestructionScope(node_id) =>
                 CodeExtent::DestructionScope(f_id(node_id)),
+            CodeExtent::ParameterScope { fn_id, body_id } =>
+                CodeExtent::ParameterScope { fn_id: f_id(fn_id), body_id: f_id(body_id) },
         }
     }
 
@@ -180,6 +194,7 @@ pub fn span(&self, ast_map: &ast_map::Map) -> Option<Span> {
         match ast_map.find(self.node_id()) {
             Some(ast_map::NodeBlock(ref blk)) => {
                 match *self {
+                    CodeExtent::ParameterScope { .. } |
                     CodeExtent::Misc(_) |
                     CodeExtent::DestructionScope(_) => Some(blk.span),
 
@@ -277,6 +292,7 @@ enum InnermostDeclaringBlock {
     Block(ast::NodeId),
     Statement(DeclaringStatementContext),
     Match(ast::NodeId),
+    FnDecl { fn_id: ast::NodeId, body_id: ast::NodeId },
 }
 
 impl InnermostDeclaringBlock {
@@ -285,6 +301,8 @@ fn to_code_extent(&self) -> Option<CodeExtent> {
             InnermostDeclaringBlock::None => {
                 return Option::None;
             }
+            InnermostDeclaringBlock::FnDecl { fn_id, body_id } =>
+                CodeExtent::ParameterScope { fn_id: fn_id, body_id: body_id },
             InnermostDeclaringBlock::Block(id) |
             InnermostDeclaringBlock::Match(id) => CodeExtent::from_node_id(id),
             InnermostDeclaringBlock::Statement(s) =>  s.to_code_extent(),
@@ -1198,13 +1216,20 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
            body.id,
            visitor.cx.parent);
 
+    // This scope covers the function body, which includes the
+    // bindings introduced by let statements as well as temporaries
+    // created by the fn's tail expression (if any). It does *not*
+    // include the fn parameters (see below).
     let body_scope = CodeExtent::from_node_id(body.id);
     visitor.region_maps.mark_as_terminating_scope(body_scope);
 
     let dtor_scope = CodeExtent::DestructionScope(body.id);
     visitor.region_maps.record_encl_scope(body_scope, dtor_scope);
 
-    record_superlifetime(visitor, dtor_scope, body.span);
+    let fn_decl_scope = CodeExtent::ParameterScope { fn_id: id, body_id: body.id };
+    visitor.region_maps.record_encl_scope(dtor_scope, fn_decl_scope);
+
+    record_superlifetime(visitor, fn_decl_scope, body.span);
 
     if let Some(root_id) = visitor.cx.root_id {
         visitor.region_maps.record_fn_parent(body.id, root_id);
@@ -1212,11 +1237,13 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
 
     let outer_cx = visitor.cx;
 
-    // The arguments and `self` are parented to the body of the fn.
+    // The arguments and `self` are parented to the fn.
     visitor.cx = Context {
         root_id: Some(body.id),
-        parent: InnermostEnclosingExpr::Some(body.id),
-        var_parent: InnermostDeclaringBlock::Block(body.id)
+        parent: InnermostEnclosingExpr::None,
+        var_parent: InnermostDeclaringBlock::FnDecl {
+            fn_id: id, body_id: body.id
+        },
     };
     visit::walk_fn_decl(visitor, decl);
 
index 60b422b3769d5bc0a2c322a590d89b776a691493..7358b4cc0f6ecbbf5fe517125b72be04f5fb00dd 100644 (file)
@@ -113,6 +113,9 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
         };
         let scope_decorated_tag = match scope {
             region::CodeExtent::Misc(_) => tag,
+            region::CodeExtent::ParameterScope { .. } => {
+                "scope of parameters for function"
+            }
             region::CodeExtent::DestructionScope(_) => {
                 new_string = format!("destruction scope surrounding {}", tag);
                 &*new_string
@@ -952,6 +955,8 @@ fn repr(&self, tcx: &ctxt) -> String {
 impl<'tcx> Repr<'tcx> for region::CodeExtent {
     fn repr(&self, _tcx: &ctxt) -> String {
         match *self {
+            region::CodeExtent::ParameterScope { fn_id, body_id } =>
+                format!("ParameterScope({}, {})", fn_id, body_id),
             region::CodeExtent::Misc(node_id) =>
                 format!("Misc({})", node_id),
             region::CodeExtent::DestructionScope(node_id) =>
index b32c6829a221ba481d87a8e5f865fc50e1ba69e1..89c19cfb0b02a8d714676eec12a1921f9dfad349 100644 (file)
@@ -277,7 +277,8 @@ fn early_callback(&mut self,
             Some(ref code) => {
                 match descriptions.find_description(&code[..]) {
                     Some(ref description) => {
-                        println!("{}", description);
+                        // Slice off the leading newline and print.
+                        print!("{}", &description[1..]);
                     }
                     None => {
                         early_error(&format!("no extended information for {}", code));
index 1acc121078e4ffae2499eb246bb1eb3e861aba2f..2884cebf6668f6e1626bd1614770de53591d3d9a 100644 (file)
@@ -1178,7 +1178,7 @@ fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
         let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
             // `int` etc. (None doesn't seem to occur.)
             None | Some(def::DefPrimTy(..)) => return false,
-            Some(def) => def.def_id()
+            Some(def) => def.def_id(),
         };
         // A path can only be private if:
         // it's in this crate...
index 045320e4fa42565e3782bd682d76757d03631911..f90c7640f8ce70770ee64359177953bfcd04182c 100644 (file)
@@ -1689,7 +1689,7 @@ fn upvarify(&self,
                     }
                 }
             }
-            DefTyParam(..) | DefSelfTy(_) => {
+            DefTyParam(..) | DefSelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
@@ -1797,63 +1797,57 @@ fn resolve_item(&mut self, item: &Item) {
             }
 
             ItemDefaultImpl(_, ref trait_ref) => {
-                self.with_optional_trait_ref(Some(trait_ref), |_| {});
+                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
             }
-            ItemImpl(_, _,
+            ItemImpl(_,
+                     _,
                      ref generics,
-                     ref implemented_traits,
+                     ref opt_trait_ref,
                      ref self_type,
                      ref impl_items) => {
                 self.resolve_implementation(generics,
-                                            implemented_traits,
+                                            opt_trait_ref,
                                             &**self_type,
+                                            item.id,
                                             &impl_items[..]);
             }
 
             ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
                 self.check_if_primitive_type_name(name, item.span);
 
-                // Create a new rib for the self type.
-                let mut self_type_rib = Rib::new(ItemRibKind);
-
-                // plain insert (no renaming, types are not currently hygienic....)
-                let name = special_names::type_self;
-                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
-                self.type_ribs.push(self_type_rib);
-
                 // Create a new rib for the trait-wide type parameters.
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                TypeSpace,
-                                                               NormalRibKind),
+                                                               ItemRibKind),
                                              |this| {
-                    this.visit_generics(generics);
-                    visit::walk_ty_param_bounds_helper(this, bounds);
-
-                    for trait_item in trait_items {
-                        // Create a new rib for the trait_item-specific type
-                        // parameters.
-                        //
-                        // FIXME #4951: Do we need a node ID here?
-
-                        let type_parameters = match trait_item.node {
-                            ast::MethodTraitItem(ref sig, _) => {
-                                HasTypeParameters(&sig.generics,
-                                                  FnSpace,
-                                                  MethodRibKind)
-                            }
-                            ast::TypeTraitItem(..) => {
-                                this.check_if_primitive_type_name(trait_item.ident.name,
-                                                                  trait_item.span);
-                                NoTypeParameters
-                            }
-                        };
-                        this.with_type_parameter_rib(type_parameters, |this| {
-                            visit::walk_trait_item(this, trait_item)
-                        });
-                    }
+                    this.with_self_rib(DefSelfTy(Some(local_def(item.id)), None), |this| {
+                        this.visit_generics(generics);
+                        visit::walk_ty_param_bounds_helper(this, bounds);
+
+                        for trait_item in trait_items {
+                            // Create a new rib for the trait_item-specific type
+                            // parameters.
+                            //
+                            // FIXME #4951: Do we need a node ID here?
+
+                            let type_parameters = match trait_item.node {
+                                ast::MethodTraitItem(ref sig, _) => {
+                                    HasTypeParameters(&sig.generics,
+                                                      FnSpace,
+                                                      MethodRibKind)
+                                }
+                                ast::TypeTraitItem(..) => {
+                                    this.check_if_primitive_type_name(trait_item.ident.name,
+                                                                      trait_item.span);
+                                    NoTypeParameters
+                                }
+                            };
+                            this.with_type_parameter_rib(type_parameters, |this| {
+                                visit::walk_trait_item(this, trait_item)
+                            });
+                        }
+                    });
                 });
-
-                self.type_ribs.pop();
             }
 
             ItemMod(_) | ItemForeignMod(_) => {
@@ -2030,8 +2024,8 @@ fn resolve_generics(&mut self, generics: &Generics) {
         visit::walk_generics(self, generics);
     }
 
-    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
-        F: FnOnce(&mut Resolver) -> T,
+    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
+        where F: FnOnce(&mut Resolver) -> T
     {
         // Handle nested impls (inside fn bodies)
         let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
@@ -2044,29 +2038,44 @@ fn with_optional_trait_ref<T, F>(&mut self,
                                      opt_trait_ref: Option<&TraitRef>,
                                      f: F)
                                      -> T
-        where F: FnOnce(&mut Resolver) -> T,
+        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
     {
         let mut new_val = None;
+        let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
-            match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
-                Ok(path_res) => {
-                    self.record_def(trait_ref.ref_id, path_res);
-                    new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
-                }
-                Err(_) => { /* error was already reported */ }
+            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
+                                                               &trait_ref.path, 0) {
+                assert!(path_res.depth == 0);
+                self.record_def(trait_ref.ref_id, path_res);
+                new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
+                new_id = Some(path_res.base_def.def_id());
             }
             visit::walk_trait_ref(self, trait_ref);
         }
         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
-        let result = f(self);
+        let result = f(self, new_id);
         self.current_trait_ref = original_trait_ref;
         result
     }
 
+    fn with_self_rib<F>(&mut self, self_def: Def, f: F)
+        where F: FnOnce(&mut Resolver)
+    {
+        let mut self_type_rib = Rib::new(NormalRibKind);
+
+        // plain insert (no renaming, types are not currently hygienic....)
+        let name = special_names::type_self;
+        self_type_rib.bindings.insert(name, DlDef(self_def));
+        self.type_ribs.push(self_type_rib);
+        f(self);
+        self.type_ribs.pop();
+    }
+
     fn resolve_implementation(&mut self,
                               generics: &Generics,
                               opt_trait_reference: &Option<TraitRef>,
                               self_type: &Ty,
+                              item_id: NodeId,
                               impl_items: &[P<ImplItem>]) {
         // If applicable, create a rib for the type parameters.
         self.with_type_parameter_rib(HasTypeParameters(generics,
@@ -2077,40 +2086,42 @@ fn resolve_implementation(&mut self,
             this.visit_generics(generics);
 
             // Resolve the trait reference, if necessary.
-            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this| {
+            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
                 // Resolve the self type.
                 this.visit_ty(self_type);
 
-                this.with_current_self_type(self_type, |this| {
-                    for impl_item in impl_items {
-                        match impl_item.node {
-                            MethodImplItem(ref sig, _) => {
-                                // If this is a trait impl, ensure the method
-                                // exists in trait
-                                this.check_trait_item(impl_item.ident.name,
-                                                      impl_item.span);
-
-                                // We also need a new scope for the method-
-                                // specific type parameters.
-                                let type_parameters =
-                                    HasTypeParameters(&sig.generics,
-                                                      FnSpace,
-                                                      MethodRibKind);
-                                this.with_type_parameter_rib(type_parameters, |this| {
-                                    visit::walk_impl_item(this, impl_item);
-                                });
-                            }
-                            TypeImplItem(ref ty) => {
-                                // If this is a trait impl, ensure the method
-                                // exists in trait
-                                this.check_trait_item(impl_item.ident.name,
-                                                      impl_item.span);
+                this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
+                    this.with_current_self_type(self_type, |this| {
+                        for impl_item in impl_items {
+                            match impl_item.node {
+                                MethodImplItem(ref sig, _) => {
+                                    // If this is a trait impl, ensure the method
+                                    // exists in trait
+                                    this.check_trait_item(impl_item.ident.name,
+                                                          impl_item.span);
+
+                                    // We also need a new scope for the method-
+                                    // specific type parameters.
+                                    let type_parameters =
+                                        HasTypeParameters(&sig.generics,
+                                                          FnSpace,
+                                                          MethodRibKind);
+                                    this.with_type_parameter_rib(type_parameters, |this| {
+                                        visit::walk_impl_item(this, impl_item);
+                                    });
+                                }
+                                TypeImplItem(ref ty) => {
+                                    // If this is a trait impl, ensure the method
+                                    // exists in trait
+                                    this.check_trait_item(impl_item.ident.name,
+                                                          impl_item.span);
 
-                                this.visit_ty(ty);
+                                    this.visit_ty(ty);
+                                }
+                                ast::MacImplItem(_) => {}
                             }
-                            ast::MacImplItem(_) => {}
                         }
-                    }
+                    });
                 });
             });
         });
index ba279dea5a280870dcb4e5e23fe7379631190096..1a19d4a1e454c2e6402728b877f583cccbf6930e 100644 (file)
@@ -248,7 +248,7 @@ fn lookup_def_kind(&self, ref_id: NodeId, span: Span) -> Option<recorder::Row> {
 
             def::DefFn(..) => Some(recorder::FnRef),
 
-            def::DefSelfTy(_) |
+            def::DefSelfTy(..) |
             def::DefRegion(_) |
             def::DefLabel(_) |
             def::DefTyParam(..) |
index 1142f15ace96a2418f60297c6766d338b02ba7db..390a9cc4d26d01c96c5f6fec37f9995b67ce81fe 100644 (file)
 
 use std;
 use std::cmp::Ordering;
-use std::iter::AdditiveIterator;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::ast::{DUMMY_NODE_ID, NodeId};
index 939142cff1c32b6d7aba9d61bf675e7fc75c0cdd..355b866013b6396ea776055036126e97321388f6 100644 (file)
 use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
 use middle::traits;
 use middle::ty::{self, RegionEscape, Ty};
-use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
+use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
              ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
 use util::common::{ErrorReported, FN_OUTPUT_NAME};
 use util::ppaux::{self, Repr, UserString};
 
-use std::iter::{repeat, AdditiveIterator};
+use std::iter::repeat;
 use std::rc::Rc;
 use std::slice;
 use syntax::{abi, ast, ast_util};
@@ -517,12 +517,13 @@ fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec<String>)
         lifetimes_for_params.push((input_pat, accumulator.len()));
     }
 
-    let implied_output_region = if lifetimes_for_params.iter().map(|&(_, n)| n).sum() == 1 {
-        assert!(possible_implied_output_region.is_some());
-        possible_implied_output_region
-    } else {
-        None
-    };
+    let implied_output_region =
+        if lifetimes_for_params.iter().map(|&(_, n)| n).sum::<usize>() == 1 {
+            assert!(possible_implied_output_region.is_some());
+            possible_implied_output_region
+        } else {
+            None
+        };
     (implied_output_region, lifetimes_for_params)
 }
 
@@ -871,24 +872,11 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>(
         }
     }
 
-    if candidates.len() > 1 {
-        span_err!(tcx.sess, binding.span, E0217,
-            "ambiguous associated type: `{}` defined in multiple supertraits `{}`",
-                    token::get_name(binding.item_name),
-                    candidates.user_string(tcx));
-        return Err(ErrorReported);
-    }
-
-    let candidate = match candidates.pop() {
-        Some(c) => c,
-        None => {
-            span_err!(tcx.sess, binding.span, E0218,
-                "no associated type `{}` defined in `{}`",
-                        token::get_name(binding.item_name),
-                        trait_ref.user_string(tcx));
-            return Err(ErrorReported);
-        }
-    };
+    let candidate = try!(one_bound_for_assoc_type(tcx,
+                                                  candidates,
+                                                  &trait_ref.user_string(tcx),
+                                                  &token::get_name(binding.item_name),
+                                                  binding.span));
 
     Ok(ty::Binder(ty::ProjectionPredicate {             // <-------------------------+
         projection_ty: ty::ProjectionTy {               //                           |
@@ -1041,6 +1029,81 @@ fn report_ambiguous_associated_type(tcx: &ty::ctxt,
               type_str, trait_str, name);
 }
 
+// Search for a bound on a type parameter which includes the associated item
+// given by assoc_name. ty_param_node_id is the node id for the type parameter
+// (which might be `Self`, but only if it is the `Self` of a trait, not an
+// impl). This function will fail if there are no suitable bounds or there is
+// any ambiguity.
+fn find_bound_for_assoc_item<'tcx>(this: &AstConv<'tcx>,
+                                   ty_param_node_id: ast::NodeId,
+                                   assoc_name: ast::Name,
+                                   span: Span)
+                                   -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
+{
+    let tcx = this.tcx();
+
+    let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
+        Ok(v) => v,
+        Err(ErrorReported) => {
+            return Err(ErrorReported);
+        }
+    };
+
+    // Ensure the super predicates and stop if we encountered an error.
+    if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
+        return Err(ErrorReported);
+    }
+
+    // Check that there is exactly one way to find an associated type with the
+    // correct name.
+    let suitable_bounds: Vec<_> =
+        traits::transitive_bounds(tcx, &bounds)
+        .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
+        .collect();
+
+    let ty_param_name = tcx.type_parameter_def(ty_param_node_id).name;
+    one_bound_for_assoc_type(tcx,
+                             suitable_bounds,
+                             &token::get_name(ty_param_name),
+                             &token::get_name(assoc_name),
+                             span)
+}
+
+
+// Checks that bounds contains exactly one element and reports appropriate
+// errors otherwise.
+fn one_bound_for_assoc_type<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                  bounds: Vec<ty::PolyTraitRef<'tcx>>,
+                                  ty_param_name: &str,
+                                  assoc_name: &str,
+                                  span: Span)
+    -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
+{
+    if bounds.len() == 0 {
+        span_err!(tcx.sess, span, E0220,
+                  "associated type `{}` not found for `{}`",
+                  assoc_name,
+                  ty_param_name);
+        return Err(ErrorReported);
+    }
+
+    if bounds.len() > 1 {
+        span_err!(tcx.sess, span, E0221,
+                  "ambiguous associated type `{}` in bounds of `{}`",
+                  assoc_name,
+                  ty_param_name);
+
+        for bound in &bounds {
+            span_note!(tcx.sess, span,
+                       "associated type `{}` could derive from `{}`",
+                       ty_param_name,
+                       bound.user_string(tcx));
+        }
+    }
+
+    Ok(bounds[0].clone())
+}
+
 // Create a type from a a path to an associated type.
 // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
 // and item_segment is the path segment for D. We return a type and a def for
@@ -1061,10 +1124,55 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
 
     check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
 
-    // Check that the path prefix given by ty/ty_path_def is a type parameter/Self.
-    match (&ty.sty, ty_path_def) {
+    // Find the type of the associated item, and the trait where the associated
+    // item is declared.
+    let bound = match (&ty.sty, ty_path_def) {
+        (_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
+            // `Self` in an impl of a trait - we have a concrete self type and a
+            // trait reference.
+            match tcx.map.expect_item(impl_id).node {
+                ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) => {
+                    if this.ensure_super_predicates(span, trait_did).is_err() {
+                        return (tcx.types.err, ty_path_def);
+                    }
+
+                    let trait_segment = &trait_ref.path.segments.last().unwrap();
+                    let trait_ref = ast_path_to_mono_trait_ref(this,
+                                                               &ExplicitRscope,
+                                                               span,
+                                                               PathParamMode::Explicit,
+                                                               trait_did,
+                                                               Some(ty),
+                                                               trait_segment);
+
+                    let candidates: Vec<ty::PolyTraitRef> =
+                        traits::supertraits(tcx, ty::Binder(trait_ref.clone()))
+                        .filter(|r| this.trait_defines_associated_type_named(r.def_id(),
+                                                                             assoc_name))
+                        .collect();
+
+                    match one_bound_for_assoc_type(tcx,
+                                                   candidates,
+                                                   "Self",
+                                                   &token::get_name(assoc_name),
+                                                   span) {
+                        Ok(bound) => bound,
+                        Err(ErrorReported) => return (tcx.types.err, ty_path_def),
+                    }
+                }
+                _ => unreachable!()
+            }
+        }
         (&ty::ty_param(_), def::DefTyParam(..)) |
-        (&ty::ty_param(_), def::DefSelfTy(_)) => {}
+        (&ty::ty_param(_), def::DefSelfTy(Some(_), None)) => {
+            // A type parameter or Self, we need to find the associated item from
+            // a bound.
+            let ty_param_node_id = ty_path_def.local_node_id();
+            match find_bound_for_assoc_item(this, ty_param_node_id, assoc_name, span) {
+                Ok(bound) => bound,
+                Err(ErrorReported) => return (tcx.types.err, ty_path_def),
+            }
+        }
         _ => {
             report_ambiguous_associated_type(tcx,
                                              span,
@@ -1073,61 +1181,15 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                              &token::get_name(assoc_name));
             return (tcx.types.err, ty_path_def);
         }
-    }
-
-    let ty_param_node_id = ty_path_def.local_node_id();
-    let ty_param_name = tcx.ty_param_defs.borrow().get(&ty_param_node_id).unwrap().name;
-
-    let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
-        Ok(v) => v,
-        Err(ErrorReported) => {
-            return (tcx.types.err, ty_path_def);
-        }
     };
 
-    // Ensure the super predicates and stop if we encountered an error.
-    if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
-        return (this.tcx().types.err, ty_path_def);
-    }
-
-    // Check that there is exactly one way to find an associated type with the
-    // correct name.
-    let mut suitable_bounds: Vec<_> =
-        traits::transitive_bounds(tcx, &bounds)
-        .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
-        .collect();
-
-    if suitable_bounds.len() == 0 {
-        span_err!(tcx.sess, span, E0220,
-                          "associated type `{}` not found for type parameter `{}`",
-                                  token::get_name(assoc_name),
-                                  token::get_name(ty_param_name));
-        return (this.tcx().types.err, ty_path_def);
-    }
-
-    if suitable_bounds.len() > 1 {
-        span_err!(tcx.sess, span, E0221,
-                          "ambiguous associated type `{}` in bounds of `{}`",
-                                  token::get_name(assoc_name),
-                                  token::get_name(ty_param_name));
-
-        for suitable_bound in &suitable_bounds {
-            span_note!(this.tcx().sess, span,
-                       "associated type `{}` could derive from `{}`",
-                       token::get_name(ty_param_name),
-                       suitable_bound.user_string(this.tcx()));
-        }
-    }
-
-    let suitable_bound = suitable_bounds.pop().unwrap().clone();
-    let trait_did = suitable_bound.0.def_id;
-
-    let ty = this.projected_ty_from_poly_trait_ref(span, suitable_bound, assoc_name);
+    let trait_did = bound.0.def_id;
+    let ty = this.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
 
     let item_did = if trait_did.krate == ast::LOCAL_CRATE {
         // `ty::trait_items` used below requires information generated
         // by type collection, which may be in progress at this point.
-        match this.tcx().map.expect_item(trait_did.node).node {
+        match tcx.map.expect_item(trait_did.node).node {
             ast::ItemTrait(_, _, _, ref trait_items) => {
                 let item = trait_items.iter()
                                       .find(|i| i.ident.name == assoc_name)
@@ -1137,7 +1199,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             _ => unreachable!()
         }
     } else {
-        let trait_items = ty::trait_items(this.tcx(), trait_did);
+        let trait_items = ty::trait_items(tcx, trait_did);
         let item = trait_items.iter().find(|i| i.name() == assoc_name);
         item.expect("missing associated type").def_id()
     };
@@ -1173,14 +1235,13 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
 
     debug!("qpath_to_ty: self_type={}", self_ty.repr(tcx));
 
-    let trait_ref =
-        ast_path_to_mono_trait_ref(this,
-                                   rscope,
-                                   span,
-                                   param_mode,
-                                   trait_def_id,
-                                   Some(self_ty),
-                                   trait_segment);
+    let trait_ref = ast_path_to_mono_trait_ref(this,
+                                               rscope,
+                                               span,
+                                               param_mode,
+                                               trait_def_id,
+                                               Some(self_ty),
+                                               trait_segment);
 
     debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(tcx));
 
@@ -1220,20 +1281,20 @@ pub fn ast_ty_arg_to_ty<'tcx>(this: &AstConv<'tcx>,
     }
 }
 
-// Note that both base_segments and assoc_segments may be empty, although not at
-// the same time.
-pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
-                                        rscope: &RegionScope,
-                                        span: Span,
-                                        param_mode: PathParamMode,
-                                        def: &def::Def,
-                                        opt_self_ty: Option<Ty<'tcx>>,
-                                        base_segments: &[ast::PathSegment],
-                                        assoc_segments: &[ast::PathSegment])
-                                        -> Ty<'tcx> {
+// Check the base def in a PathResolution and convert it to a Ty. If there are
+// associated types in the PathResolution, these will need to be seperately
+// resolved.
+fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
+                        rscope: &RegionScope,
+                        span: Span,
+                        param_mode: PathParamMode,
+                        def: &def::Def,
+                        opt_self_ty: Option<Ty<'tcx>>,
+                        base_segments: &[ast::PathSegment])
+                        -> Ty<'tcx> {
     let tcx = this.tcx();
 
-    let base_ty = match *def {
+    match *def {
         def::DefTrait(trait_def_id) => {
             // N.B. this case overlaps somewhat with
             // TyObjectSum, see that fn for details
@@ -1257,18 +1318,28 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
         }
         def::DefTy(did, _) | def::DefStruct(did) => {
             check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
-            ast_path_to_ty(this, rscope, span,
-                           param_mode, did,
+            ast_path_to_ty(this,
+                           rscope,
+                           span,
+                           param_mode,
+                           did,
                            base_segments.last().unwrap())
         }
         def::DefTyParam(space, index, _, name) => {
             check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
             ty::mk_param(tcx, space, index, name)
         }
-        def::DefSelfTy(_) => {
-            // N.b.: resolve guarantees that the this type only appears in a
-            // trait, which we rely upon in various places when creating
-            // substs.
+        def::DefSelfTy(_, Some((_, self_ty_id))) => {
+            // Self in impl (we know the concrete type).
+            check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
+            if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) {
+                ty
+            } else {
+                tcx.sess.span_bug(span, "self type has not been fully resolved")
+            }
+        }
+        def::DefSelfTy(Some(_), None) => {
+            // Self in trait.
             check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
             ty::mk_self_type(tcx)
         }
@@ -1288,6 +1359,9 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             // FIXME(#22519) This part of the resolution logic should be
             // avoided entirely for that form, once we stop needed a Def
             // for `associated_path_def_to_ty`.
+            // Fixing this will also let use resolve <Self>::Foo the same way we
+            // resolve Self::Foo, at the moment we can't resolve the former because
+            // we don't have the trait information around, which is just sad.
 
             if !base_segments.is_empty() {
                 span_err!(tcx.sess,
@@ -1308,11 +1382,29 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                       "found value name used as a type: {:?}", *def);
             return this.tcx().types.err;
         }
-    };
+    }
+}
 
-    // If any associated type segments remain, attempt to resolve them.
-    let mut ty = base_ty;
+// Note that both base_segments and assoc_segments may be empty, although not at
+// the same time.
+pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
+                                        rscope: &RegionScope,
+                                        span: Span,
+                                        param_mode: PathParamMode,
+                                        def: &def::Def,
+                                        opt_self_ty: Option<Ty<'tcx>>,
+                                        base_segments: &[ast::PathSegment],
+                                        assoc_segments: &[ast::PathSegment])
+                                        -> Ty<'tcx> {
+    let mut ty = base_def_to_ty(this,
+                                rscope,
+                                span,
+                                param_mode,
+                                def,
+                                opt_self_ty,
+                                base_segments);
     let mut def = *def;
+    // If any associated type segments remain, attempt to resolve them.
     for segment in assoc_segments {
         if ty.sty == ty::ty_err {
             break;
@@ -1996,7 +2088,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
                                 check_type_argument_count(tcx, b.trait_ref.path.span,
                                                           parameters.types().len(), 0, 0);
                             }
-                            if parameters.lifetimes().len() > 0{
+                            if parameters.lifetimes().len() > 0 {
                                 report_lifetime_number_error(tcx, b.trait_ref.path.span,
                                                              parameters.lifetimes().len(), 0);
                             }
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
new file mode 100644 (file)
index 0000000..3773ff7
--- /dev/null
@@ -0,0 +1,190 @@
+// Copyright 2015 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.
+
+//! Code for type-checking cast expressions.
+
+use super::coercion;
+use super::demand;
+use super::FnCtxt;
+use super::structurally_resolved_type;
+
+use lint;
+use middle::infer;
+use middle::ty;
+use middle::ty::Ty;
+use syntax::ast;
+use syntax::codemap::Span;
+
+/// Reifies a cast check to be checked once we have full type information for
+/// a function context.
+pub struct CastCheck<'tcx> {
+    expr: ast::Expr,
+    expr_ty: Ty<'tcx>,
+    cast_ty: Ty<'tcx>,
+    span: Span,
+}
+
+impl<'tcx> CastCheck<'tcx> {
+    pub fn new(expr: ast::Expr, expr_ty: Ty<'tcx>, cast_ty: Ty<'tcx>, span: Span)
+               -> CastCheck<'tcx> {
+        CastCheck {
+            expr: expr,
+            expr_ty: expr_ty,
+            cast_ty: cast_ty,
+            span: span,
+        }
+    }
+}
+
+pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
+    fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                          span: Span,
+                                          t_1: Ty<'tcx>,
+                                          t_e: Ty<'tcx>) {
+        fcx.type_error_message(span, |actual| {
+            format!("illegal cast; cast through an \
+                    integer first: `{}` as `{}`",
+                    actual,
+                    fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
+    }
+
+    let span = cast.span;
+    let e = &cast.expr;
+    let t_e = structurally_resolved_type(fcx, span, cast.expr_ty);
+    let t_1 = structurally_resolved_type(fcx, span, cast.cast_ty);
+
+    // Check for trivial casts.
+    if !ty::type_has_ty_infer(t_1) {
+        if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) {
+            if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) {
+                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
+                                        e.id,
+                                        span,
+                                        format!("trivial numeric cast: `{}` as `{}`. Cast can be \
+                                                 replaced by coercion, this might require type \
+                                                 ascription or a temporary variable",
+                                                fcx.infcx().ty_to_string(t_e),
+                                                fcx.infcx().ty_to_string(t_1)));
+            } else {
+                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS,
+                                        e.id,
+                                        span,
+                                        format!("trivial cast: `{}` as `{}`. Cast can be \
+                                                 replaced by coercion, this might require type \
+                                                 ascription or a temporary variable",
+                                                fcx.infcx().ty_to_string(t_e),
+                                                fcx.infcx().ty_to_string(t_1)));
+            }
+            return;
+        }
+    }
+
+    let t_e_is_bare_fn_item = ty::type_is_bare_fn_item(t_e);
+    let t_e_is_scalar = ty::type_is_scalar(t_e);
+    let t_e_is_integral = ty::type_is_integral(t_e);
+    let t_e_is_float = ty::type_is_floating_point(t_e);
+    let t_e_is_c_enum = ty::type_is_c_like_enum(fcx.tcx(), t_e);
+
+    let t_1_is_scalar = ty::type_is_scalar(t_1);
+    let t_1_is_integral = ty::type_is_integral(t_1);
+    let t_1_is_char = ty::type_is_char(t_1);
+    let t_1_is_bare_fn = ty::type_is_bare_fn(t_1);
+    let t_1_is_float = ty::type_is_floating_point(t_1);
+    let t_1_is_c_enum = ty::type_is_c_like_enum(fcx.tcx(), t_1);
+
+    // casts to scalars other than `char` and `bare fn` are trivial
+    let t_1_is_trivial = t_1_is_scalar && !t_1_is_char && !t_1_is_bare_fn;
+
+    if t_e_is_bare_fn_item && t_1_is_bare_fn {
+        demand::coerce(fcx, e.span, t_1, &e);
+    } else if t_1_is_char {
+        let t_e = fcx.infcx().shallow_resolve(t_e);
+        if t_e.sty != ty::ty_uint(ast::TyU8) {
+            fcx.type_error_message(span, |actual| {
+                format!("only `u8` can be cast as `char`, not `{}`", actual)
+            }, t_e, None);
+        }
+    } else if t_1.sty == ty::ty_bool {
+        span_err!(fcx.tcx().sess, span, E0054,
+                  "cannot cast as `bool`, compare with zero instead");
+    } else if t_e_is_float && (t_1_is_scalar || t_1_is_c_enum) &&
+        !(t_1_is_integral || t_1_is_float) {
+        // Casts from float must go through an integer
+        cast_through_integer_err(fcx, span, t_1, t_e)
+    } else if t_1_is_float && (t_e_is_scalar || t_e_is_c_enum) &&
+        !(t_e_is_integral || t_e_is_float || t_e.sty == ty::ty_bool) {
+        // Casts to float must go through an integer or boolean
+        cast_through_integer_err(fcx, span, t_1, t_e)
+    } else if t_e_is_c_enum && t_1_is_trivial {
+        if ty::type_is_unsafe_ptr(t_1) {
+            // ... and likewise with C enum -> *T
+            cast_through_integer_err(fcx, span, t_1, t_e)
+        }
+        // casts from C-like enums are allowed
+    } else if ty::type_is_region_ptr(t_e) && ty::type_is_unsafe_ptr(t_1) {
+        fn types_compatible<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
+                                      t1: Ty<'tcx>, t2: Ty<'tcx>) -> bool {
+            match t1.sty {
+                ty::ty_vec(_, Some(_)) => {}
+                _ => return false
+            }
+            if ty::type_needs_infer(t2) {
+                // This prevents this special case from going off when casting
+                // to a type that isn't fully specified; e.g. `as *_`. (Issue
+                // #14893.)
+                return false
+            }
+
+            let el = ty::sequence_element_type(fcx.tcx(), t1);
+            infer::mk_eqty(fcx.infcx(),
+                           false,
+                           infer::Misc(sp),
+                           el,
+                           t2).is_ok()
+        }
+
+        // Due to the limitations of LLVM global constants,
+        // region pointers end up pointing at copies of
+        // vector elements instead of the original values.
+        // To allow unsafe pointers to work correctly, we
+        // need to special-case obtaining an unsafe pointer
+        // from a region pointer to a vector.
+
+        /* this cast is only allowed from &[T, ..n] to *T or
+        &T to *T. */
+        match (&t_e.sty, &t_1.sty) {
+            (&ty::ty_rptr(_, ty::mt { ty: mt1, mutbl: ast::MutImmutable }),
+             &ty::ty_ptr(ty::mt { ty: mt2, mutbl: ast::MutImmutable }))
+            if types_compatible(fcx, e.span, mt1, mt2) => {
+                /* this case is allowed */
+            }
+            _ => {
+                demand::coerce(fcx, e.span, t_1, &e);
+            }
+        }
+    } else if fcx.type_is_fat_ptr(t_e, span) && !fcx.type_is_fat_ptr(t_1, span) {
+        fcx.type_error_message(span, |actual| {
+            format!("illegal cast; cast from fat pointer: `{}` as `{}`",
+                    actual, fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
+    } else if !(t_e_is_scalar && t_1_is_trivial) {
+        /*
+        If more type combinations should be supported than are
+        supported here, then file an enhancement issue and
+        record the issue number in this comment.
+        */
+        fcx.type_error_message(span, |actual| {
+            format!("non-scalar cast: `{}` as `{}`",
+                    actual,
+                    fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
+    }
+}
index 156fbfede9c98aebf51b120086f56b005bbdd28c..f7bbc693ce59b9e3e285fab6c821e5286281946b 100644 (file)
 pub mod method;
 mod upvar;
 pub mod wf;
+mod cast;
 mod closure;
 mod callee;
 mod compare_method;
@@ -185,7 +186,7 @@ pub struct Inherited<'a, 'tcx: 'a> {
     // back and process them.
     deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
 
-    deferred_cast_checks: RefCell<Vec<CastCheck<'tcx>>>,
+    deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
 }
 
 trait DeferredCallResolution<'tcx> {
@@ -194,15 +195,6 @@ trait DeferredCallResolution<'tcx> {
 
 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
 
-/// Reifies a cast check to be checked once we have full type information for
-/// a function context.
-struct CastCheck<'tcx> {
-    expr: ast::Expr,
-    expr_ty: Ty<'tcx>,
-    cast_ty: Ty<'tcx>,
-    span: Span,
-}
-
 /// When type-checking an expression, we propagate downward
 /// whatever type hint we are able in the form of an `Expectation`.
 #[derive(Copy, Clone)]
@@ -1071,141 +1063,6 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 
-fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
-    fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                          span: Span,
-                                          t_1: Ty<'tcx>,
-                                          t_e: Ty<'tcx>) {
-        fcx.type_error_message(span, |actual| {
-            format!("illegal cast; cast through an \
-                    integer first: `{}` as `{}`",
-                    actual,
-                    fcx.infcx().ty_to_string(t_1))
-        }, t_e, None);
-    }
-
-    let span = cast.span;
-    let e = &cast.expr;
-    let t_e = structurally_resolved_type(fcx, span, cast.expr_ty);
-    let t_1 = structurally_resolved_type(fcx, span, cast.cast_ty);
-
-    // Check for trivial casts.
-    if !ty::type_has_ty_infer(t_1) {
-        if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) {
-            if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) {
-                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
-                                        e.id,
-                                        span,
-                                        format!("trivial numeric cast: `{}` as `{}`. Cast can be \
-                                                 replaced by coercion, this might require type \
-                                                 ascription or a temporary variable",
-                                                fcx.infcx().ty_to_string(t_e),
-                                                fcx.infcx().ty_to_string(t_1)));
-            } else {
-                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS,
-                                        e.id,
-                                        span,
-                                        format!("trivial cast: `{}` as `{}`. Cast can be \
-                                                 replaced by coercion, this might require type \
-                                                 ascription or a temporary variable",
-                                                fcx.infcx().ty_to_string(t_e),
-                                                fcx.infcx().ty_to_string(t_1)));
-            }
-            return;
-        }
-    }
-
-    let t_e_is_bare_fn_item = ty::type_is_bare_fn_item(t_e);
-    let t_e_is_scalar = ty::type_is_scalar(t_e);
-    let t_e_is_integral = ty::type_is_integral(t_e);
-    let t_e_is_float = ty::type_is_floating_point(t_e);
-    let t_e_is_c_enum = ty::type_is_c_like_enum(fcx.tcx(), t_e);
-
-    let t_1_is_scalar = ty::type_is_scalar(t_1);
-    let t_1_is_char = ty::type_is_char(t_1);
-    let t_1_is_bare_fn = ty::type_is_bare_fn(t_1);
-    let t_1_is_float = ty::type_is_floating_point(t_1);
-
-    // casts to scalars other than `char` and `bare fn` are trivial
-    let t_1_is_trivial = t_1_is_scalar && !t_1_is_char && !t_1_is_bare_fn;
-
-    if t_e_is_bare_fn_item && t_1_is_bare_fn {
-        demand::coerce(fcx, e.span, t_1, &e);
-    } else if t_1_is_char {
-        let t_e = fcx.infcx().shallow_resolve(t_e);
-        if t_e.sty != ty::ty_uint(ast::TyU8) {
-            fcx.type_error_message(span, |actual| {
-                format!("only `u8` can be cast as `char`, not `{}`", actual)
-            }, t_e, None);
-        }
-    } else if t_1.sty == ty::ty_bool {
-        span_err!(fcx.tcx().sess, span, E0054,
-                  "cannot cast as `bool`, compare with zero instead");
-    } else if t_1_is_float && (t_e_is_scalar || t_e_is_c_enum) && !(
-        t_e_is_integral || t_e_is_float || t_e.sty == ty::ty_bool) {
-        // Casts to float must go through an integer or boolean
-        cast_through_integer_err(fcx, span, t_1, t_e)
-    } else if t_e_is_c_enum && t_1_is_trivial {
-        if ty::type_is_unsafe_ptr(t_1) {
-            // ... and likewise with C enum -> *T
-            cast_through_integer_err(fcx, span, t_1, t_e)
-        }
-        // casts from C-like enums are allowed
-    } else if ty::type_is_region_ptr(t_e) && ty::type_is_unsafe_ptr(t_1) {
-        fn types_compatible<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
-                                      t1: Ty<'tcx>, t2: Ty<'tcx>) -> bool {
-            match t1.sty {
-                ty::ty_vec(_, Some(_)) => {}
-                _ => return false
-            }
-            if ty::type_needs_infer(t2) {
-                // This prevents this special case from going off when casting
-                // to a type that isn't fully specified; e.g. `as *_`. (Issue
-                // #14893.)
-                return false
-            }
-
-            let el = ty::sequence_element_type(fcx.tcx(), t1);
-            infer::mk_eqty(fcx.infcx(),
-                           false,
-                           infer::Misc(sp),
-                           el,
-                           t2).is_ok()
-        }
-
-        // Due to the limitations of LLVM global constants,
-        // region pointers end up pointing at copies of
-        // vector elements instead of the original values.
-        // To allow unsafe pointers to work correctly, we
-        // need to special-case obtaining an unsafe pointer
-        // from a region pointer to a vector.
-
-        /* this cast is only allowed from &[T, ..n] to *T or
-        &T to *T. */
-        match (&t_e.sty, &t_1.sty) {
-            (&ty::ty_rptr(_, ty::mt { ty: mt1, mutbl: ast::MutImmutable }),
-             &ty::ty_ptr(ty::mt { ty: mt2, mutbl: ast::MutImmutable }))
-            if types_compatible(fcx, e.span, mt1, mt2) => {
-                /* this case is allowed */
-            }
-            _ => {
-                demand::coerce(fcx, e.span, t_1, &e);
-            }
-        }
-    } else if !(t_e_is_scalar && t_1_is_trivial) {
-        /*
-        If more type combinations should be supported than are
-        supported here, then file an enhancement issue and
-        record the issue number in this comment.
-        */
-        fcx.type_error_message(span, |actual| {
-            format!("non-scalar cast: `{}` as `{}`",
-                    actual,
-                    fcx.infcx().ty_to_string(t_1))
-        }, t_e, None);
-    }
-}
-
 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
 
@@ -1702,6 +1559,13 @@ pub fn type_is_known_to_be_sized(&self,
                                                  span)
     }
 
+    pub fn type_is_fat_ptr(&self, ty: Ty<'tcx>, span: Span) -> bool {
+        if let Some(mt) = ty::deref(ty, true) {
+            return !self.type_is_known_to_be_sized(mt.ty, span);
+        }
+        false
+    }
+
     pub fn register_builtin_bound(&self,
                                   ty: Ty<'tcx>,
                                   builtin_bound: ty::BuiltinBound,
@@ -1925,7 +1789,7 @@ pub fn lookup_tup_field_ty(&self,
     fn check_casts(&self) {
         let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
         for check in deferred_cast_checks.iter() {
-            check_cast(self, check);
+            cast::check_cast(self, check);
         }
 
         deferred_cast_checks.clear();
@@ -3341,11 +3205,17 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
           let def = path_res.base_def;
           if path_res.depth == 0 {
-              let (scheme, predicates) =
-                  type_scheme_and_predicates_for_def(fcx, expr.span, def);
-              instantiate_path(fcx, &path.segments,
-                               scheme, &predicates,
-                               opt_self_ty, def, expr.span, id);
+              let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
+                                                                            expr.span,
+                                                                            def);
+              instantiate_path(fcx,
+                               &path.segments,
+                               scheme,
+                               &predicates,
+                               opt_self_ty,
+                               def,
+                               expr.span,
+                               id);
           } else {
               let ty_segments = path.segments.init();
               let base_ty_end = path.segments.len() - path_res.depth;
@@ -3531,12 +3401,8 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
-            deferred_cast_checks.push(CastCheck {
-                expr: (**e).clone(),
-                expr_ty: t_e,
-                cast_ty: t_1,
-                span: expr.span,
-            });
+            let cast_check = cast::CastCheck::new((**e).clone(), t_e, t_1, expr.span);
+            deferred_cast_checks.push(cast_check);
         }
       }
       ast::ExprVec(ref args) => {
index 8f1b8bf109215d6caa2825ce2dc7eac907ef89ed..95b943b254785ff0725dcc8801664ed19d06a703 100644 (file)
@@ -547,14 +547,15 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
     if let ast::TyPath(None, _) = ast_ty.node {
         let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
         match path_res.base_def {
-            def::DefSelfTy(node_id) =>
-                path_res.depth == 0 && node_id == param_id,
-
-            def::DefTyParam(_, _, def_id, _) =>
-                path_res.depth == 0 && def_id == local_def(param_id),
-
-            _ =>
-                false,
+            def::DefSelfTy(Some(def_id), None) => {
+                path_res.depth == 0 && def_id.node == param_id
+            }
+            def::DefTyParam(_, _, def_id, _) => {
+                path_res.depth == 0 && def_id == local_def(param_id)
+            }
+            _ => {
+                false
+            }
         }
     } else {
         false
@@ -1814,7 +1815,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                     ty::ty_param(p) => if p.idx > cur_idx {
                         span_err!(tcx.sess, path.span, E0128,
                                   "type parameters with a default cannot use \
-                                  forward declared identifiers");
+                                   forward declared identifiers");
                         },
                         _ => {}
                     }
index d361f17cbe41bc87bfafba0ee601edac29b9c2cf..2850d92e34d401152a378af9e60cb409bfacf497 100644 (file)
@@ -18,6 +18,7 @@
 use io::{self, BufReader, LineWriter};
 use sync::{Arc, Mutex, MutexGuard};
 use sys::stdio;
+use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
 
 /// Stdout used by print! and println! macros
 thread_local! {
@@ -210,7 +211,7 @@ pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
     //        stdout (tty or not). Note that if this is not line buffered it
     //        should also flush-on-panic or some form of flush-on-abort.
-    inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
+    inner: Arc<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>>,
 }
 
 /// A locked reference to the a `Stdout` handle.
@@ -219,7 +220,7 @@ pub struct Stdout {
 /// method on `Stdout`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
-    inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
+    inner: ReentrantMutexGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
 }
 
 /// Constructs a new reference to the standard output of the current process.
@@ -231,13 +232,13 @@ pub struct StdoutLock<'a> {
 /// The returned handle implements the `Write` trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
-    static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> = lazy_init!(stdout_init);
     return Stdout {
         inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
     };
 
-    fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
-        Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
+    fn stdout_init() -> Arc<ReentrantMutex<RefCell<LineWriter<StdoutRaw>>>> {
+        Arc::new(ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw()))))
     }
 }
 
@@ -264,15 +265,18 @@ fn flush(&mut self) -> io::Result<()> {
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
         self.lock().write_all(buf)
     }
-    // Don't override write_fmt as it's possible to run arbitrary code during a
-    // write_fmt, allowing the possibility of a recursive lock (aka deadlock)
+    fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> {
+        self.lock().write_fmt(args)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StdoutLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+        self.inner.borrow_mut().write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.inner.borrow_mut().flush()
     }
-    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
 
 /// A handle to the standard error stream of a process.
@@ -280,7 +284,7 @@ fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 /// For more information, see `stderr`
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stderr {
-    inner: Arc<Mutex<StderrRaw>>,
+    inner: Arc<ReentrantMutex<RefCell<StderrRaw>>>,
 }
 
 /// A locked reference to the a `Stderr` handle.
@@ -289,7 +293,7 @@ pub struct Stderr {
 /// method on `Stderr`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
-    inner: MutexGuard<'a, StderrRaw>,
+    inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
 }
 
 /// Constructs a new reference to the standard error stream of a process.
@@ -300,13 +304,13 @@ pub struct StderrLock<'a> {
 /// The returned handle implements the `Write` trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
-    static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
+    static INSTANCE: Lazy<ReentrantMutex<RefCell<StderrRaw>>> = lazy_init!(stderr_init);
     return Stderr {
         inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
     };
 
-    fn stderr_init() -> Arc<Mutex<StderrRaw>> {
-        Arc::new(Mutex::new(stderr_raw()))
+    fn stderr_init() -> Arc<ReentrantMutex<RefCell<StderrRaw>>> {
+        Arc::new(ReentrantMutex::new(RefCell::new(stderr_raw())))
     }
 }
 
@@ -333,14 +337,18 @@ fn flush(&mut self) -> io::Result<()> {
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
         self.lock().write_all(buf)
     }
-    // Don't override write_fmt for the same reasons as Stdout
+    fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> {
+        self.lock().write_fmt(args)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StderrLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+        self.inner.borrow_mut().write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.inner.borrow_mut().flush()
     }
-    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
 
 /// Resets the task-local stderr handle to the specified writer
index c517fab257f9574678d813ff07b0e20c63da59f9..af63be2aa9e3f891d0ec2716f7a68cd8e4ddc6b6 100644 (file)
@@ -15,8 +15,7 @@
 use fmt;
 use hash;
 use old_io::Writer;
-use iter::{AdditiveIterator, Extend};
-use iter::{Iterator, Map};
+use iter::{Extend, Iterator, Map};
 use marker::Sized;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
@@ -351,7 +350,7 @@ fn normalize(v: &[u8]) -> Vec<u8> {
                         Some(vec![SEP_BYTE])
                     } else {
                         let n = if is_abs { comps.len() } else { comps.len() - 1} +
-                                comps.iter().map(|v| v.len()).sum();
+                                comps.iter().map(|v| v.len()).sum::<usize>();
                         let mut v = Vec::with_capacity(n);
                         let mut it = comps.into_iter();
                         if !is_abs {
index 0b88f368b3952aa9985839ec42636dc40e88f70c..65aad38a2b43d5e848edba99ae4d9174fae3d2fa 100644 (file)
@@ -20,8 +20,7 @@
 use fmt;
 use hash;
 use old_io::Writer;
-use iter::{AdditiveIterator, Extend};
-use iter::{Iterator, Map, repeat};
+use iter::{Extend, Iterator, Map, repeat};
 use mem;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
@@ -785,7 +784,7 @@ fn normalize__(s: &str, prefix: Option<PathPrefix>) -> Option<String> {
                         let prefix_ = &s[..prefix_len(prefix)];
                         let n = prefix_.len() +
                                 if is_abs { comps.len() } else { comps.len() - 1} +
-                                comps.iter().map(|v| v.len()).sum();
+                                comps.iter().map(|v| v.len()).sum::<usize>();
                         let mut s = String::with_capacity(n);
                         match prefix {
                             Some(DiskPrefix) => {
index a7d8b287a64c031567a8605f50c69fb8ef6dc9a8..654b33f1a579d1f5372093adcd8fb117af0d3881 100644 (file)
 use prelude::v1::*;
 
 use sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
-use sync::poison::{self, LockResult};
-use sys::time::SteadyTime;
+use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
 use sys_common::mutex as sys_mutex;
+use sys_common::poison::{self, LockResult};
+use sys::time::SteadyTime;
 use time::Duration;
-use sync::{mutex, MutexGuard, PoisonError};
 
 /// A Condition Variable
 ///
index a5259a00390f55369a7e737781fe0f6c00f52e34..91e9714fbef48b896793f53deff438346ca804b7 100644 (file)
 pub use alloc::arc::{Arc, Weak};
 pub use core::atomic;
 
-pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
-pub use self::mutex::MUTEX_INIT;
-pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
-pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
+pub use self::barrier::{Barrier, BarrierWaitResult};
 pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT};
+pub use self::mutex::MUTEX_INIT;
+pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
 pub use self::once::{Once, ONCE_INIT};
+pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
+pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
+pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
 pub use self::semaphore::{Semaphore, SemaphoreGuard};
-pub use self::barrier::{Barrier, BarrierWaitResult};
-pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 
 pub use self::future::Future;
 
@@ -39,6 +39,5 @@
 mod future;
 mod mutex;
 mod once;
-mod poison;
 mod rwlock;
 mod semaphore;
index c80182ec07d3223df0b61929e50acf163a9b06a6..e5444843516008bcfd66df49d7d19dab513f86cb 100644 (file)
 //! });
 //! rx.recv().unwrap();
 //! ```
-//!
-//! Reading from a channel with a timeout requires to use a Timer together
-//! with the channel. You can use the `select!` macro to select either and
-//! handle the timeout case. This first example will break out of the loop
-//! after 10 seconds no matter what:
-//!
-//! ```no_run
-//! # #![feature(std_misc, old_io)]
-//! use std::sync::mpsc::channel;
-//! use std::old_io::timer::Timer;
-//! use std::time::Duration;
-//!
-//! let (tx, rx) = channel::<i32>();
-//! let mut timer = Timer::new().unwrap();
-//! let timeout = timer.oneshot(Duration::seconds(10));
-//!
-//! loop {
-//!     select! {
-//!         val = rx.recv() => println!("Received {}", val.unwrap()),
-//!         _ = timeout.recv() => {
-//!             println!("timed out, total time was more than 10 seconds");
-//!             break;
-//!         }
-//!     }
-//! }
-//! ```
-//!
-//! This second example is more costly since it allocates a new timer every
-//! time a message is received, but it allows you to timeout after the channel
-//! has been inactive for 5 seconds:
-//!
-//! ```no_run
-//! # #![feature(std_misc, old_io)]
-//! use std::sync::mpsc::channel;
-//! use std::old_io::timer::Timer;
-//! use std::time::Duration;
-//!
-//! let (tx, rx) = channel::<i32>();
-//! let mut timer = Timer::new().unwrap();
-//!
-//! loop {
-//!     let timeout = timer.oneshot(Duration::seconds(5));
-//!
-//!     select! {
-//!         val = rx.recv() => println!("Received {}", val.unwrap()),
-//!         _ = timeout.recv() => {
-//!             println!("timed out, no message received in 5 seconds");
-//!             break;
-//!         }
-//!     }
-//! }
-//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 16e7f265412f3211a40e0118c6b40ff4d26b8757..46fb20cd6a2d69356b5f93fe38a9ef50bc7af725 100644 (file)
 use prelude::v1::*;
 
 use cell::UnsafeCell;
+use fmt;
 use marker;
 use ops::{Deref, DerefMut};
-use sync::poison::{self, TryLockError, TryLockResult, LockResult};
 use sys_common::mutex as sys;
-use fmt;
+use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 
 /// A mutual exclusion primitive useful for protecting shared data
 ///
@@ -212,7 +212,7 @@ pub fn lock(&self) -> LockResult<MutexGuard<T>> {
 
     /// Attempts to acquire this lock.
     ///
-    /// If the lock could not be acquired at this time, then `None` is returned.
+    /// If the lock could not be acquired at this time, then `Err` is returned.
     /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
     /// guard is dropped.
     ///
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
deleted file mode 100644 (file)
index 347cd0b..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2014 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 prelude::v1::*;
-
-use cell::UnsafeCell;
-use error::{Error};
-use fmt;
-use thread;
-
-pub struct Flag { failed: UnsafeCell<bool> }
-
-// This flag is only ever accessed with a lock previously held. Note that this
-// a totally private structure.
-unsafe impl Send for Flag {}
-unsafe impl Sync for Flag {}
-
-pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } };
-
-impl Flag {
-    #[inline]
-    pub fn borrow(&self) -> LockResult<Guard> {
-        let ret = Guard { panicking: thread::panicking() };
-        if unsafe { *self.failed.get() } {
-            Err(PoisonError::new(ret))
-        } else {
-            Ok(ret)
-        }
-    }
-
-    #[inline]
-    pub fn done(&self, guard: &Guard) {
-        if !guard.panicking && thread::panicking() {
-            unsafe { *self.failed.get() = true; }
-        }
-    }
-
-    #[inline]
-    pub fn get(&self) -> bool {
-        unsafe { *self.failed.get() }
-    }
-}
-
-pub struct Guard {
-    panicking: bool,
-}
-
-/// A type of error which can be returned whenever a lock is acquired.
-///
-/// Both Mutexes and RwLocks are poisoned whenever a task fails while the lock
-/// is held. The precise semantics for when a lock is poisoned is documented on
-/// each lock, but once a lock is poisoned then all future acquisitions will
-/// return this error.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct PoisonError<T> {
-    guard: T,
-}
-
-/// An enumeration of possible errors which can occur while calling the
-/// `try_lock` method.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub enum TryLockError<T> {
-    /// The lock could not be acquired because another task failed while holding
-    /// the lock.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    Poisoned(PoisonError<T>),
-    /// The lock could not be acquired at this time because the operation would
-    /// otherwise block.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    WouldBlock,
-}
-
-/// A type alias for the result of a lock method which can be poisoned.
-///
-/// The `Ok` variant of this result indicates that the primitive was not
-/// poisoned, and the `Guard` is contained within. The `Err` variant indicates
-/// that the primitive was poisoned. Note that the `Err` variant *also* carries
-/// the associated guard, and it can be acquired through the `into_inner`
-/// method.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
-
-/// A type alias for the result of a nonblocking locking method.
-///
-/// For more information, see `LockResult`. A `TryLockResult` doesn't
-/// necessarily hold the associated guard in the `Err` type as the lock may not
-/// have been acquired for other reasons.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> fmt::Debug for PoisonError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        "PoisonError { inner: .. }".fmt(f)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> fmt::Display for PoisonError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        "poisoned lock: another task failed inside".fmt(f)
-    }
-}
-
-impl<T: Send> Error for PoisonError<T> {
-    fn description(&self) -> &str {
-        "poisoned lock: another task failed inside"
-    }
-}
-
-impl<T> PoisonError<T> {
-    /// Create a `PoisonError`.
-    #[unstable(feature = "std_misc")]
-    pub fn new(guard: T) -> PoisonError<T> {
-        PoisonError { guard: guard }
-    }
-
-    /// Consumes this error indicating that a lock is poisoned, returning the
-    /// underlying guard to allow access regardless.
-    #[unstable(feature = "std_misc")]
-    pub fn into_inner(self) -> T { self.guard }
-
-    /// Reaches into this error indicating that a lock is poisoned, returning a
-    /// reference to the underlying guard to allow access regardless.
-    #[unstable(feature = "std_misc")]
-    pub fn get_ref(&self) -> &T { &self.guard }
-
-    /// Reaches into this error indicating that a lock is poisoned, returning a
-    /// mutable reference to the underlying guard to allow access regardless.
-    #[unstable(feature = "std_misc")]
-    pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
-}
-
-impl<T> From<PoisonError<T>> for TryLockError<T> {
-    fn from(err: PoisonError<T>) -> TryLockError<T> {
-        TryLockError::Poisoned(err)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> fmt::Debug for TryLockError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f),
-            TryLockError::WouldBlock => "WouldBlock".fmt(f)
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> fmt::Display for TryLockError<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.description().fmt(f)
-    }
-}
-
-impl<T: Send> Error for TryLockError<T> {
-    fn description(&self) -> &str {
-        match *self {
-            TryLockError::Poisoned(ref p) => p.description(),
-            TryLockError::WouldBlock => "try_lock failed because the operation would block"
-        }
-    }
-
-    fn cause(&self) -> Option<&Error> {
-        match *self {
-            TryLockError::Poisoned(ref p) => Some(p),
-            _ => None
-        }
-    }
-}
-
-pub fn map_result<T, U, F>(result: LockResult<T>, f: F)
-                           -> LockResult<U>
-                           where F: FnOnce(T) -> U {
-    match result {
-        Ok(t) => Ok(f(t)),
-        Err(PoisonError { guard }) => Err(PoisonError::new(f(guard)))
-    }
-}
index d70350bc7d6512d40a975dd8dd1da2637c6afa4c..eb6d46a5dda7a160e3a4212140def19945804481 100644 (file)
 use prelude::v1::*;
 
 use cell::UnsafeCell;
+use fmt;
 use marker;
 use ops::{Deref, DerefMut};
-use sync::poison::{self, LockResult, TryLockError, TryLockResult};
+use sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
 use sys_common::rwlock as sys;
-use fmt;
 
 /// A reader-writer lock
 ///
index d2e2f1044d612aef23ce8d7c5a7d0a78ee952680..8a01eace889c378abb7a248aa99e7acc6d06c06e 100644 (file)
@@ -29,6 +29,8 @@
 pub mod mutex;
 pub mod net;
 pub mod net2;
+pub mod poison;
+pub mod remutex;
 pub mod rwlock;
 pub mod stack;
 pub mod thread;
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
new file mode 100644 (file)
index 0000000..347cd0b
--- /dev/null
@@ -0,0 +1,187 @@
+// Copyright 2014 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 prelude::v1::*;
+
+use cell::UnsafeCell;
+use error::{Error};
+use fmt;
+use thread;
+
+pub struct Flag { failed: UnsafeCell<bool> }
+
+// This flag is only ever accessed with a lock previously held. Note that this
+// a totally private structure.
+unsafe impl Send for Flag {}
+unsafe impl Sync for Flag {}
+
+pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } };
+
+impl Flag {
+    #[inline]
+    pub fn borrow(&self) -> LockResult<Guard> {
+        let ret = Guard { panicking: thread::panicking() };
+        if unsafe { *self.failed.get() } {
+            Err(PoisonError::new(ret))
+        } else {
+            Ok(ret)
+        }
+    }
+
+    #[inline]
+    pub fn done(&self, guard: &Guard) {
+        if !guard.panicking && thread::panicking() {
+            unsafe { *self.failed.get() = true; }
+        }
+    }
+
+    #[inline]
+    pub fn get(&self) -> bool {
+        unsafe { *self.failed.get() }
+    }
+}
+
+pub struct Guard {
+    panicking: bool,
+}
+
+/// A type of error which can be returned whenever a lock is acquired.
+///
+/// Both Mutexes and RwLocks are poisoned whenever a task fails while the lock
+/// is held. The precise semantics for when a lock is poisoned is documented on
+/// each lock, but once a lock is poisoned then all future acquisitions will
+/// return this error.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct PoisonError<T> {
+    guard: T,
+}
+
+/// An enumeration of possible errors which can occur while calling the
+/// `try_lock` method.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum TryLockError<T> {
+    /// The lock could not be acquired because another task failed while holding
+    /// the lock.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Poisoned(PoisonError<T>),
+    /// The lock could not be acquired at this time because the operation would
+    /// otherwise block.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    WouldBlock,
+}
+
+/// A type alias for the result of a lock method which can be poisoned.
+///
+/// The `Ok` variant of this result indicates that the primitive was not
+/// poisoned, and the `Guard` is contained within. The `Err` variant indicates
+/// that the primitive was poisoned. Note that the `Err` variant *also* carries
+/// the associated guard, and it can be acquired through the `into_inner`
+/// method.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
+
+/// A type alias for the result of a nonblocking locking method.
+///
+/// For more information, see `LockResult`. A `TryLockResult` doesn't
+/// necessarily hold the associated guard in the `Err` type as the lock may not
+/// have been acquired for other reasons.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Debug for PoisonError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "PoisonError { inner: .. }".fmt(f)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Display for PoisonError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "poisoned lock: another task failed inside".fmt(f)
+    }
+}
+
+impl<T: Send> Error for PoisonError<T> {
+    fn description(&self) -> &str {
+        "poisoned lock: another task failed inside"
+    }
+}
+
+impl<T> PoisonError<T> {
+    /// Create a `PoisonError`.
+    #[unstable(feature = "std_misc")]
+    pub fn new(guard: T) -> PoisonError<T> {
+        PoisonError { guard: guard }
+    }
+
+    /// Consumes this error indicating that a lock is poisoned, returning the
+    /// underlying guard to allow access regardless.
+    #[unstable(feature = "std_misc")]
+    pub fn into_inner(self) -> T { self.guard }
+
+    /// Reaches into this error indicating that a lock is poisoned, returning a
+    /// reference to the underlying guard to allow access regardless.
+    #[unstable(feature = "std_misc")]
+    pub fn get_ref(&self) -> &T { &self.guard }
+
+    /// Reaches into this error indicating that a lock is poisoned, returning a
+    /// mutable reference to the underlying guard to allow access regardless.
+    #[unstable(feature = "std_misc")]
+    pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
+}
+
+impl<T> From<PoisonError<T>> for TryLockError<T> {
+    fn from(err: PoisonError<T>) -> TryLockError<T> {
+        TryLockError::Poisoned(err)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Debug for TryLockError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f),
+            TryLockError::WouldBlock => "WouldBlock".fmt(f)
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Send> fmt::Display for TryLockError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
+impl<T: Send> Error for TryLockError<T> {
+    fn description(&self) -> &str {
+        match *self {
+            TryLockError::Poisoned(ref p) => p.description(),
+            TryLockError::WouldBlock => "try_lock failed because the operation would block"
+        }
+    }
+
+    fn cause(&self) -> Option<&Error> {
+        match *self {
+            TryLockError::Poisoned(ref p) => Some(p),
+            _ => None
+        }
+    }
+}
+
+pub fn map_result<T, U, F>(result: LockResult<T>, f: F)
+                           -> LockResult<U>
+                           where F: FnOnce(T) -> U {
+    match result {
+        Ok(t) => Ok(f(t)),
+        Err(PoisonError { guard }) => Err(PoisonError::new(f(guard)))
+    }
+}
diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs
new file mode 100644 (file)
index 0000000..b35063c
--- /dev/null
@@ -0,0 +1,233 @@
+// Copyright 2015 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.
+#![unstable(feature = "reentrant_mutex", reason = "new API")]
+
+use prelude::v1::*;
+
+use fmt;
+use marker;
+use ops::Deref;
+use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
+use sys::mutex as sys;
+
+/// A re-entrant mutual exclusion
+///
+/// This mutex will block *other* threads waiting for the lock to become available. The thread
+/// which has already locked the mutex can lock it multiple times without blocking, preventing a
+/// common source of deadlocks.
+pub struct ReentrantMutex<T> {
+    inner: Box<sys::ReentrantMutex>,
+    poison: poison::Flag,
+    data: T,
+}
+
+unsafe impl<T: Send> Send for ReentrantMutex<T> {}
+unsafe impl<T: Send> Sync for ReentrantMutex<T> {}
+
+
+/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
+/// dropped (falls out of scope), the lock will be unlocked.
+///
+/// The data protected by the mutex can be accessed through this guard via its
+/// Deref and DerefMut implementations
+#[must_use]
+pub struct ReentrantMutexGuard<'a, T: 'a> {
+    // funny underscores due to how Deref/DerefMut currently work (they
+    // disregard field privacy).
+    __lock: &'a ReentrantMutex<T>,
+    __poison: poison::Guard,
+}
+
+impl<'a, T> !marker::Send for ReentrantMutexGuard<'a, T> {}
+
+
+impl<T> ReentrantMutex<T> {
+    /// Creates a new reentrant mutex in an unlocked state.
+    pub fn new(t: T) -> ReentrantMutex<T> {
+        ReentrantMutex {
+            inner: box unsafe { sys::ReentrantMutex::new() },
+            poison: poison::FLAG_INIT,
+            data: t,
+        }
+    }
+
+    /// Acquires a mutex, blocking the current thread until it is able to do so.
+    ///
+    /// This function will block the caller until it is available to acquire the mutex.
+    /// Upon returning, the thread is the only thread with the mutex held. When the thread
+    /// calling this method already holds the lock, the call shall succeed without
+    /// blocking.
+    ///
+    /// # Failure
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return failure if the mutex would otherwise be
+    /// acquired.
+    pub fn lock(&self) -> LockResult<ReentrantMutexGuard<T>> {
+        unsafe { self.inner.lock() }
+        ReentrantMutexGuard::new(&self)
+    }
+
+    /// Attempts to acquire this lock.
+    ///
+    /// If the lock could not be acquired at this time, then `Err` is returned.
+    /// Otherwise, an RAII guard is returned.
+    ///
+    /// This function does not block.
+    ///
+    /// # Failure
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will return failure if the mutex would otherwise be
+    /// acquired.
+    pub fn try_lock(&self) -> TryLockResult<ReentrantMutexGuard<T>> {
+        if unsafe { self.inner.try_lock() } {
+            Ok(try!(ReentrantMutexGuard::new(&self)))
+        } else {
+            Err(TryLockError::WouldBlock)
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for ReentrantMutex<T> {
+    fn drop(&mut self) {
+        // This is actually safe b/c we know that there is no further usage of
+        // this mutex (it's up to the user to arrange for a mutex to get
+        // dropped, that's not our job)
+        unsafe { self.inner.destroy() }
+    }
+}
+
+impl<T: fmt::Debug + 'static> fmt::Debug for ReentrantMutex<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.try_lock() {
+            Ok(guard) => write!(f, "ReentrantMutex {{ data: {:?} }}", &*guard),
+            Err(TryLockError::Poisoned(err)) => {
+                write!(f, "ReentrantMutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
+            },
+            Err(TryLockError::WouldBlock) => write!(f, "ReentrantMutex {{ <locked> }}")
+        }
+    }
+}
+
+impl<'mutex, T> ReentrantMutexGuard<'mutex, T> {
+    fn new(lock: &'mutex ReentrantMutex<T>)
+            -> LockResult<ReentrantMutexGuard<'mutex, T>> {
+        poison::map_result(lock.poison.borrow(), |guard| {
+            ReentrantMutexGuard {
+                __lock: lock,
+                __poison: guard,
+            }
+        })
+    }
+}
+
+impl<'mutex, T> Deref for ReentrantMutexGuard<'mutex, T> {
+    type Target = T;
+
+    fn deref<'a>(&'a self) -> &'a T {
+        &self.__lock.data
+    }
+}
+
+#[unsafe_destructor]
+impl<'a, T> Drop for ReentrantMutexGuard<'a, T> {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.__lock.poison.done(&self.__poison);
+            self.__lock.inner.unlock();
+        }
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use prelude::v1::*;
+    use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
+    use cell::RefCell;
+    use sync::Arc;
+    use boxed;
+    use thread;
+
+    #[test]
+    fn smoke() {
+        let m = ReentrantMutex::new(());
+        {
+            let a = m.lock().unwrap();
+            {
+                let b = m.lock().unwrap();
+                {
+                    let c = m.lock().unwrap();
+                    assert_eq!(*c, ());
+                }
+                assert_eq!(*b, ());
+            }
+            assert_eq!(*a, ());
+        }
+    }
+
+    #[test]
+    fn is_mutex() {
+        let m = ReentrantMutex::new(RefCell::new(0));
+        let lock = m.lock().unwrap();
+        let handle = thread::scoped(|| {
+            let lock = m.lock().unwrap();
+            assert_eq!(*lock.borrow(), 4950);
+        });
+        for i in 0..100 {
+            let mut lock = m.lock().unwrap();
+            *lock.borrow_mut() += i;
+        }
+        drop(lock);
+        drop(handle);
+    }
+
+    #[test]
+    fn trylock_works() {
+        let m = ReentrantMutex::new(());
+        let lock = m.try_lock().unwrap();
+        let lock2 = m.try_lock().unwrap();
+        {
+            thread::scoped(|| {
+                let lock = m.try_lock();
+                assert!(lock.is_err());
+            });
+        }
+        let lock3 = m.try_lock().unwrap();
+    }
+
+    pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
+    impl<'a> Drop for Answer<'a> {
+        fn drop(&mut self) {
+            *self.0.borrow_mut() = 42;
+        }
+    }
+
+    #[test]
+    fn poison_works() {
+        let m = Arc::new(ReentrantMutex::new(RefCell::new(0)));
+        let mc = m.clone();
+        let result = thread::spawn(move ||{
+            let lock = mc.lock().unwrap();
+            *lock.borrow_mut() = 1;
+            let lock2 = mc.lock().unwrap();
+            *lock.borrow_mut() = 2;
+            let answer = Answer(lock2);
+            panic!("What the answer to my lifetimes dilemma is?");
+            drop(answer);
+        }).join();
+        assert!(result.is_err());
+        let r = m.lock().err().unwrap().into_inner();
+        assert_eq!(*r.borrow(), 42);
+    }
+}
index 1c0ce2938040dceee727939abeff47242bda5f19..af814653c1466c5f1d315bb69de7faaa28fcb3d0 100644 (file)
@@ -12,6 +12,7 @@
 
 use cell::UnsafeCell;
 use sys::sync as ffi;
+use mem;
 
 pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
 
@@ -67,3 +68,50 @@ pub unsafe fn destroy(&self) {
         debug_assert!(r == 0 || r == libc::EINVAL);
     }
 }
+
+// FIXME: remove the box, because box happens twice now, once at the common layer and once here.
+// Box is necessary here, because mutex may not change address after it is intialised on some
+// platforms. Regular Mutex above handles this by offloading intialisation to the OS on first lock.
+// Sadly, as far as reentrant mutexes go, this scheme is not quite portable and we must initialise
+// when we create the mutex, in the `new`.
+pub struct ReentrantMutex { inner: Box<UnsafeCell<ffi::pthread_mutex_t>> }
+
+unsafe impl Send for ReentrantMutex {}
+unsafe impl Sync for ReentrantMutex {}
+
+impl ReentrantMutex {
+    pub unsafe fn new() -> ReentrantMutex {
+        let mutex = ReentrantMutex { inner: box mem::uninitialized() };
+        let mut attr: ffi::pthread_mutexattr_t = mem::uninitialized();
+        let result = ffi::pthread_mutexattr_init(&mut attr as *mut _);
+        debug_assert_eq!(result, 0);
+        let result = ffi::pthread_mutexattr_settype(&mut attr as *mut _,
+                                                    ffi::PTHREAD_MUTEX_RECURSIVE);
+        debug_assert_eq!(result, 0);
+        let result = ffi::pthread_mutex_init(mutex.inner.get(), &attr as *const _);
+        debug_assert_eq!(result, 0);
+        let result = ffi::pthread_mutexattr_destroy(&mut attr as *mut _);
+        debug_assert_eq!(result, 0);
+        mutex
+    }
+
+    pub unsafe fn lock(&self) {
+        let result = ffi::pthread_mutex_lock(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        ffi::pthread_mutex_trylock(self.inner.get()) == 0
+    }
+
+    pub unsafe fn unlock(&self) {
+        let result = ffi::pthread_mutex_unlock(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+
+    pub unsafe fn destroy(&self) {
+        let result = ffi::pthread_mutex_destroy(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+}
index 3c05fd602be8530d5d23251d12930d58bff4e900..41e1e206a423a7c43a0869c6ec642a5aedf9d1e9 100644 (file)
 
 use libc;
 
-pub use self::os::{PTHREAD_MUTEX_INITIALIZER, pthread_mutex_t};
+pub use self::os::{PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_RECURSIVE, pthread_mutex_t,
+                   pthread_mutexattr_t};
 pub use self::os::{PTHREAD_COND_INITIALIZER, pthread_cond_t};
 pub use self::os::{PTHREAD_RWLOCK_INITIALIZER, pthread_rwlock_t};
 
 extern {
     // mutexes
+    pub fn pthread_mutex_init(lock: *mut pthread_mutex_t, attr: *const pthread_mutexattr_t)
+                            -> libc::c_int;
     pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> libc::c_int;
     pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> libc::c_int;
     pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> libc::c_int;
     pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> libc::c_int;
 
+    pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> libc::c_int;
+    pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> libc::c_int;
+    pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: libc::c_int)
+                                    -> libc::c_int;
+
     // cvars
     pub fn pthread_cond_wait(cond: *mut pthread_cond_t,
                              lock: *mut pthread_mutex_t) -> libc::c_int;
@@ -52,12 +60,14 @@ mod os {
     use libc;
 
     pub type pthread_mutex_t = *mut libc::c_void;
+    pub type pthread_mutexattr_t = *mut libc::c_void;
     pub type pthread_cond_t = *mut libc::c_void;
     pub type pthread_rwlock_t = *mut libc::c_void;
 
     pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _;
     pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _;
     pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _;
+    pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
@@ -95,6 +105,12 @@ pub struct pthread_mutex_t {
         __opaque: [u8; __PTHREAD_MUTEX_SIZE__],
     }
     #[repr(C)]
+    pub struct pthread_mutexattr_t {
+        __sig: libc::c_long,
+        // note, that this is 16 bytes just to be safe, the actual struct might be smaller.
+        __opaque: [u8; 16],
+    }
+    #[repr(C)]
     pub struct pthread_cond_t {
         __sig: libc::c_long,
         __opaque: [u8; __PTHREAD_COND_SIZE__],
@@ -117,6 +133,8 @@ pub struct pthread_rwlock_t {
         __sig: _PTHREAD_RWLOCK_SIG_INIT,
         __opaque: [0; __PTHREAD_RWLOCK_SIZE__],
     };
+
+    pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
 }
 
 #[cfg(target_os = "linux")]
@@ -161,6 +179,12 @@ pub struct pthread_mutex_t {
         size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
     }
     #[repr(C)]
+    pub struct pthread_mutexattr_t {
+        __align: libc::c_longlong,
+        // note, that this is 16 bytes just to be safe, the actual struct might be smaller.
+        size: [u8; 16],
+    }
+    #[repr(C)]
     pub struct pthread_cond_t {
         __align: libc::c_longlong,
         size: [u8; __SIZEOF_PTHREAD_COND_T],
@@ -183,6 +207,7 @@ pub struct pthread_rwlock_t {
         __align: 0,
         size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
     };
+    pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
 }
 #[cfg(target_os = "android")]
 mod os {
@@ -190,6 +215,7 @@ mod os {
 
     #[repr(C)]
     pub struct pthread_mutex_t { value: libc::c_int }
+    pub type pthread_mutexattr_t = libc::c_long;
     #[repr(C)]
     pub struct pthread_cond_t { value: libc::c_int }
     #[repr(C)]
@@ -218,4 +244,5 @@ pub struct pthread_rwlock_t {
         pendingWriters: 0,
         reserved: [0 as *mut _; 4],
     };
+    pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
 }
index 0847f3b52bfabe171e370bed4e1b6a43cb75bfa5..ca20858bb5bc503936ef09078626454d299e390c 100644 (file)
@@ -12,6 +12,7 @@
 
 use cell::UnsafeCell;
 use sys::sync as ffi;
+use mem;
 
 pub struct Mutex { inner: UnsafeCell<ffi::SRWLOCK> }
 
@@ -57,3 +58,33 @@ pub unsafe fn destroy(&self) {
         // ...
     }
 }
+
+pub struct ReentrantMutex { inner: Box<UnsafeCell<ffi::CRITICAL_SECTION>> }
+
+unsafe impl Send for ReentrantMutex {}
+unsafe impl Sync for ReentrantMutex {}
+
+impl ReentrantMutex {
+    pub unsafe fn new() -> ReentrantMutex {
+        let mutex = ReentrantMutex { inner: box mem::uninitialized() };
+        ffi::InitializeCriticalSection(mutex.inner.get());
+        mutex
+    }
+
+    pub unsafe fn lock(&self) {
+        ffi::EnterCriticalSection(self.inner.get());
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        ffi::TryEnterCriticalSection(self.inner.get()) != 0
+    }
+
+    pub unsafe fn unlock(&self) {
+        ffi::LeaveCriticalSection(self.inner.get());
+    }
+
+    pub unsafe fn destroy(&self) {
+        ffi::DeleteCriticalSection(self.inner.get());
+    }
+}
index 7614104c98bf37bd8759f6832b6fcaa39d70b4a9..5410259540eaccbf5338c460a0c0c0add8a2a7c1 100644 (file)
@@ -8,17 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::{BOOL, DWORD, LPVOID, c_ulong};
+use libc::{BOOL, DWORD, LPVOID, LONG, HANDLE, c_ulong};
 use libc::types::os::arch::extra::BOOLEAN;
 
 pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
 pub type PSRWLOCK = *mut SRWLOCK;
 pub type ULONG = c_ulong;
+pub type ULONG_PTR = c_ulong;
 
 #[repr(C)]
 pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
 #[repr(C)]
 pub struct SRWLOCK { pub ptr: LPVOID }
+#[repr(C)]
+pub struct CRITICAL_SECTION {
+    CriticalSectionDebug: LPVOID,
+    LockCount: LONG,
+    RecursionCount: LONG,
+    OwningThread: HANDLE,
+    LockSemaphore: HANDLE,
+    SpinCount: ULONG_PTR
+}
 
 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
     ptr: 0 as *mut _,
@@ -41,4 +51,10 @@ pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
     pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK);
     pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
     pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
+
+    pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
+    pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
 }
index f13047d3725ec7c40586ee55b73caad7eeb13911..dd0c7d716b7979e462145a5dfa5fef7f44d28132 100644 (file)
@@ -14,7 +14,6 @@
 use ast::{StmtExpr, StmtSemi};
 use ast::TokenTree;
 use ast;
-use ast_util::path_to_ident;
 use ext::mtwt;
 use ext::build::AstBuilder;
 use attr;
 use visit::Visitor;
 use std_inject;
 
-pub fn expand_type(t: P<ast::Ty>,
-                   fld: &mut MacroExpander,
-                   impl_ty: Option<P<ast::Ty>>)
-                   -> P<ast::Ty> {
-    debug!("expanding type {:?} with impl_ty {:?}", t, impl_ty);
-    let t = match (t.node.clone(), impl_ty) {
-        // Expand uses of `Self` in impls to the concrete type.
-        (ast::Ty_::TyPath(None, ref path), Some(ref impl_ty)) => {
-            let path_as_ident = path_to_ident(path);
-            // Note unhygenic comparison here. I think this is correct, since
-            // even though `Self` is almost just a type parameter, the treatment
-            // for this expansion is as if it were a keyword.
-            if path_as_ident.is_some() &&
-               path_as_ident.unwrap().name == token::special_idents::type_self.name {
-                impl_ty.clone()
-            } else {
-                t
-            }
-        }
-        _ => t
-    };
-    fold::noop_fold_ty(t, fld)
-}
-
 pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
     e.and_then(|ast::Expr {id, node, span}| match node {
         // expr_mac should really be expr_ext or something; it's the
@@ -1354,13 +1329,11 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
-    // The type of the impl currently being expanded.
-    current_impl_type: Option<P<ast::Ty>>,
 }
 
 impl<'a, 'b> MacroExpander<'a, 'b> {
     pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
-        MacroExpander { cx: cx, current_impl_type: None }
+        MacroExpander { cx: cx }
     }
 }
 
@@ -1374,14 +1347,7 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
     }
 
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
-        let prev_type = self.current_impl_type.clone();
-        if let ast::Item_::ItemImpl(_, _, _, _, ref ty, _) = item.node {
-            self.current_impl_type = Some(ty.clone());
-        }
-
-        let result = expand_item(item, self);
-        self.current_impl_type = prev_type;
-        result
+        expand_item(item, self)
     }
 
     fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ {
@@ -1410,11 +1376,6 @@ fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem
             .into_iter().map(|i| i.expect_impl_item()).collect()
     }
 
-    fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> {
-        let impl_type = self.current_impl_type.clone();
-        expand_type(t, self, impl_type)
-    }
-
     fn new_span(&mut self, span: Span) -> Span {
         new_span(self.cx, span)
     }
index 250ba0442babeee9b45ca5d6172f392f7b098ec7..009075540fa1e01cbcf9f312ad009859c86420b7 100644 (file)
 
 struct ParserAnyMacro<'a> {
     parser: RefCell<Parser<'a>>,
+
+    /// Span of the expansion site of the macro this parser is for
+    site_span: Span,
+    /// The ident of the macro we're parsing
+    macro_ident: ast::Ident
 }
 
 impl<'a> ParserAnyMacro<'a> {
@@ -50,6 +55,12 @@ fn ensure_complete_parse(&self, allow_semi: bool) {
                               token_str);
             let span = parser.span;
             parser.span_err(span, &msg[..]);
+
+            let name = token::get_ident(self.macro_ident);
+            let msg = format!("caused by the macro expansion here; the usage \
+                               of `{}` is likely invalid in this context",
+                               name);
+            parser.span_note(self.site_span, &msg[..]);
         }
     }
 }
@@ -169,6 +180,12 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 // Weird, but useful for X-macros.
                 return box ParserAnyMacro {
                     parser: RefCell::new(p),
+
+                    // Pass along the original expansion site and the name of the macro
+                    // so we can print a useful error message if the parse of the expanded
+                    // macro leaves unparsed tokens.
+                    site_span: sp,
+                    macro_ident: name
                 }
               }
               Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
index 7e0bcd3e1dc3f8a2229823209c8d47a9cb722bdc..5032cd57eeb376772caf416f74966e961e2a5887 100644 (file)
@@ -111,6 +111,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> fmt::Pointer for P<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Pointer::fmt(&self.ptr, f)
+    }
+}
+
 impl<T: Hash> Hash for P<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         (**self).hash(state);
index 1fb6ee7bc7ce1952c59d0f0dd579b6b6e86413e3..ad6e81d53abccd8e646357165461d1df37bbcf12 100644 (file)
@@ -7798,15 +7798,15 @@ pub mod grapheme {
     #[allow(non_camel_case_types)]
     #[derive(Clone, Copy)]
     pub enum GraphemeCat {
-        GC_LV,
-        GC_LVT,
-        GC_T,
+        GC_Control,
         GC_Extend,
+        GC_LVT,
         GC_V,
-        GC_Control,
-        GC_SpacingMark,
         GC_L,
-        GC_RegionalIndicator,
+        GC_Regional_Indicator,
+        GC_LV,
+        GC_T,
+        GC_SpacingMark,
         GC_Any,
     }
 
@@ -7895,387 +7895,382 @@ pub fn grapheme_category(c: char) -> GraphemeCat {
         GC_Extend), ('\u{f3e}', '\u{f3f}', GC_SpacingMark), ('\u{f71}', '\u{f7e}', GC_Extend),
         ('\u{f7f}', '\u{f7f}', GC_SpacingMark), ('\u{f80}', '\u{f84}', GC_Extend), ('\u{f86}',
         '\u{f87}', GC_Extend), ('\u{f8d}', '\u{f97}', GC_Extend), ('\u{f99}', '\u{fbc}', GC_Extend),
-        ('\u{fc6}', '\u{fc6}', GC_Extend), ('\u{102b}', '\u{102c}', GC_SpacingMark), ('\u{102d}',
-        '\u{1030}', GC_Extend), ('\u{1031}', '\u{1031}', GC_SpacingMark), ('\u{1032}', '\u{1037}',
-        GC_Extend), ('\u{1038}', '\u{1038}', GC_SpacingMark), ('\u{1039}', '\u{103a}', GC_Extend),
-        ('\u{103b}', '\u{103c}', GC_SpacingMark), ('\u{103d}', '\u{103e}', GC_Extend), ('\u{1056}',
-        '\u{1057}', GC_SpacingMark), ('\u{1058}', '\u{1059}', GC_Extend), ('\u{105e}', '\u{1060}',
-        GC_Extend), ('\u{1062}', '\u{1064}', GC_SpacingMark), ('\u{1067}', '\u{106d}',
-        GC_SpacingMark), ('\u{1071}', '\u{1074}', GC_Extend), ('\u{1082}', '\u{1082}', GC_Extend),
-        ('\u{1083}', '\u{1084}', GC_SpacingMark), ('\u{1085}', '\u{1086}', GC_Extend), ('\u{1087}',
-        '\u{108c}', GC_SpacingMark), ('\u{108d}', '\u{108d}', GC_Extend), ('\u{108f}', '\u{108f}',
-        GC_SpacingMark), ('\u{109a}', '\u{109c}', GC_SpacingMark), ('\u{109d}', '\u{109d}',
-        GC_Extend), ('\u{1100}', '\u{115f}', GC_L), ('\u{1160}', '\u{11a7}', GC_V), ('\u{11a8}',
-        '\u{11ff}', GC_T), ('\u{135d}', '\u{135f}', GC_Extend), ('\u{1712}', '\u{1714}', GC_Extend),
-        ('\u{1732}', '\u{1734}', GC_Extend), ('\u{1752}', '\u{1753}', GC_Extend), ('\u{1772}',
-        '\u{1773}', GC_Extend), ('\u{17b4}', '\u{17b5}', GC_Extend), ('\u{17b6}', '\u{17b6}',
-        GC_SpacingMark), ('\u{17b7}', '\u{17bd}', GC_Extend), ('\u{17be}', '\u{17c5}',
-        GC_SpacingMark), ('\u{17c6}', '\u{17c6}', GC_Extend), ('\u{17c7}', '\u{17c8}',
-        GC_SpacingMark), ('\u{17c9}', '\u{17d3}', GC_Extend), ('\u{17dd}', '\u{17dd}', GC_Extend),
-        ('\u{180b}', '\u{180d}', GC_Extend), ('\u{180e}', '\u{180e}', GC_Control), ('\u{18a9}',
-        '\u{18a9}', GC_Extend), ('\u{1920}', '\u{1922}', GC_Extend), ('\u{1923}', '\u{1926}',
-        GC_SpacingMark), ('\u{1927}', '\u{1928}', GC_Extend), ('\u{1929}', '\u{192b}',
-        GC_SpacingMark), ('\u{1930}', '\u{1931}', GC_SpacingMark), ('\u{1932}', '\u{1932}',
-        GC_Extend), ('\u{1933}', '\u{1938}', GC_SpacingMark), ('\u{1939}', '\u{193b}', GC_Extend),
-        ('\u{19b0}', '\u{19c0}', GC_SpacingMark), ('\u{19c8}', '\u{19c9}', GC_SpacingMark),
-        ('\u{1a17}', '\u{1a18}', GC_Extend), ('\u{1a19}', '\u{1a1a}', GC_SpacingMark), ('\u{1a1b}',
-        '\u{1a1b}', GC_Extend), ('\u{1a55}', '\u{1a55}', GC_SpacingMark), ('\u{1a56}', '\u{1a56}',
-        GC_Extend), ('\u{1a57}', '\u{1a57}', GC_SpacingMark), ('\u{1a58}', '\u{1a5e}', GC_Extend),
-        ('\u{1a60}', '\u{1a60}', GC_Extend), ('\u{1a61}', '\u{1a61}', GC_SpacingMark), ('\u{1a62}',
-        '\u{1a62}', GC_Extend), ('\u{1a63}', '\u{1a64}', GC_SpacingMark), ('\u{1a65}', '\u{1a6c}',
-        GC_Extend), ('\u{1a6d}', '\u{1a72}', GC_SpacingMark), ('\u{1a73}', '\u{1a7c}', GC_Extend),
-        ('\u{1a7f}', '\u{1a7f}', GC_Extend), ('\u{1ab0}', '\u{1abd}', GC_Extend), ('\u{1abe}',
-        '\u{1abe}', GC_Extend), ('\u{1b00}', '\u{1b03}', GC_Extend), ('\u{1b04}', '\u{1b04}',
-        GC_SpacingMark), ('\u{1b34}', '\u{1b34}', GC_Extend), ('\u{1b35}', '\u{1b35}',
-        GC_SpacingMark), ('\u{1b36}', '\u{1b3a}', GC_Extend), ('\u{1b3b}', '\u{1b3b}',
-        GC_SpacingMark), ('\u{1b3c}', '\u{1b3c}', GC_Extend), ('\u{1b3d}', '\u{1b41}',
-        GC_SpacingMark), ('\u{1b42}', '\u{1b42}', GC_Extend), ('\u{1b43}', '\u{1b44}',
-        GC_SpacingMark), ('\u{1b6b}', '\u{1b73}', GC_Extend), ('\u{1b80}', '\u{1b81}', GC_Extend),
-        ('\u{1b82}', '\u{1b82}', GC_SpacingMark), ('\u{1ba1}', '\u{1ba1}', GC_SpacingMark),
-        ('\u{1ba2}', '\u{1ba5}', GC_Extend), ('\u{1ba6}', '\u{1ba7}', GC_SpacingMark), ('\u{1ba8}',
-        '\u{1ba9}', GC_Extend), ('\u{1baa}', '\u{1baa}', GC_SpacingMark), ('\u{1bab}', '\u{1bad}',
-        GC_Extend), ('\u{1be6}', '\u{1be6}', GC_Extend), ('\u{1be7}', '\u{1be7}', GC_SpacingMark),
-        ('\u{1be8}', '\u{1be9}', GC_Extend), ('\u{1bea}', '\u{1bec}', GC_SpacingMark), ('\u{1bed}',
-        '\u{1bed}', GC_Extend), ('\u{1bee}', '\u{1bee}', GC_SpacingMark), ('\u{1bef}', '\u{1bf1}',
-        GC_Extend), ('\u{1bf2}', '\u{1bf3}', GC_SpacingMark), ('\u{1c24}', '\u{1c2b}',
-        GC_SpacingMark), ('\u{1c2c}', '\u{1c33}', GC_Extend), ('\u{1c34}', '\u{1c35}',
-        GC_SpacingMark), ('\u{1c36}', '\u{1c37}', GC_Extend), ('\u{1cd0}', '\u{1cd2}', GC_Extend),
-        ('\u{1cd4}', '\u{1ce0}', GC_Extend), ('\u{1ce1}', '\u{1ce1}', GC_SpacingMark), ('\u{1ce2}',
-        '\u{1ce8}', GC_Extend), ('\u{1ced}', '\u{1ced}', GC_Extend), ('\u{1cf2}', '\u{1cf3}',
-        GC_SpacingMark), ('\u{1cf4}', '\u{1cf4}', GC_Extend), ('\u{1cf8}', '\u{1cf9}', GC_Extend),
-        ('\u{1dc0}', '\u{1df5}', GC_Extend), ('\u{1dfc}', '\u{1dff}', GC_Extend), ('\u{200b}',
-        '\u{200b}', GC_Control), ('\u{200c}', '\u{200d}', GC_Extend), ('\u{200e}', '\u{200f}',
-        GC_Control), ('\u{2028}', '\u{202e}', GC_Control), ('\u{2060}', '\u{206f}', GC_Control),
-        ('\u{20d0}', '\u{20dc}', GC_Extend), ('\u{20dd}', '\u{20e0}', GC_Extend), ('\u{20e1}',
-        '\u{20e1}', GC_Extend), ('\u{20e2}', '\u{20e4}', GC_Extend), ('\u{20e5}', '\u{20f0}',
-        GC_Extend), ('\u{2cef}', '\u{2cf1}', GC_Extend), ('\u{2d7f}', '\u{2d7f}', GC_Extend),
-        ('\u{2de0}', '\u{2dff}', GC_Extend), ('\u{302a}', '\u{302d}', GC_Extend), ('\u{302e}',
-        '\u{302f}', GC_Extend), ('\u{3099}', '\u{309a}', GC_Extend), ('\u{a66f}', '\u{a66f}',
-        GC_Extend), ('\u{a670}', '\u{a672}', GC_Extend), ('\u{a674}', '\u{a67d}', GC_Extend),
-        ('\u{a69f}', '\u{a69f}', GC_Extend), ('\u{a6f0}', '\u{a6f1}', GC_Extend), ('\u{a802}',
-        '\u{a802}', GC_Extend), ('\u{a806}', '\u{a806}', GC_Extend), ('\u{a80b}', '\u{a80b}',
-        GC_Extend), ('\u{a823}', '\u{a824}', GC_SpacingMark), ('\u{a825}', '\u{a826}', GC_Extend),
-        ('\u{a827}', '\u{a827}', GC_SpacingMark), ('\u{a880}', '\u{a881}', GC_SpacingMark),
-        ('\u{a8b4}', '\u{a8c3}', GC_SpacingMark), ('\u{a8c4}', '\u{a8c4}', GC_Extend), ('\u{a8e0}',
-        '\u{a8f1}', GC_Extend), ('\u{a926}', '\u{a92d}', GC_Extend), ('\u{a947}', '\u{a951}',
-        GC_Extend), ('\u{a952}', '\u{a953}', GC_SpacingMark), ('\u{a960}', '\u{a97c}', GC_L),
-        ('\u{a980}', '\u{a982}', GC_Extend), ('\u{a983}', '\u{a983}', GC_SpacingMark), ('\u{a9b3}',
-        '\u{a9b3}', GC_Extend), ('\u{a9b4}', '\u{a9b5}', GC_SpacingMark), ('\u{a9b6}', '\u{a9b9}',
-        GC_Extend), ('\u{a9ba}', '\u{a9bb}', GC_SpacingMark), ('\u{a9bc}', '\u{a9bc}', GC_Extend),
-        ('\u{a9bd}', '\u{a9c0}', GC_SpacingMark), ('\u{a9e5}', '\u{a9e5}', GC_Extend), ('\u{aa29}',
-        '\u{aa2e}', GC_Extend), ('\u{aa2f}', '\u{aa30}', GC_SpacingMark), ('\u{aa31}', '\u{aa32}',
-        GC_Extend), ('\u{aa33}', '\u{aa34}', GC_SpacingMark), ('\u{aa35}', '\u{aa36}', GC_Extend),
-        ('\u{aa43}', '\u{aa43}', GC_Extend), ('\u{aa4c}', '\u{aa4c}', GC_Extend), ('\u{aa4d}',
-        '\u{aa4d}', GC_SpacingMark), ('\u{aa7b}', '\u{aa7b}', GC_SpacingMark), ('\u{aa7c}',
-        '\u{aa7c}', GC_Extend), ('\u{aa7d}', '\u{aa7d}', GC_SpacingMark), ('\u{aab0}', '\u{aab0}',
-        GC_Extend), ('\u{aab2}', '\u{aab4}', GC_Extend), ('\u{aab7}', '\u{aab8}', GC_Extend),
-        ('\u{aabe}', '\u{aabf}', GC_Extend), ('\u{aac1}', '\u{aac1}', GC_Extend), ('\u{aaeb}',
-        '\u{aaeb}', GC_SpacingMark), ('\u{aaec}', '\u{aaed}', GC_Extend), ('\u{aaee}', '\u{aaef}',
-        GC_SpacingMark), ('\u{aaf5}', '\u{aaf5}', GC_SpacingMark), ('\u{aaf6}', '\u{aaf6}',
-        GC_Extend), ('\u{abe3}', '\u{abe4}', GC_SpacingMark), ('\u{abe5}', '\u{abe5}', GC_Extend),
-        ('\u{abe6}', '\u{abe7}', GC_SpacingMark), ('\u{abe8}', '\u{abe8}', GC_Extend), ('\u{abe9}',
-        '\u{abea}', GC_SpacingMark), ('\u{abec}', '\u{abec}', GC_SpacingMark), ('\u{abed}',
-        '\u{abed}', GC_Extend), ('\u{ac00}', '\u{ac00}', GC_LV), ('\u{ac01}', '\u{ac1b}', GC_LVT),
-        ('\u{ac1c}', '\u{ac1c}', GC_LV), ('\u{ac1d}', '\u{ac37}', GC_LVT), ('\u{ac38}', '\u{ac38}',
-        GC_LV), ('\u{ac39}', '\u{ac53}', GC_LVT), ('\u{ac54}', '\u{ac54}', GC_LV), ('\u{ac55}',
-        '\u{ac6f}', GC_LVT), ('\u{ac70}', '\u{ac70}', GC_LV), ('\u{ac71}', '\u{ac8b}', GC_LVT),
-        ('\u{ac8c}', '\u{ac8c}', GC_LV), ('\u{ac8d}', '\u{aca7}', GC_LVT), ('\u{aca8}', '\u{aca8}',
-        GC_LV), ('\u{aca9}', '\u{acc3}', GC_LVT), ('\u{acc4}', '\u{acc4}', GC_LV), ('\u{acc5}',
-        '\u{acdf}', GC_LVT), ('\u{ace0}', '\u{ace0}', GC_LV), ('\u{ace1}', '\u{acfb}', GC_LVT),
-        ('\u{acfc}', '\u{acfc}', GC_LV), ('\u{acfd}', '\u{ad17}', GC_LVT), ('\u{ad18}', '\u{ad18}',
-        GC_LV), ('\u{ad19}', '\u{ad33}', GC_LVT), ('\u{ad34}', '\u{ad34}', GC_LV), ('\u{ad35}',
-        '\u{ad4f}', GC_LVT), ('\u{ad50}', '\u{ad50}', GC_LV), ('\u{ad51}', '\u{ad6b}', GC_LVT),
-        ('\u{ad6c}', '\u{ad6c}', GC_LV), ('\u{ad6d}', '\u{ad87}', GC_LVT), ('\u{ad88}', '\u{ad88}',
-        GC_LV), ('\u{ad89}', '\u{ada3}', GC_LVT), ('\u{ada4}', '\u{ada4}', GC_LV), ('\u{ada5}',
-        '\u{adbf}', GC_LVT), ('\u{adc0}', '\u{adc0}', GC_LV), ('\u{adc1}', '\u{addb}', GC_LVT),
-        ('\u{addc}', '\u{addc}', GC_LV), ('\u{addd}', '\u{adf7}', GC_LVT), ('\u{adf8}', '\u{adf8}',
-        GC_LV), ('\u{adf9}', '\u{ae13}', GC_LVT), ('\u{ae14}', '\u{ae14}', GC_LV), ('\u{ae15}',
-        '\u{ae2f}', GC_LVT), ('\u{ae30}', '\u{ae30}', GC_LV), ('\u{ae31}', '\u{ae4b}', GC_LVT),
-        ('\u{ae4c}', '\u{ae4c}', GC_LV), ('\u{ae4d}', '\u{ae67}', GC_LVT), ('\u{ae68}', '\u{ae68}',
-        GC_LV), ('\u{ae69}', '\u{ae83}', GC_LVT), ('\u{ae84}', '\u{ae84}', GC_LV), ('\u{ae85}',
-        '\u{ae9f}', GC_LVT), ('\u{aea0}', '\u{aea0}', GC_LV), ('\u{aea1}', '\u{aebb}', GC_LVT),
-        ('\u{aebc}', '\u{aebc}', GC_LV), ('\u{aebd}', '\u{aed7}', GC_LVT), ('\u{aed8}', '\u{aed8}',
-        GC_LV), ('\u{aed9}', '\u{aef3}', GC_LVT), ('\u{aef4}', '\u{aef4}', GC_LV), ('\u{aef5}',
-        '\u{af0f}', GC_LVT), ('\u{af10}', '\u{af10}', GC_LV), ('\u{af11}', '\u{af2b}', GC_LVT),
-        ('\u{af2c}', '\u{af2c}', GC_LV), ('\u{af2d}', '\u{af47}', GC_LVT), ('\u{af48}', '\u{af48}',
-        GC_LV), ('\u{af49}', '\u{af63}', GC_LVT), ('\u{af64}', '\u{af64}', GC_LV), ('\u{af65}',
-        '\u{af7f}', GC_LVT), ('\u{af80}', '\u{af80}', GC_LV), ('\u{af81}', '\u{af9b}', GC_LVT),
-        ('\u{af9c}', '\u{af9c}', GC_LV), ('\u{af9d}', '\u{afb7}', GC_LVT), ('\u{afb8}', '\u{afb8}',
-        GC_LV), ('\u{afb9}', '\u{afd3}', GC_LVT), ('\u{afd4}', '\u{afd4}', GC_LV), ('\u{afd5}',
-        '\u{afef}', GC_LVT), ('\u{aff0}', '\u{aff0}', GC_LV), ('\u{aff1}', '\u{b00b}', GC_LVT),
-        ('\u{b00c}', '\u{b00c}', GC_LV), ('\u{b00d}', '\u{b027}', GC_LVT), ('\u{b028}', '\u{b028}',
-        GC_LV), ('\u{b029}', '\u{b043}', GC_LVT), ('\u{b044}', '\u{b044}', GC_LV), ('\u{b045}',
-        '\u{b05f}', GC_LVT), ('\u{b060}', '\u{b060}', GC_LV), ('\u{b061}', '\u{b07b}', GC_LVT),
-        ('\u{b07c}', '\u{b07c}', GC_LV), ('\u{b07d}', '\u{b097}', GC_LVT), ('\u{b098}', '\u{b098}',
-        GC_LV), ('\u{b099}', '\u{b0b3}', GC_LVT), ('\u{b0b4}', '\u{b0b4}', GC_LV), ('\u{b0b5}',
-        '\u{b0cf}', GC_LVT), ('\u{b0d0}', '\u{b0d0}', GC_LV), ('\u{b0d1}', '\u{b0eb}', GC_LVT),
-        ('\u{b0ec}', '\u{b0ec}', GC_LV), ('\u{b0ed}', '\u{b107}', GC_LVT), ('\u{b108}', '\u{b108}',
-        GC_LV), ('\u{b109}', '\u{b123}', GC_LVT), ('\u{b124}', '\u{b124}', GC_LV), ('\u{b125}',
-        '\u{b13f}', GC_LVT), ('\u{b140}', '\u{b140}', GC_LV), ('\u{b141}', '\u{b15b}', GC_LVT),
-        ('\u{b15c}', '\u{b15c}', GC_LV), ('\u{b15d}', '\u{b177}', GC_LVT), ('\u{b178}', '\u{b178}',
-        GC_LV), ('\u{b179}', '\u{b193}', GC_LVT), ('\u{b194}', '\u{b194}', GC_LV), ('\u{b195}',
-        '\u{b1af}', GC_LVT), ('\u{b1b0}', '\u{b1b0}', GC_LV), ('\u{b1b1}', '\u{b1cb}', GC_LVT),
-        ('\u{b1cc}', '\u{b1cc}', GC_LV), ('\u{b1cd}', '\u{b1e7}', GC_LVT), ('\u{b1e8}', '\u{b1e8}',
-        GC_LV), ('\u{b1e9}', '\u{b203}', GC_LVT), ('\u{b204}', '\u{b204}', GC_LV), ('\u{b205}',
-        '\u{b21f}', GC_LVT), ('\u{b220}', '\u{b220}', GC_LV), ('\u{b221}', '\u{b23b}', GC_LVT),
-        ('\u{b23c}', '\u{b23c}', GC_LV), ('\u{b23d}', '\u{b257}', GC_LVT), ('\u{b258}', '\u{b258}',
-        GC_LV), ('\u{b259}', '\u{b273}', GC_LVT), ('\u{b274}', '\u{b274}', GC_LV), ('\u{b275}',
-        '\u{b28f}', GC_LVT), ('\u{b290}', '\u{b290}', GC_LV), ('\u{b291}', '\u{b2ab}', GC_LVT),
-        ('\u{b2ac}', '\u{b2ac}', GC_LV), ('\u{b2ad}', '\u{b2c7}', GC_LVT), ('\u{b2c8}', '\u{b2c8}',
-        GC_LV), ('\u{b2c9}', '\u{b2e3}', GC_LVT), ('\u{b2e4}', '\u{b2e4}', GC_LV), ('\u{b2e5}',
-        '\u{b2ff}', GC_LVT), ('\u{b300}', '\u{b300}', GC_LV), ('\u{b301}', '\u{b31b}', GC_LVT),
-        ('\u{b31c}', '\u{b31c}', GC_LV), ('\u{b31d}', '\u{b337}', GC_LVT), ('\u{b338}', '\u{b338}',
-        GC_LV), ('\u{b339}', '\u{b353}', GC_LVT), ('\u{b354}', '\u{b354}', GC_LV), ('\u{b355}',
-        '\u{b36f}', GC_LVT), ('\u{b370}', '\u{b370}', GC_LV), ('\u{b371}', '\u{b38b}', GC_LVT),
-        ('\u{b38c}', '\u{b38c}', GC_LV), ('\u{b38d}', '\u{b3a7}', GC_LVT), ('\u{b3a8}', '\u{b3a8}',
-        GC_LV), ('\u{b3a9}', '\u{b3c3}', GC_LVT), ('\u{b3c4}', '\u{b3c4}', GC_LV), ('\u{b3c5}',
-        '\u{b3df}', GC_LVT), ('\u{b3e0}', '\u{b3e0}', GC_LV), ('\u{b3e1}', '\u{b3fb}', GC_LVT),
-        ('\u{b3fc}', '\u{b3fc}', GC_LV), ('\u{b3fd}', '\u{b417}', GC_LVT), ('\u{b418}', '\u{b418}',
-        GC_LV), ('\u{b419}', '\u{b433}', GC_LVT), ('\u{b434}', '\u{b434}', GC_LV), ('\u{b435}',
-        '\u{b44f}', GC_LVT), ('\u{b450}', '\u{b450}', GC_LV), ('\u{b451}', '\u{b46b}', GC_LVT),
-        ('\u{b46c}', '\u{b46c}', GC_LV), ('\u{b46d}', '\u{b487}', GC_LVT), ('\u{b488}', '\u{b488}',
-        GC_LV), ('\u{b489}', '\u{b4a3}', GC_LVT), ('\u{b4a4}', '\u{b4a4}', GC_LV), ('\u{b4a5}',
-        '\u{b4bf}', GC_LVT), ('\u{b4c0}', '\u{b4c0}', GC_LV), ('\u{b4c1}', '\u{b4db}', GC_LVT),
-        ('\u{b4dc}', '\u{b4dc}', GC_LV), ('\u{b4dd}', '\u{b4f7}', GC_LVT), ('\u{b4f8}', '\u{b4f8}',
-        GC_LV), ('\u{b4f9}', '\u{b513}', GC_LVT), ('\u{b514}', '\u{b514}', GC_LV), ('\u{b515}',
-        '\u{b52f}', GC_LVT), ('\u{b530}', '\u{b530}', GC_LV), ('\u{b531}', '\u{b54b}', GC_LVT),
-        ('\u{b54c}', '\u{b54c}', GC_LV), ('\u{b54d}', '\u{b567}', GC_LVT), ('\u{b568}', '\u{b568}',
-        GC_LV), ('\u{b569}', '\u{b583}', GC_LVT), ('\u{b584}', '\u{b584}', GC_LV), ('\u{b585}',
-        '\u{b59f}', GC_LVT), ('\u{b5a0}', '\u{b5a0}', GC_LV), ('\u{b5a1}', '\u{b5bb}', GC_LVT),
-        ('\u{b5bc}', '\u{b5bc}', GC_LV), ('\u{b5bd}', '\u{b5d7}', GC_LVT), ('\u{b5d8}', '\u{b5d8}',
-        GC_LV), ('\u{b5d9}', '\u{b5f3}', GC_LVT), ('\u{b5f4}', '\u{b5f4}', GC_LV), ('\u{b5f5}',
-        '\u{b60f}', GC_LVT), ('\u{b610}', '\u{b610}', GC_LV), ('\u{b611}', '\u{b62b}', GC_LVT),
-        ('\u{b62c}', '\u{b62c}', GC_LV), ('\u{b62d}', '\u{b647}', GC_LVT), ('\u{b648}', '\u{b648}',
-        GC_LV), ('\u{b649}', '\u{b663}', GC_LVT), ('\u{b664}', '\u{b664}', GC_LV), ('\u{b665}',
-        '\u{b67f}', GC_LVT), ('\u{b680}', '\u{b680}', GC_LV), ('\u{b681}', '\u{b69b}', GC_LVT),
-        ('\u{b69c}', '\u{b69c}', GC_LV), ('\u{b69d}', '\u{b6b7}', GC_LVT), ('\u{b6b8}', '\u{b6b8}',
-        GC_LV), ('\u{b6b9}', '\u{b6d3}', GC_LVT), ('\u{b6d4}', '\u{b6d4}', GC_LV), ('\u{b6d5}',
-        '\u{b6ef}', GC_LVT), ('\u{b6f0}', '\u{b6f0}', GC_LV), ('\u{b6f1}', '\u{b70b}', GC_LVT),
-        ('\u{b70c}', '\u{b70c}', GC_LV), ('\u{b70d}', '\u{b727}', GC_LVT), ('\u{b728}', '\u{b728}',
-        GC_LV), ('\u{b729}', '\u{b743}', GC_LVT), ('\u{b744}', '\u{b744}', GC_LV), ('\u{b745}',
-        '\u{b75f}', GC_LVT), ('\u{b760}', '\u{b760}', GC_LV), ('\u{b761}', '\u{b77b}', GC_LVT),
-        ('\u{b77c}', '\u{b77c}', GC_LV), ('\u{b77d}', '\u{b797}', GC_LVT), ('\u{b798}', '\u{b798}',
-        GC_LV), ('\u{b799}', '\u{b7b3}', GC_LVT), ('\u{b7b4}', '\u{b7b4}', GC_LV), ('\u{b7b5}',
-        '\u{b7cf}', GC_LVT), ('\u{b7d0}', '\u{b7d0}', GC_LV), ('\u{b7d1}', '\u{b7eb}', GC_LVT),
-        ('\u{b7ec}', '\u{b7ec}', GC_LV), ('\u{b7ed}', '\u{b807}', GC_LVT), ('\u{b808}', '\u{b808}',
-        GC_LV), ('\u{b809}', '\u{b823}', GC_LVT), ('\u{b824}', '\u{b824}', GC_LV), ('\u{b825}',
-        '\u{b83f}', GC_LVT), ('\u{b840}', '\u{b840}', GC_LV), ('\u{b841}', '\u{b85b}', GC_LVT),
-        ('\u{b85c}', '\u{b85c}', GC_LV), ('\u{b85d}', '\u{b877}', GC_LVT), ('\u{b878}', '\u{b878}',
-        GC_LV), ('\u{b879}', '\u{b893}', GC_LVT), ('\u{b894}', '\u{b894}', GC_LV), ('\u{b895}',
-        '\u{b8af}', GC_LVT), ('\u{b8b0}', '\u{b8b0}', GC_LV), ('\u{b8b1}', '\u{b8cb}', GC_LVT),
-        ('\u{b8cc}', '\u{b8cc}', GC_LV), ('\u{b8cd}', '\u{b8e7}', GC_LVT), ('\u{b8e8}', '\u{b8e8}',
-        GC_LV), ('\u{b8e9}', '\u{b903}', GC_LVT), ('\u{b904}', '\u{b904}', GC_LV), ('\u{b905}',
-        '\u{b91f}', GC_LVT), ('\u{b920}', '\u{b920}', GC_LV), ('\u{b921}', '\u{b93b}', GC_LVT),
-        ('\u{b93c}', '\u{b93c}', GC_LV), ('\u{b93d}', '\u{b957}', GC_LVT), ('\u{b958}', '\u{b958}',
-        GC_LV), ('\u{b959}', '\u{b973}', GC_LVT), ('\u{b974}', '\u{b974}', GC_LV), ('\u{b975}',
-        '\u{b98f}', GC_LVT), ('\u{b990}', '\u{b990}', GC_LV), ('\u{b991}', '\u{b9ab}', GC_LVT),
-        ('\u{b9ac}', '\u{b9ac}', GC_LV), ('\u{b9ad}', '\u{b9c7}', GC_LVT), ('\u{b9c8}', '\u{b9c8}',
-        GC_LV), ('\u{b9c9}', '\u{b9e3}', GC_LVT), ('\u{b9e4}', '\u{b9e4}', GC_LV), ('\u{b9e5}',
-        '\u{b9ff}', GC_LVT), ('\u{ba00}', '\u{ba00}', GC_LV), ('\u{ba01}', '\u{ba1b}', GC_LVT),
-        ('\u{ba1c}', '\u{ba1c}', GC_LV), ('\u{ba1d}', '\u{ba37}', GC_LVT), ('\u{ba38}', '\u{ba38}',
-        GC_LV), ('\u{ba39}', '\u{ba53}', GC_LVT), ('\u{ba54}', '\u{ba54}', GC_LV), ('\u{ba55}',
-        '\u{ba6f}', GC_LVT), ('\u{ba70}', '\u{ba70}', GC_LV), ('\u{ba71}', '\u{ba8b}', GC_LVT),
-        ('\u{ba8c}', '\u{ba8c}', GC_LV), ('\u{ba8d}', '\u{baa7}', GC_LVT), ('\u{baa8}', '\u{baa8}',
-        GC_LV), ('\u{baa9}', '\u{bac3}', GC_LVT), ('\u{bac4}', '\u{bac4}', GC_LV), ('\u{bac5}',
-        '\u{badf}', GC_LVT), ('\u{bae0}', '\u{bae0}', GC_LV), ('\u{bae1}', '\u{bafb}', GC_LVT),
-        ('\u{bafc}', '\u{bafc}', GC_LV), ('\u{bafd}', '\u{bb17}', GC_LVT), ('\u{bb18}', '\u{bb18}',
-        GC_LV), ('\u{bb19}', '\u{bb33}', GC_LVT), ('\u{bb34}', '\u{bb34}', GC_LV), ('\u{bb35}',
-        '\u{bb4f}', GC_LVT), ('\u{bb50}', '\u{bb50}', GC_LV), ('\u{bb51}', '\u{bb6b}', GC_LVT),
-        ('\u{bb6c}', '\u{bb6c}', GC_LV), ('\u{bb6d}', '\u{bb87}', GC_LVT), ('\u{bb88}', '\u{bb88}',
-        GC_LV), ('\u{bb89}', '\u{bba3}', GC_LVT), ('\u{bba4}', '\u{bba4}', GC_LV), ('\u{bba5}',
-        '\u{bbbf}', GC_LVT), ('\u{bbc0}', '\u{bbc0}', GC_LV), ('\u{bbc1}', '\u{bbdb}', GC_LVT),
-        ('\u{bbdc}', '\u{bbdc}', GC_LV), ('\u{bbdd}', '\u{bbf7}', GC_LVT), ('\u{bbf8}', '\u{bbf8}',
-        GC_LV), ('\u{bbf9}', '\u{bc13}', GC_LVT), ('\u{bc14}', '\u{bc14}', GC_LV), ('\u{bc15}',
-        '\u{bc2f}', GC_LVT), ('\u{bc30}', '\u{bc30}', GC_LV), ('\u{bc31}', '\u{bc4b}', GC_LVT),
-        ('\u{bc4c}', '\u{bc4c}', GC_LV), ('\u{bc4d}', '\u{bc67}', GC_LVT), ('\u{bc68}', '\u{bc68}',
-        GC_LV), ('\u{bc69}', '\u{bc83}', GC_LVT), ('\u{bc84}', '\u{bc84}', GC_LV), ('\u{bc85}',
-        '\u{bc9f}', GC_LVT), ('\u{bca0}', '\u{bca0}', GC_LV), ('\u{bca1}', '\u{bcbb}', GC_LVT),
-        ('\u{bcbc}', '\u{bcbc}', GC_LV), ('\u{bcbd}', '\u{bcd7}', GC_LVT), ('\u{bcd8}', '\u{bcd8}',
-        GC_LV), ('\u{bcd9}', '\u{bcf3}', GC_LVT), ('\u{bcf4}', '\u{bcf4}', GC_LV), ('\u{bcf5}',
-        '\u{bd0f}', GC_LVT), ('\u{bd10}', '\u{bd10}', GC_LV), ('\u{bd11}', '\u{bd2b}', GC_LVT),
-        ('\u{bd2c}', '\u{bd2c}', GC_LV), ('\u{bd2d}', '\u{bd47}', GC_LVT), ('\u{bd48}', '\u{bd48}',
-        GC_LV), ('\u{bd49}', '\u{bd63}', GC_LVT), ('\u{bd64}', '\u{bd64}', GC_LV), ('\u{bd65}',
-        '\u{bd7f}', GC_LVT), ('\u{bd80}', '\u{bd80}', GC_LV), ('\u{bd81}', '\u{bd9b}', GC_LVT),
-        ('\u{bd9c}', '\u{bd9c}', GC_LV), ('\u{bd9d}', '\u{bdb7}', GC_LVT), ('\u{bdb8}', '\u{bdb8}',
-        GC_LV), ('\u{bdb9}', '\u{bdd3}', GC_LVT), ('\u{bdd4}', '\u{bdd4}', GC_LV), ('\u{bdd5}',
-        '\u{bdef}', GC_LVT), ('\u{bdf0}', '\u{bdf0}', GC_LV), ('\u{bdf1}', '\u{be0b}', GC_LVT),
-        ('\u{be0c}', '\u{be0c}', GC_LV), ('\u{be0d}', '\u{be27}', GC_LVT), ('\u{be28}', '\u{be28}',
-        GC_LV), ('\u{be29}', '\u{be43}', GC_LVT), ('\u{be44}', '\u{be44}', GC_LV), ('\u{be45}',
-        '\u{be5f}', GC_LVT), ('\u{be60}', '\u{be60}', GC_LV), ('\u{be61}', '\u{be7b}', GC_LVT),
-        ('\u{be7c}', '\u{be7c}', GC_LV), ('\u{be7d}', '\u{be97}', GC_LVT), ('\u{be98}', '\u{be98}',
-        GC_LV), ('\u{be99}', '\u{beb3}', GC_LVT), ('\u{beb4}', '\u{beb4}', GC_LV), ('\u{beb5}',
-        '\u{becf}', GC_LVT), ('\u{bed0}', '\u{bed0}', GC_LV), ('\u{bed1}', '\u{beeb}', GC_LVT),
-        ('\u{beec}', '\u{beec}', GC_LV), ('\u{beed}', '\u{bf07}', GC_LVT), ('\u{bf08}', '\u{bf08}',
-        GC_LV), ('\u{bf09}', '\u{bf23}', GC_LVT), ('\u{bf24}', '\u{bf24}', GC_LV), ('\u{bf25}',
-        '\u{bf3f}', GC_LVT), ('\u{bf40}', '\u{bf40}', GC_LV), ('\u{bf41}', '\u{bf5b}', GC_LVT),
-        ('\u{bf5c}', '\u{bf5c}', GC_LV), ('\u{bf5d}', '\u{bf77}', GC_LVT), ('\u{bf78}', '\u{bf78}',
-        GC_LV), ('\u{bf79}', '\u{bf93}', GC_LVT), ('\u{bf94}', '\u{bf94}', GC_LV), ('\u{bf95}',
-        '\u{bfaf}', GC_LVT), ('\u{bfb0}', '\u{bfb0}', GC_LV), ('\u{bfb1}', '\u{bfcb}', GC_LVT),
-        ('\u{bfcc}', '\u{bfcc}', GC_LV), ('\u{bfcd}', '\u{bfe7}', GC_LVT), ('\u{bfe8}', '\u{bfe8}',
-        GC_LV), ('\u{bfe9}', '\u{c003}', GC_LVT), ('\u{c004}', '\u{c004}', GC_LV), ('\u{c005}',
-        '\u{c01f}', GC_LVT), ('\u{c020}', '\u{c020}', GC_LV), ('\u{c021}', '\u{c03b}', GC_LVT),
-        ('\u{c03c}', '\u{c03c}', GC_LV), ('\u{c03d}', '\u{c057}', GC_LVT), ('\u{c058}', '\u{c058}',
-        GC_LV), ('\u{c059}', '\u{c073}', GC_LVT), ('\u{c074}', '\u{c074}', GC_LV), ('\u{c075}',
-        '\u{c08f}', GC_LVT), ('\u{c090}', '\u{c090}', GC_LV), ('\u{c091}', '\u{c0ab}', GC_LVT),
-        ('\u{c0ac}', '\u{c0ac}', GC_LV), ('\u{c0ad}', '\u{c0c7}', GC_LVT), ('\u{c0c8}', '\u{c0c8}',
-        GC_LV), ('\u{c0c9}', '\u{c0e3}', GC_LVT), ('\u{c0e4}', '\u{c0e4}', GC_LV), ('\u{c0e5}',
-        '\u{c0ff}', GC_LVT), ('\u{c100}', '\u{c100}', GC_LV), ('\u{c101}', '\u{c11b}', GC_LVT),
-        ('\u{c11c}', '\u{c11c}', GC_LV), ('\u{c11d}', '\u{c137}', GC_LVT), ('\u{c138}', '\u{c138}',
-        GC_LV), ('\u{c139}', '\u{c153}', GC_LVT), ('\u{c154}', '\u{c154}', GC_LV), ('\u{c155}',
-        '\u{c16f}', GC_LVT), ('\u{c170}', '\u{c170}', GC_LV), ('\u{c171}', '\u{c18b}', GC_LVT),
-        ('\u{c18c}', '\u{c18c}', GC_LV), ('\u{c18d}', '\u{c1a7}', GC_LVT), ('\u{c1a8}', '\u{c1a8}',
-        GC_LV), ('\u{c1a9}', '\u{c1c3}', GC_LVT), ('\u{c1c4}', '\u{c1c4}', GC_LV), ('\u{c1c5}',
-        '\u{c1df}', GC_LVT), ('\u{c1e0}', '\u{c1e0}', GC_LV), ('\u{c1e1}', '\u{c1fb}', GC_LVT),
-        ('\u{c1fc}', '\u{c1fc}', GC_LV), ('\u{c1fd}', '\u{c217}', GC_LVT), ('\u{c218}', '\u{c218}',
-        GC_LV), ('\u{c219}', '\u{c233}', GC_LVT), ('\u{c234}', '\u{c234}', GC_LV), ('\u{c235}',
-        '\u{c24f}', GC_LVT), ('\u{c250}', '\u{c250}', GC_LV), ('\u{c251}', '\u{c26b}', GC_LVT),
-        ('\u{c26c}', '\u{c26c}', GC_LV), ('\u{c26d}', '\u{c287}', GC_LVT), ('\u{c288}', '\u{c288}',
-        GC_LV), ('\u{c289}', '\u{c2a3}', GC_LVT), ('\u{c2a4}', '\u{c2a4}', GC_LV), ('\u{c2a5}',
-        '\u{c2bf}', GC_LVT), ('\u{c2c0}', '\u{c2c0}', GC_LV), ('\u{c2c1}', '\u{c2db}', GC_LVT),
-        ('\u{c2dc}', '\u{c2dc}', GC_LV), ('\u{c2dd}', '\u{c2f7}', GC_LVT), ('\u{c2f8}', '\u{c2f8}',
-        GC_LV), ('\u{c2f9}', '\u{c313}', GC_LVT), ('\u{c314}', '\u{c314}', GC_LV), ('\u{c315}',
-        '\u{c32f}', GC_LVT), ('\u{c330}', '\u{c330}', GC_LV), ('\u{c331}', '\u{c34b}', GC_LVT),
-        ('\u{c34c}', '\u{c34c}', GC_LV), ('\u{c34d}', '\u{c367}', GC_LVT), ('\u{c368}', '\u{c368}',
-        GC_LV), ('\u{c369}', '\u{c383}', GC_LVT), ('\u{c384}', '\u{c384}', GC_LV), ('\u{c385}',
-        '\u{c39f}', GC_LVT), ('\u{c3a0}', '\u{c3a0}', GC_LV), ('\u{c3a1}', '\u{c3bb}', GC_LVT),
-        ('\u{c3bc}', '\u{c3bc}', GC_LV), ('\u{c3bd}', '\u{c3d7}', GC_LVT), ('\u{c3d8}', '\u{c3d8}',
-        GC_LV), ('\u{c3d9}', '\u{c3f3}', GC_LVT), ('\u{c3f4}', '\u{c3f4}', GC_LV), ('\u{c3f5}',
-        '\u{c40f}', GC_LVT), ('\u{c410}', '\u{c410}', GC_LV), ('\u{c411}', '\u{c42b}', GC_LVT),
-        ('\u{c42c}', '\u{c42c}', GC_LV), ('\u{c42d}', '\u{c447}', GC_LVT), ('\u{c448}', '\u{c448}',
-        GC_LV), ('\u{c449}', '\u{c463}', GC_LVT), ('\u{c464}', '\u{c464}', GC_LV), ('\u{c465}',
-        '\u{c47f}', GC_LVT), ('\u{c480}', '\u{c480}', GC_LV), ('\u{c481}', '\u{c49b}', GC_LVT),
-        ('\u{c49c}', '\u{c49c}', GC_LV), ('\u{c49d}', '\u{c4b7}', GC_LVT), ('\u{c4b8}', '\u{c4b8}',
-        GC_LV), ('\u{c4b9}', '\u{c4d3}', GC_LVT), ('\u{c4d4}', '\u{c4d4}', GC_LV), ('\u{c4d5}',
-        '\u{c4ef}', GC_LVT), ('\u{c4f0}', '\u{c4f0}', GC_LV), ('\u{c4f1}', '\u{c50b}', GC_LVT),
-        ('\u{c50c}', '\u{c50c}', GC_LV), ('\u{c50d}', '\u{c527}', GC_LVT), ('\u{c528}', '\u{c528}',
-        GC_LV), ('\u{c529}', '\u{c543}', GC_LVT), ('\u{c544}', '\u{c544}', GC_LV), ('\u{c545}',
-        '\u{c55f}', GC_LVT), ('\u{c560}', '\u{c560}', GC_LV), ('\u{c561}', '\u{c57b}', GC_LVT),
-        ('\u{c57c}', '\u{c57c}', GC_LV), ('\u{c57d}', '\u{c597}', GC_LVT), ('\u{c598}', '\u{c598}',
-        GC_LV), ('\u{c599}', '\u{c5b3}', GC_LVT), ('\u{c5b4}', '\u{c5b4}', GC_LV), ('\u{c5b5}',
-        '\u{c5cf}', GC_LVT), ('\u{c5d0}', '\u{c5d0}', GC_LV), ('\u{c5d1}', '\u{c5eb}', GC_LVT),
-        ('\u{c5ec}', '\u{c5ec}', GC_LV), ('\u{c5ed}', '\u{c607}', GC_LVT), ('\u{c608}', '\u{c608}',
-        GC_LV), ('\u{c609}', '\u{c623}', GC_LVT), ('\u{c624}', '\u{c624}', GC_LV), ('\u{c625}',
-        '\u{c63f}', GC_LVT), ('\u{c640}', '\u{c640}', GC_LV), ('\u{c641}', '\u{c65b}', GC_LVT),
-        ('\u{c65c}', '\u{c65c}', GC_LV), ('\u{c65d}', '\u{c677}', GC_LVT), ('\u{c678}', '\u{c678}',
-        GC_LV), ('\u{c679}', '\u{c693}', GC_LVT), ('\u{c694}', '\u{c694}', GC_LV), ('\u{c695}',
-        '\u{c6af}', GC_LVT), ('\u{c6b0}', '\u{c6b0}', GC_LV), ('\u{c6b1}', '\u{c6cb}', GC_LVT),
-        ('\u{c6cc}', '\u{c6cc}', GC_LV), ('\u{c6cd}', '\u{c6e7}', GC_LVT), ('\u{c6e8}', '\u{c6e8}',
-        GC_LV), ('\u{c6e9}', '\u{c703}', GC_LVT), ('\u{c704}', '\u{c704}', GC_LV), ('\u{c705}',
-        '\u{c71f}', GC_LVT), ('\u{c720}', '\u{c720}', GC_LV), ('\u{c721}', '\u{c73b}', GC_LVT),
-        ('\u{c73c}', '\u{c73c}', GC_LV), ('\u{c73d}', '\u{c757}', GC_LVT), ('\u{c758}', '\u{c758}',
-        GC_LV), ('\u{c759}', '\u{c773}', GC_LVT), ('\u{c774}', '\u{c774}', GC_LV), ('\u{c775}',
-        '\u{c78f}', GC_LVT), ('\u{c790}', '\u{c790}', GC_LV), ('\u{c791}', '\u{c7ab}', GC_LVT),
-        ('\u{c7ac}', '\u{c7ac}', GC_LV), ('\u{c7ad}', '\u{c7c7}', GC_LVT), ('\u{c7c8}', '\u{c7c8}',
-        GC_LV), ('\u{c7c9}', '\u{c7e3}', GC_LVT), ('\u{c7e4}', '\u{c7e4}', GC_LV), ('\u{c7e5}',
-        '\u{c7ff}', GC_LVT), ('\u{c800}', '\u{c800}', GC_LV), ('\u{c801}', '\u{c81b}', GC_LVT),
-        ('\u{c81c}', '\u{c81c}', GC_LV), ('\u{c81d}', '\u{c837}', GC_LVT), ('\u{c838}', '\u{c838}',
-        GC_LV), ('\u{c839}', '\u{c853}', GC_LVT), ('\u{c854}', '\u{c854}', GC_LV), ('\u{c855}',
-        '\u{c86f}', GC_LVT), ('\u{c870}', '\u{c870}', GC_LV), ('\u{c871}', '\u{c88b}', GC_LVT),
-        ('\u{c88c}', '\u{c88c}', GC_LV), ('\u{c88d}', '\u{c8a7}', GC_LVT), ('\u{c8a8}', '\u{c8a8}',
-        GC_LV), ('\u{c8a9}', '\u{c8c3}', GC_LVT), ('\u{c8c4}', '\u{c8c4}', GC_LV), ('\u{c8c5}',
-        '\u{c8df}', GC_LVT), ('\u{c8e0}', '\u{c8e0}', GC_LV), ('\u{c8e1}', '\u{c8fb}', GC_LVT),
-        ('\u{c8fc}', '\u{c8fc}', GC_LV), ('\u{c8fd}', '\u{c917}', GC_LVT), ('\u{c918}', '\u{c918}',
-        GC_LV), ('\u{c919}', '\u{c933}', GC_LVT), ('\u{c934}', '\u{c934}', GC_LV), ('\u{c935}',
-        '\u{c94f}', GC_LVT), ('\u{c950}', '\u{c950}', GC_LV), ('\u{c951}', '\u{c96b}', GC_LVT),
-        ('\u{c96c}', '\u{c96c}', GC_LV), ('\u{c96d}', '\u{c987}', GC_LVT), ('\u{c988}', '\u{c988}',
-        GC_LV), ('\u{c989}', '\u{c9a3}', GC_LVT), ('\u{c9a4}', '\u{c9a4}', GC_LV), ('\u{c9a5}',
-        '\u{c9bf}', GC_LVT), ('\u{c9c0}', '\u{c9c0}', GC_LV), ('\u{c9c1}', '\u{c9db}', GC_LVT),
-        ('\u{c9dc}', '\u{c9dc}', GC_LV), ('\u{c9dd}', '\u{c9f7}', GC_LVT), ('\u{c9f8}', '\u{c9f8}',
-        GC_LV), ('\u{c9f9}', '\u{ca13}', GC_LVT), ('\u{ca14}', '\u{ca14}', GC_LV), ('\u{ca15}',
-        '\u{ca2f}', GC_LVT), ('\u{ca30}', '\u{ca30}', GC_LV), ('\u{ca31}', '\u{ca4b}', GC_LVT),
-        ('\u{ca4c}', '\u{ca4c}', GC_LV), ('\u{ca4d}', '\u{ca67}', GC_LVT), ('\u{ca68}', '\u{ca68}',
-        GC_LV), ('\u{ca69}', '\u{ca83}', GC_LVT), ('\u{ca84}', '\u{ca84}', GC_LV), ('\u{ca85}',
-        '\u{ca9f}', GC_LVT), ('\u{caa0}', '\u{caa0}', GC_LV), ('\u{caa1}', '\u{cabb}', GC_LVT),
-        ('\u{cabc}', '\u{cabc}', GC_LV), ('\u{cabd}', '\u{cad7}', GC_LVT), ('\u{cad8}', '\u{cad8}',
-        GC_LV), ('\u{cad9}', '\u{caf3}', GC_LVT), ('\u{caf4}', '\u{caf4}', GC_LV), ('\u{caf5}',
-        '\u{cb0f}', GC_LVT), ('\u{cb10}', '\u{cb10}', GC_LV), ('\u{cb11}', '\u{cb2b}', GC_LVT),
-        ('\u{cb2c}', '\u{cb2c}', GC_LV), ('\u{cb2d}', '\u{cb47}', GC_LVT), ('\u{cb48}', '\u{cb48}',
-        GC_LV), ('\u{cb49}', '\u{cb63}', GC_LVT), ('\u{cb64}', '\u{cb64}', GC_LV), ('\u{cb65}',
-        '\u{cb7f}', GC_LVT), ('\u{cb80}', '\u{cb80}', GC_LV), ('\u{cb81}', '\u{cb9b}', GC_LVT),
-        ('\u{cb9c}', '\u{cb9c}', GC_LV), ('\u{cb9d}', '\u{cbb7}', GC_LVT), ('\u{cbb8}', '\u{cbb8}',
-        GC_LV), ('\u{cbb9}', '\u{cbd3}', GC_LVT), ('\u{cbd4}', '\u{cbd4}', GC_LV), ('\u{cbd5}',
-        '\u{cbef}', GC_LVT), ('\u{cbf0}', '\u{cbf0}', GC_LV), ('\u{cbf1}', '\u{cc0b}', GC_LVT),
-        ('\u{cc0c}', '\u{cc0c}', GC_LV), ('\u{cc0d}', '\u{cc27}', GC_LVT), ('\u{cc28}', '\u{cc28}',
-        GC_LV), ('\u{cc29}', '\u{cc43}', GC_LVT), ('\u{cc44}', '\u{cc44}', GC_LV), ('\u{cc45}',
-        '\u{cc5f}', GC_LVT), ('\u{cc60}', '\u{cc60}', GC_LV), ('\u{cc61}', '\u{cc7b}', GC_LVT),
-        ('\u{cc7c}', '\u{cc7c}', GC_LV), ('\u{cc7d}', '\u{cc97}', GC_LVT), ('\u{cc98}', '\u{cc98}',
-        GC_LV), ('\u{cc99}', '\u{ccb3}', GC_LVT), ('\u{ccb4}', '\u{ccb4}', GC_LV), ('\u{ccb5}',
-        '\u{cccf}', GC_LVT), ('\u{ccd0}', '\u{ccd0}', GC_LV), ('\u{ccd1}', '\u{cceb}', GC_LVT),
-        ('\u{ccec}', '\u{ccec}', GC_LV), ('\u{cced}', '\u{cd07}', GC_LVT), ('\u{cd08}', '\u{cd08}',
-        GC_LV), ('\u{cd09}', '\u{cd23}', GC_LVT), ('\u{cd24}', '\u{cd24}', GC_LV), ('\u{cd25}',
-        '\u{cd3f}', GC_LVT), ('\u{cd40}', '\u{cd40}', GC_LV), ('\u{cd41}', '\u{cd5b}', GC_LVT),
-        ('\u{cd5c}', '\u{cd5c}', GC_LV), ('\u{cd5d}', '\u{cd77}', GC_LVT), ('\u{cd78}', '\u{cd78}',
-        GC_LV), ('\u{cd79}', '\u{cd93}', GC_LVT), ('\u{cd94}', '\u{cd94}', GC_LV), ('\u{cd95}',
-        '\u{cdaf}', GC_LVT), ('\u{cdb0}', '\u{cdb0}', GC_LV), ('\u{cdb1}', '\u{cdcb}', GC_LVT),
-        ('\u{cdcc}', '\u{cdcc}', GC_LV), ('\u{cdcd}', '\u{cde7}', GC_LVT), ('\u{cde8}', '\u{cde8}',
-        GC_LV), ('\u{cde9}', '\u{ce03}', GC_LVT), ('\u{ce04}', '\u{ce04}', GC_LV), ('\u{ce05}',
-        '\u{ce1f}', GC_LVT), ('\u{ce20}', '\u{ce20}', GC_LV), ('\u{ce21}', '\u{ce3b}', GC_LVT),
-        ('\u{ce3c}', '\u{ce3c}', GC_LV), ('\u{ce3d}', '\u{ce57}', GC_LVT), ('\u{ce58}', '\u{ce58}',
-        GC_LV), ('\u{ce59}', '\u{ce73}', GC_LVT), ('\u{ce74}', '\u{ce74}', GC_LV), ('\u{ce75}',
-        '\u{ce8f}', GC_LVT), ('\u{ce90}', '\u{ce90}', GC_LV), ('\u{ce91}', '\u{ceab}', GC_LVT),
-        ('\u{ceac}', '\u{ceac}', GC_LV), ('\u{cead}', '\u{cec7}', GC_LVT), ('\u{cec8}', '\u{cec8}',
-        GC_LV), ('\u{cec9}', '\u{cee3}', GC_LVT), ('\u{cee4}', '\u{cee4}', GC_LV), ('\u{cee5}',
-        '\u{ceff}', GC_LVT), ('\u{cf00}', '\u{cf00}', GC_LV), ('\u{cf01}', '\u{cf1b}', GC_LVT),
-        ('\u{cf1c}', '\u{cf1c}', GC_LV), ('\u{cf1d}', '\u{cf37}', GC_LVT), ('\u{cf38}', '\u{cf38}',
-        GC_LV), ('\u{cf39}', '\u{cf53}', GC_LVT), ('\u{cf54}', '\u{cf54}', GC_LV), ('\u{cf55}',
-        '\u{cf6f}', GC_LVT), ('\u{cf70}', '\u{cf70}', GC_LV), ('\u{cf71}', '\u{cf8b}', GC_LVT),
-        ('\u{cf8c}', '\u{cf8c}', GC_LV), ('\u{cf8d}', '\u{cfa7}', GC_LVT), ('\u{cfa8}', '\u{cfa8}',
-        GC_LV), ('\u{cfa9}', '\u{cfc3}', GC_LVT), ('\u{cfc4}', '\u{cfc4}', GC_LV), ('\u{cfc5}',
-        '\u{cfdf}', GC_LVT), ('\u{cfe0}', '\u{cfe0}', GC_LV), ('\u{cfe1}', '\u{cffb}', GC_LVT),
-        ('\u{cffc}', '\u{cffc}', GC_LV), ('\u{cffd}', '\u{d017}', GC_LVT), ('\u{d018}', '\u{d018}',
-        GC_LV), ('\u{d019}', '\u{d033}', GC_LVT), ('\u{d034}', '\u{d034}', GC_LV), ('\u{d035}',
-        '\u{d04f}', GC_LVT), ('\u{d050}', '\u{d050}', GC_LV), ('\u{d051}', '\u{d06b}', GC_LVT),
-        ('\u{d06c}', '\u{d06c}', GC_LV), ('\u{d06d}', '\u{d087}', GC_LVT), ('\u{d088}', '\u{d088}',
-        GC_LV), ('\u{d089}', '\u{d0a3}', GC_LVT), ('\u{d0a4}', '\u{d0a4}', GC_LV), ('\u{d0a5}',
-        '\u{d0bf}', GC_LVT), ('\u{d0c0}', '\u{d0c0}', GC_LV), ('\u{d0c1}', '\u{d0db}', GC_LVT),
-        ('\u{d0dc}', '\u{d0dc}', GC_LV), ('\u{d0dd}', '\u{d0f7}', GC_LVT), ('\u{d0f8}', '\u{d0f8}',
-        GC_LV), ('\u{d0f9}', '\u{d113}', GC_LVT), ('\u{d114}', '\u{d114}', GC_LV), ('\u{d115}',
-        '\u{d12f}', GC_LVT), ('\u{d130}', '\u{d130}', GC_LV), ('\u{d131}', '\u{d14b}', GC_LVT),
-        ('\u{d14c}', '\u{d14c}', GC_LV), ('\u{d14d}', '\u{d167}', GC_LVT), ('\u{d168}', '\u{d168}',
-        GC_LV), ('\u{d169}', '\u{d183}', GC_LVT), ('\u{d184}', '\u{d184}', GC_LV), ('\u{d185}',
-        '\u{d19f}', GC_LVT), ('\u{d1a0}', '\u{d1a0}', GC_LV), ('\u{d1a1}', '\u{d1bb}', GC_LVT),
-        ('\u{d1bc}', '\u{d1bc}', GC_LV), ('\u{d1bd}', '\u{d1d7}', GC_LVT), ('\u{d1d8}', '\u{d1d8}',
-        GC_LV), ('\u{d1d9}', '\u{d1f3}', GC_LVT), ('\u{d1f4}', '\u{d1f4}', GC_LV), ('\u{d1f5}',
-        '\u{d20f}', GC_LVT), ('\u{d210}', '\u{d210}', GC_LV), ('\u{d211}', '\u{d22b}', GC_LVT),
-        ('\u{d22c}', '\u{d22c}', GC_LV), ('\u{d22d}', '\u{d247}', GC_LVT), ('\u{d248}', '\u{d248}',
-        GC_LV), ('\u{d249}', '\u{d263}', GC_LVT), ('\u{d264}', '\u{d264}', GC_LV), ('\u{d265}',
-        '\u{d27f}', GC_LVT), ('\u{d280}', '\u{d280}', GC_LV), ('\u{d281}', '\u{d29b}', GC_LVT),
-        ('\u{d29c}', '\u{d29c}', GC_LV), ('\u{d29d}', '\u{d2b7}', GC_LVT), ('\u{d2b8}', '\u{d2b8}',
-        GC_LV), ('\u{d2b9}', '\u{d2d3}', GC_LVT), ('\u{d2d4}', '\u{d2d4}', GC_LV), ('\u{d2d5}',
-        '\u{d2ef}', GC_LVT), ('\u{d2f0}', '\u{d2f0}', GC_LV), ('\u{d2f1}', '\u{d30b}', GC_LVT),
-        ('\u{d30c}', '\u{d30c}', GC_LV), ('\u{d30d}', '\u{d327}', GC_LVT), ('\u{d328}', '\u{d328}',
-        GC_LV), ('\u{d329}', '\u{d343}', GC_LVT), ('\u{d344}', '\u{d344}', GC_LV), ('\u{d345}',
-        '\u{d35f}', GC_LVT), ('\u{d360}', '\u{d360}', GC_LV), ('\u{d361}', '\u{d37b}', GC_LVT),
-        ('\u{d37c}', '\u{d37c}', GC_LV), ('\u{d37d}', '\u{d397}', GC_LVT), ('\u{d398}', '\u{d398}',
-        GC_LV), ('\u{d399}', '\u{d3b3}', GC_LVT), ('\u{d3b4}', '\u{d3b4}', GC_LV), ('\u{d3b5}',
-        '\u{d3cf}', GC_LVT), ('\u{d3d0}', '\u{d3d0}', GC_LV), ('\u{d3d1}', '\u{d3eb}', GC_LVT),
-        ('\u{d3ec}', '\u{d3ec}', GC_LV), ('\u{d3ed}', '\u{d407}', GC_LVT), ('\u{d408}', '\u{d408}',
-        GC_LV), ('\u{d409}', '\u{d423}', GC_LVT), ('\u{d424}', '\u{d424}', GC_LV), ('\u{d425}',
-        '\u{d43f}', GC_LVT), ('\u{d440}', '\u{d440}', GC_LV), ('\u{d441}', '\u{d45b}', GC_LVT),
-        ('\u{d45c}', '\u{d45c}', GC_LV), ('\u{d45d}', '\u{d477}', GC_LVT), ('\u{d478}', '\u{d478}',
-        GC_LV), ('\u{d479}', '\u{d493}', GC_LVT), ('\u{d494}', '\u{d494}', GC_LV), ('\u{d495}',
-        '\u{d4af}', GC_LVT), ('\u{d4b0}', '\u{d4b0}', GC_LV), ('\u{d4b1}', '\u{d4cb}', GC_LVT),
-        ('\u{d4cc}', '\u{d4cc}', GC_LV), ('\u{d4cd}', '\u{d4e7}', GC_LVT), ('\u{d4e8}', '\u{d4e8}',
-        GC_LV), ('\u{d4e9}', '\u{d503}', GC_LVT), ('\u{d504}', '\u{d504}', GC_LV), ('\u{d505}',
-        '\u{d51f}', GC_LVT), ('\u{d520}', '\u{d520}', GC_LV), ('\u{d521}', '\u{d53b}', GC_LVT),
-        ('\u{d53c}', '\u{d53c}', GC_LV), ('\u{d53d}', '\u{d557}', GC_LVT), ('\u{d558}', '\u{d558}',
-        GC_LV), ('\u{d559}', '\u{d573}', GC_LVT), ('\u{d574}', '\u{d574}', GC_LV), ('\u{d575}',
-        '\u{d58f}', GC_LVT), ('\u{d590}', '\u{d590}', GC_LV), ('\u{d591}', '\u{d5ab}', GC_LVT),
-        ('\u{d5ac}', '\u{d5ac}', GC_LV), ('\u{d5ad}', '\u{d5c7}', GC_LVT), ('\u{d5c8}', '\u{d5c8}',
-        GC_LV), ('\u{d5c9}', '\u{d5e3}', GC_LVT), ('\u{d5e4}', '\u{d5e4}', GC_LV), ('\u{d5e5}',
-        '\u{d5ff}', GC_LVT), ('\u{d600}', '\u{d600}', GC_LV), ('\u{d601}', '\u{d61b}', GC_LVT),
-        ('\u{d61c}', '\u{d61c}', GC_LV), ('\u{d61d}', '\u{d637}', GC_LVT), ('\u{d638}', '\u{d638}',
-        GC_LV), ('\u{d639}', '\u{d653}', GC_LVT), ('\u{d654}', '\u{d654}', GC_LV), ('\u{d655}',
-        '\u{d66f}', GC_LVT), ('\u{d670}', '\u{d670}', GC_LV), ('\u{d671}', '\u{d68b}', GC_LVT),
-        ('\u{d68c}', '\u{d68c}', GC_LV), ('\u{d68d}', '\u{d6a7}', GC_LVT), ('\u{d6a8}', '\u{d6a8}',
-        GC_LV), ('\u{d6a9}', '\u{d6c3}', GC_LVT), ('\u{d6c4}', '\u{d6c4}', GC_LV), ('\u{d6c5}',
-        '\u{d6df}', GC_LVT), ('\u{d6e0}', '\u{d6e0}', GC_LV), ('\u{d6e1}', '\u{d6fb}', GC_LVT),
-        ('\u{d6fc}', '\u{d6fc}', GC_LV), ('\u{d6fd}', '\u{d717}', GC_LVT), ('\u{d718}', '\u{d718}',
-        GC_LV), ('\u{d719}', '\u{d733}', GC_LVT), ('\u{d734}', '\u{d734}', GC_LV), ('\u{d735}',
-        '\u{d74f}', GC_LVT), ('\u{d750}', '\u{d750}', GC_LV), ('\u{d751}', '\u{d76b}', GC_LVT),
-        ('\u{d76c}', '\u{d76c}', GC_LV), ('\u{d76d}', '\u{d787}', GC_LVT), ('\u{d788}', '\u{d788}',
-        GC_LV), ('\u{d789}', '\u{d7a3}', GC_LVT), ('\u{d7b0}', '\u{d7c6}', GC_V), ('\u{d7cb}',
-        '\u{d7fb}', GC_T), ('\u{fb1e}', '\u{fb1e}', GC_Extend), ('\u{fe00}', '\u{fe0f}', GC_Extend),
+        ('\u{fc6}', '\u{fc6}', GC_Extend), ('\u{102d}', '\u{1030}', GC_Extend), ('\u{1031}',
+        '\u{1031}', GC_SpacingMark), ('\u{1032}', '\u{1037}', GC_Extend), ('\u{1039}', '\u{103a}',
+        GC_Extend), ('\u{103b}', '\u{103c}', GC_SpacingMark), ('\u{103d}', '\u{103e}', GC_Extend),
+        ('\u{1056}', '\u{1057}', GC_SpacingMark), ('\u{1058}', '\u{1059}', GC_Extend), ('\u{105e}',
+        '\u{1060}', GC_Extend), ('\u{1071}', '\u{1074}', GC_Extend), ('\u{1082}', '\u{1082}',
+        GC_Extend), ('\u{1084}', '\u{1084}', GC_SpacingMark), ('\u{1085}', '\u{1086}', GC_Extend),
+        ('\u{108d}', '\u{108d}', GC_Extend), ('\u{109d}', '\u{109d}', GC_Extend), ('\u{1100}',
+        '\u{115f}', GC_L), ('\u{1160}', '\u{11a7}', GC_V), ('\u{11a8}', '\u{11ff}', GC_T),
+        ('\u{135d}', '\u{135f}', GC_Extend), ('\u{1712}', '\u{1714}', GC_Extend), ('\u{1732}',
+        '\u{1734}', GC_Extend), ('\u{1752}', '\u{1753}', GC_Extend), ('\u{1772}', '\u{1773}',
+        GC_Extend), ('\u{17b4}', '\u{17b5}', GC_Extend), ('\u{17b6}', '\u{17b6}', GC_SpacingMark),
+        ('\u{17b7}', '\u{17bd}', GC_Extend), ('\u{17be}', '\u{17c5}', GC_SpacingMark), ('\u{17c6}',
+        '\u{17c6}', GC_Extend), ('\u{17c7}', '\u{17c8}', GC_SpacingMark), ('\u{17c9}', '\u{17d3}',
+        GC_Extend), ('\u{17dd}', '\u{17dd}', GC_Extend), ('\u{180b}', '\u{180d}', GC_Extend),
+        ('\u{180e}', '\u{180e}', GC_Control), ('\u{18a9}', '\u{18a9}', GC_Extend), ('\u{1920}',
+        '\u{1922}', GC_Extend), ('\u{1923}', '\u{1926}', GC_SpacingMark), ('\u{1927}', '\u{1928}',
+        GC_Extend), ('\u{1929}', '\u{192b}', GC_SpacingMark), ('\u{1930}', '\u{1931}',
+        GC_SpacingMark), ('\u{1932}', '\u{1932}', GC_Extend), ('\u{1933}', '\u{1938}',
+        GC_SpacingMark), ('\u{1939}', '\u{193b}', GC_Extend), ('\u{19b5}', '\u{19b7}',
+        GC_SpacingMark), ('\u{19ba}', '\u{19ba}', GC_SpacingMark), ('\u{1a17}', '\u{1a18}',
+        GC_Extend), ('\u{1a19}', '\u{1a1a}', GC_SpacingMark), ('\u{1a1b}', '\u{1a1b}', GC_Extend),
+        ('\u{1a55}', '\u{1a55}', GC_SpacingMark), ('\u{1a56}', '\u{1a56}', GC_Extend), ('\u{1a57}',
+        '\u{1a57}', GC_SpacingMark), ('\u{1a58}', '\u{1a5e}', GC_Extend), ('\u{1a60}', '\u{1a60}',
+        GC_Extend), ('\u{1a62}', '\u{1a62}', GC_Extend), ('\u{1a65}', '\u{1a6c}', GC_Extend),
+        ('\u{1a6d}', '\u{1a72}', GC_SpacingMark), ('\u{1a73}', '\u{1a7c}', GC_Extend), ('\u{1a7f}',
+        '\u{1a7f}', GC_Extend), ('\u{1ab0}', '\u{1abd}', GC_Extend), ('\u{1abe}', '\u{1abe}',
+        GC_Extend), ('\u{1b00}', '\u{1b03}', GC_Extend), ('\u{1b04}', '\u{1b04}', GC_SpacingMark),
+        ('\u{1b34}', '\u{1b34}', GC_Extend), ('\u{1b35}', '\u{1b35}', GC_SpacingMark), ('\u{1b36}',
+        '\u{1b3a}', GC_Extend), ('\u{1b3b}', '\u{1b3b}', GC_SpacingMark), ('\u{1b3c}', '\u{1b3c}',
+        GC_Extend), ('\u{1b3d}', '\u{1b41}', GC_SpacingMark), ('\u{1b42}', '\u{1b42}', GC_Extend),
+        ('\u{1b43}', '\u{1b44}', GC_SpacingMark), ('\u{1b6b}', '\u{1b73}', GC_Extend), ('\u{1b80}',
+        '\u{1b81}', GC_Extend), ('\u{1b82}', '\u{1b82}', GC_SpacingMark), ('\u{1ba1}', '\u{1ba1}',
+        GC_SpacingMark), ('\u{1ba2}', '\u{1ba5}', GC_Extend), ('\u{1ba6}', '\u{1ba7}',
+        GC_SpacingMark), ('\u{1ba8}', '\u{1ba9}', GC_Extend), ('\u{1baa}', '\u{1baa}',
+        GC_SpacingMark), ('\u{1bab}', '\u{1bad}', GC_Extend), ('\u{1be6}', '\u{1be6}', GC_Extend),
+        ('\u{1be7}', '\u{1be7}', GC_SpacingMark), ('\u{1be8}', '\u{1be9}', GC_Extend), ('\u{1bea}',
+        '\u{1bec}', GC_SpacingMark), ('\u{1bed}', '\u{1bed}', GC_Extend), ('\u{1bee}', '\u{1bee}',
+        GC_SpacingMark), ('\u{1bef}', '\u{1bf1}', GC_Extend), ('\u{1bf2}', '\u{1bf3}',
+        GC_SpacingMark), ('\u{1c24}', '\u{1c2b}', GC_SpacingMark), ('\u{1c2c}', '\u{1c33}',
+        GC_Extend), ('\u{1c34}', '\u{1c35}', GC_SpacingMark), ('\u{1c36}', '\u{1c37}', GC_Extend),
+        ('\u{1cd0}', '\u{1cd2}', GC_Extend), ('\u{1cd4}', '\u{1ce0}', GC_Extend), ('\u{1ce1}',
+        '\u{1ce1}', GC_SpacingMark), ('\u{1ce2}', '\u{1ce8}', GC_Extend), ('\u{1ced}', '\u{1ced}',
+        GC_Extend), ('\u{1cf2}', '\u{1cf3}', GC_SpacingMark), ('\u{1cf4}', '\u{1cf4}', GC_Extend),
+        ('\u{1cf8}', '\u{1cf9}', GC_Extend), ('\u{1dc0}', '\u{1df5}', GC_Extend), ('\u{1dfc}',
+        '\u{1dff}', GC_Extend), ('\u{200b}', '\u{200b}', GC_Control), ('\u{200c}', '\u{200d}',
+        GC_Extend), ('\u{200e}', '\u{200f}', GC_Control), ('\u{2028}', '\u{202e}', GC_Control),
+        ('\u{2060}', '\u{206f}', GC_Control), ('\u{20d0}', '\u{20dc}', GC_Extend), ('\u{20dd}',
+        '\u{20e0}', GC_Extend), ('\u{20e1}', '\u{20e1}', GC_Extend), ('\u{20e2}', '\u{20e4}',
+        GC_Extend), ('\u{20e5}', '\u{20f0}', GC_Extend), ('\u{2cef}', '\u{2cf1}', GC_Extend),
+        ('\u{2d7f}', '\u{2d7f}', GC_Extend), ('\u{2de0}', '\u{2dff}', GC_Extend), ('\u{302a}',
+        '\u{302d}', GC_Extend), ('\u{302e}', '\u{302f}', GC_Extend), ('\u{3099}', '\u{309a}',
+        GC_Extend), ('\u{a66f}', '\u{a66f}', GC_Extend), ('\u{a670}', '\u{a672}', GC_Extend),
+        ('\u{a674}', '\u{a67d}', GC_Extend), ('\u{a69f}', '\u{a69f}', GC_Extend), ('\u{a6f0}',
+        '\u{a6f1}', GC_Extend), ('\u{a802}', '\u{a802}', GC_Extend), ('\u{a806}', '\u{a806}',
+        GC_Extend), ('\u{a80b}', '\u{a80b}', GC_Extend), ('\u{a823}', '\u{a824}', GC_SpacingMark),
+        ('\u{a825}', '\u{a826}', GC_Extend), ('\u{a827}', '\u{a827}', GC_SpacingMark), ('\u{a880}',
+        '\u{a881}', GC_SpacingMark), ('\u{a8b4}', '\u{a8c3}', GC_SpacingMark), ('\u{a8c4}',
+        '\u{a8c4}', GC_Extend), ('\u{a8e0}', '\u{a8f1}', GC_Extend), ('\u{a926}', '\u{a92d}',
+        GC_Extend), ('\u{a947}', '\u{a951}', GC_Extend), ('\u{a952}', '\u{a953}', GC_SpacingMark),
+        ('\u{a960}', '\u{a97c}', GC_L), ('\u{a980}', '\u{a982}', GC_Extend), ('\u{a983}',
+        '\u{a983}', GC_SpacingMark), ('\u{a9b3}', '\u{a9b3}', GC_Extend), ('\u{a9b4}', '\u{a9b5}',
+        GC_SpacingMark), ('\u{a9b6}', '\u{a9b9}', GC_Extend), ('\u{a9ba}', '\u{a9bb}',
+        GC_SpacingMark), ('\u{a9bc}', '\u{a9bc}', GC_Extend), ('\u{a9bd}', '\u{a9c0}',
+        GC_SpacingMark), ('\u{a9e5}', '\u{a9e5}', GC_Extend), ('\u{aa29}', '\u{aa2e}', GC_Extend),
+        ('\u{aa2f}', '\u{aa30}', GC_SpacingMark), ('\u{aa31}', '\u{aa32}', GC_Extend), ('\u{aa33}',
+        '\u{aa34}', GC_SpacingMark), ('\u{aa35}', '\u{aa36}', GC_Extend), ('\u{aa43}', '\u{aa43}',
+        GC_Extend), ('\u{aa4c}', '\u{aa4c}', GC_Extend), ('\u{aa4d}', '\u{aa4d}', GC_SpacingMark),
+        ('\u{aa7c}', '\u{aa7c}', GC_Extend), ('\u{aab0}', '\u{aab0}', GC_Extend), ('\u{aab2}',
+        '\u{aab4}', GC_Extend), ('\u{aab7}', '\u{aab8}', GC_Extend), ('\u{aabe}', '\u{aabf}',
+        GC_Extend), ('\u{aac1}', '\u{aac1}', GC_Extend), ('\u{aaeb}', '\u{aaeb}', GC_SpacingMark),
+        ('\u{aaec}', '\u{aaed}', GC_Extend), ('\u{aaee}', '\u{aaef}', GC_SpacingMark), ('\u{aaf5}',
+        '\u{aaf5}', GC_SpacingMark), ('\u{aaf6}', '\u{aaf6}', GC_Extend), ('\u{abe3}', '\u{abe4}',
+        GC_SpacingMark), ('\u{abe5}', '\u{abe5}', GC_Extend), ('\u{abe6}', '\u{abe7}',
+        GC_SpacingMark), ('\u{abe8}', '\u{abe8}', GC_Extend), ('\u{abe9}', '\u{abea}',
+        GC_SpacingMark), ('\u{abec}', '\u{abec}', GC_SpacingMark), ('\u{abed}', '\u{abed}',
+        GC_Extend), ('\u{ac00}', '\u{ac00}', GC_LV), ('\u{ac01}', '\u{ac1b}', GC_LVT), ('\u{ac1c}',
+        '\u{ac1c}', GC_LV), ('\u{ac1d}', '\u{ac37}', GC_LVT), ('\u{ac38}', '\u{ac38}', GC_LV),
+        ('\u{ac39}', '\u{ac53}', GC_LVT), ('\u{ac54}', '\u{ac54}', GC_LV), ('\u{ac55}', '\u{ac6f}',
+        GC_LVT), ('\u{ac70}', '\u{ac70}', GC_LV), ('\u{ac71}', '\u{ac8b}', GC_LVT), ('\u{ac8c}',
+        '\u{ac8c}', GC_LV), ('\u{ac8d}', '\u{aca7}', GC_LVT), ('\u{aca8}', '\u{aca8}', GC_LV),
+        ('\u{aca9}', '\u{acc3}', GC_LVT), ('\u{acc4}', '\u{acc4}', GC_LV), ('\u{acc5}', '\u{acdf}',
+        GC_LVT), ('\u{ace0}', '\u{ace0}', GC_LV), ('\u{ace1}', '\u{acfb}', GC_LVT), ('\u{acfc}',
+        '\u{acfc}', GC_LV), ('\u{acfd}', '\u{ad17}', GC_LVT), ('\u{ad18}', '\u{ad18}', GC_LV),
+        ('\u{ad19}', '\u{ad33}', GC_LVT), ('\u{ad34}', '\u{ad34}', GC_LV), ('\u{ad35}', '\u{ad4f}',
+        GC_LVT), ('\u{ad50}', '\u{ad50}', GC_LV), ('\u{ad51}', '\u{ad6b}', GC_LVT), ('\u{ad6c}',
+        '\u{ad6c}', GC_LV), ('\u{ad6d}', '\u{ad87}', GC_LVT), ('\u{ad88}', '\u{ad88}', GC_LV),
+        ('\u{ad89}', '\u{ada3}', GC_LVT), ('\u{ada4}', '\u{ada4}', GC_LV), ('\u{ada5}', '\u{adbf}',
+        GC_LVT), ('\u{adc0}', '\u{adc0}', GC_LV), ('\u{adc1}', '\u{addb}', GC_LVT), ('\u{addc}',
+        '\u{addc}', GC_LV), ('\u{addd}', '\u{adf7}', GC_LVT), ('\u{adf8}', '\u{adf8}', GC_LV),
+        ('\u{adf9}', '\u{ae13}', GC_LVT), ('\u{ae14}', '\u{ae14}', GC_LV), ('\u{ae15}', '\u{ae2f}',
+        GC_LVT), ('\u{ae30}', '\u{ae30}', GC_LV), ('\u{ae31}', '\u{ae4b}', GC_LVT), ('\u{ae4c}',
+        '\u{ae4c}', GC_LV), ('\u{ae4d}', '\u{ae67}', GC_LVT), ('\u{ae68}', '\u{ae68}', GC_LV),
+        ('\u{ae69}', '\u{ae83}', GC_LVT), ('\u{ae84}', '\u{ae84}', GC_LV), ('\u{ae85}', '\u{ae9f}',
+        GC_LVT), ('\u{aea0}', '\u{aea0}', GC_LV), ('\u{aea1}', '\u{aebb}', GC_LVT), ('\u{aebc}',
+        '\u{aebc}', GC_LV), ('\u{aebd}', '\u{aed7}', GC_LVT), ('\u{aed8}', '\u{aed8}', GC_LV),
+        ('\u{aed9}', '\u{aef3}', GC_LVT), ('\u{aef4}', '\u{aef4}', GC_LV), ('\u{aef5}', '\u{af0f}',
+        GC_LVT), ('\u{af10}', '\u{af10}', GC_LV), ('\u{af11}', '\u{af2b}', GC_LVT), ('\u{af2c}',
+        '\u{af2c}', GC_LV), ('\u{af2d}', '\u{af47}', GC_LVT), ('\u{af48}', '\u{af48}', GC_LV),
+        ('\u{af49}', '\u{af63}', GC_LVT), ('\u{af64}', '\u{af64}', GC_LV), ('\u{af65}', '\u{af7f}',
+        GC_LVT), ('\u{af80}', '\u{af80}', GC_LV), ('\u{af81}', '\u{af9b}', GC_LVT), ('\u{af9c}',
+        '\u{af9c}', GC_LV), ('\u{af9d}', '\u{afb7}', GC_LVT), ('\u{afb8}', '\u{afb8}', GC_LV),
+        ('\u{afb9}', '\u{afd3}', GC_LVT), ('\u{afd4}', '\u{afd4}', GC_LV), ('\u{afd5}', '\u{afef}',
+        GC_LVT), ('\u{aff0}', '\u{aff0}', GC_LV), ('\u{aff1}', '\u{b00b}', GC_LVT), ('\u{b00c}',
+        '\u{b00c}', GC_LV), ('\u{b00d}', '\u{b027}', GC_LVT), ('\u{b028}', '\u{b028}', GC_LV),
+        ('\u{b029}', '\u{b043}', GC_LVT), ('\u{b044}', '\u{b044}', GC_LV), ('\u{b045}', '\u{b05f}',
+        GC_LVT), ('\u{b060}', '\u{b060}', GC_LV), ('\u{b061}', '\u{b07b}', GC_LVT), ('\u{b07c}',
+        '\u{b07c}', GC_LV), ('\u{b07d}', '\u{b097}', GC_LVT), ('\u{b098}', '\u{b098}', GC_LV),
+        ('\u{b099}', '\u{b0b3}', GC_LVT), ('\u{b0b4}', '\u{b0b4}', GC_LV), ('\u{b0b5}', '\u{b0cf}',
+        GC_LVT), ('\u{b0d0}', '\u{b0d0}', GC_LV), ('\u{b0d1}', '\u{b0eb}', GC_LVT), ('\u{b0ec}',
+        '\u{b0ec}', GC_LV), ('\u{b0ed}', '\u{b107}', GC_LVT), ('\u{b108}', '\u{b108}', GC_LV),
+        ('\u{b109}', '\u{b123}', GC_LVT), ('\u{b124}', '\u{b124}', GC_LV), ('\u{b125}', '\u{b13f}',
+        GC_LVT), ('\u{b140}', '\u{b140}', GC_LV), ('\u{b141}', '\u{b15b}', GC_LVT), ('\u{b15c}',
+        '\u{b15c}', GC_LV), ('\u{b15d}', '\u{b177}', GC_LVT), ('\u{b178}', '\u{b178}', GC_LV),
+        ('\u{b179}', '\u{b193}', GC_LVT), ('\u{b194}', '\u{b194}', GC_LV), ('\u{b195}', '\u{b1af}',
+        GC_LVT), ('\u{b1b0}', '\u{b1b0}', GC_LV), ('\u{b1b1}', '\u{b1cb}', GC_LVT), ('\u{b1cc}',
+        '\u{b1cc}', GC_LV), ('\u{b1cd}', '\u{b1e7}', GC_LVT), ('\u{b1e8}', '\u{b1e8}', GC_LV),
+        ('\u{b1e9}', '\u{b203}', GC_LVT), ('\u{b204}', '\u{b204}', GC_LV), ('\u{b205}', '\u{b21f}',
+        GC_LVT), ('\u{b220}', '\u{b220}', GC_LV), ('\u{b221}', '\u{b23b}', GC_LVT), ('\u{b23c}',
+        '\u{b23c}', GC_LV), ('\u{b23d}', '\u{b257}', GC_LVT), ('\u{b258}', '\u{b258}', GC_LV),
+        ('\u{b259}', '\u{b273}', GC_LVT), ('\u{b274}', '\u{b274}', GC_LV), ('\u{b275}', '\u{b28f}',
+        GC_LVT), ('\u{b290}', '\u{b290}', GC_LV), ('\u{b291}', '\u{b2ab}', GC_LVT), ('\u{b2ac}',
+        '\u{b2ac}', GC_LV), ('\u{b2ad}', '\u{b2c7}', GC_LVT), ('\u{b2c8}', '\u{b2c8}', GC_LV),
+        ('\u{b2c9}', '\u{b2e3}', GC_LVT), ('\u{b2e4}', '\u{b2e4}', GC_LV), ('\u{b2e5}', '\u{b2ff}',
+        GC_LVT), ('\u{b300}', '\u{b300}', GC_LV), ('\u{b301}', '\u{b31b}', GC_LVT), ('\u{b31c}',
+        '\u{b31c}', GC_LV), ('\u{b31d}', '\u{b337}', GC_LVT), ('\u{b338}', '\u{b338}', GC_LV),
+        ('\u{b339}', '\u{b353}', GC_LVT), ('\u{b354}', '\u{b354}', GC_LV), ('\u{b355}', '\u{b36f}',
+        GC_LVT), ('\u{b370}', '\u{b370}', GC_LV), ('\u{b371}', '\u{b38b}', GC_LVT), ('\u{b38c}',
+        '\u{b38c}', GC_LV), ('\u{b38d}', '\u{b3a7}', GC_LVT), ('\u{b3a8}', '\u{b3a8}', GC_LV),
+        ('\u{b3a9}', '\u{b3c3}', GC_LVT), ('\u{b3c4}', '\u{b3c4}', GC_LV), ('\u{b3c5}', '\u{b3df}',
+        GC_LVT), ('\u{b3e0}', '\u{b3e0}', GC_LV), ('\u{b3e1}', '\u{b3fb}', GC_LVT), ('\u{b3fc}',
+        '\u{b3fc}', GC_LV), ('\u{b3fd}', '\u{b417}', GC_LVT), ('\u{b418}', '\u{b418}', GC_LV),
+        ('\u{b419}', '\u{b433}', GC_LVT), ('\u{b434}', '\u{b434}', GC_LV), ('\u{b435}', '\u{b44f}',
+        GC_LVT), ('\u{b450}', '\u{b450}', GC_LV), ('\u{b451}', '\u{b46b}', GC_LVT), ('\u{b46c}',
+        '\u{b46c}', GC_LV), ('\u{b46d}', '\u{b487}', GC_LVT), ('\u{b488}', '\u{b488}', GC_LV),
+        ('\u{b489}', '\u{b4a3}', GC_LVT), ('\u{b4a4}', '\u{b4a4}', GC_LV), ('\u{b4a5}', '\u{b4bf}',
+        GC_LVT), ('\u{b4c0}', '\u{b4c0}', GC_LV), ('\u{b4c1}', '\u{b4db}', GC_LVT), ('\u{b4dc}',
+        '\u{b4dc}', GC_LV), ('\u{b4dd}', '\u{b4f7}', GC_LVT), ('\u{b4f8}', '\u{b4f8}', GC_LV),
+        ('\u{b4f9}', '\u{b513}', GC_LVT), ('\u{b514}', '\u{b514}', GC_LV), ('\u{b515}', '\u{b52f}',
+        GC_LVT), ('\u{b530}', '\u{b530}', GC_LV), ('\u{b531}', '\u{b54b}', GC_LVT), ('\u{b54c}',
+        '\u{b54c}', GC_LV), ('\u{b54d}', '\u{b567}', GC_LVT), ('\u{b568}', '\u{b568}', GC_LV),
+        ('\u{b569}', '\u{b583}', GC_LVT), ('\u{b584}', '\u{b584}', GC_LV), ('\u{b585}', '\u{b59f}',
+        GC_LVT), ('\u{b5a0}', '\u{b5a0}', GC_LV), ('\u{b5a1}', '\u{b5bb}', GC_LVT), ('\u{b5bc}',
+        '\u{b5bc}', GC_LV), ('\u{b5bd}', '\u{b5d7}', GC_LVT), ('\u{b5d8}', '\u{b5d8}', GC_LV),
+        ('\u{b5d9}', '\u{b5f3}', GC_LVT), ('\u{b5f4}', '\u{b5f4}', GC_LV), ('\u{b5f5}', '\u{b60f}',
+        GC_LVT), ('\u{b610}', '\u{b610}', GC_LV), ('\u{b611}', '\u{b62b}', GC_LVT), ('\u{b62c}',
+        '\u{b62c}', GC_LV), ('\u{b62d}', '\u{b647}', GC_LVT), ('\u{b648}', '\u{b648}', GC_LV),
+        ('\u{b649}', '\u{b663}', GC_LVT), ('\u{b664}', '\u{b664}', GC_LV), ('\u{b665}', '\u{b67f}',
+        GC_LVT), ('\u{b680}', '\u{b680}', GC_LV), ('\u{b681}', '\u{b69b}', GC_LVT), ('\u{b69c}',
+        '\u{b69c}', GC_LV), ('\u{b69d}', '\u{b6b7}', GC_LVT), ('\u{b6b8}', '\u{b6b8}', GC_LV),
+        ('\u{b6b9}', '\u{b6d3}', GC_LVT), ('\u{b6d4}', '\u{b6d4}', GC_LV), ('\u{b6d5}', '\u{b6ef}',
+        GC_LVT), ('\u{b6f0}', '\u{b6f0}', GC_LV), ('\u{b6f1}', '\u{b70b}', GC_LVT), ('\u{b70c}',
+        '\u{b70c}', GC_LV), ('\u{b70d}', '\u{b727}', GC_LVT), ('\u{b728}', '\u{b728}', GC_LV),
+        ('\u{b729}', '\u{b743}', GC_LVT), ('\u{b744}', '\u{b744}', GC_LV), ('\u{b745}', '\u{b75f}',
+        GC_LVT), ('\u{b760}', '\u{b760}', GC_LV), ('\u{b761}', '\u{b77b}', GC_LVT), ('\u{b77c}',
+        '\u{b77c}', GC_LV), ('\u{b77d}', '\u{b797}', GC_LVT), ('\u{b798}', '\u{b798}', GC_LV),
+        ('\u{b799}', '\u{b7b3}', GC_LVT), ('\u{b7b4}', '\u{b7b4}', GC_LV), ('\u{b7b5}', '\u{b7cf}',
+        GC_LVT), ('\u{b7d0}', '\u{b7d0}', GC_LV), ('\u{b7d1}', '\u{b7eb}', GC_LVT), ('\u{b7ec}',
+        '\u{b7ec}', GC_LV), ('\u{b7ed}', '\u{b807}', GC_LVT), ('\u{b808}', '\u{b808}', GC_LV),
+        ('\u{b809}', '\u{b823}', GC_LVT), ('\u{b824}', '\u{b824}', GC_LV), ('\u{b825}', '\u{b83f}',
+        GC_LVT), ('\u{b840}', '\u{b840}', GC_LV), ('\u{b841}', '\u{b85b}', GC_LVT), ('\u{b85c}',
+        '\u{b85c}', GC_LV), ('\u{b85d}', '\u{b877}', GC_LVT), ('\u{b878}', '\u{b878}', GC_LV),
+        ('\u{b879}', '\u{b893}', GC_LVT), ('\u{b894}', '\u{b894}', GC_LV), ('\u{b895}', '\u{b8af}',
+        GC_LVT), ('\u{b8b0}', '\u{b8b0}', GC_LV), ('\u{b8b1}', '\u{b8cb}', GC_LVT), ('\u{b8cc}',
+        '\u{b8cc}', GC_LV), ('\u{b8cd}', '\u{b8e7}', GC_LVT), ('\u{b8e8}', '\u{b8e8}', GC_LV),
+        ('\u{b8e9}', '\u{b903}', GC_LVT), ('\u{b904}', '\u{b904}', GC_LV), ('\u{b905}', '\u{b91f}',
+        GC_LVT), ('\u{b920}', '\u{b920}', GC_LV), ('\u{b921}', '\u{b93b}', GC_LVT), ('\u{b93c}',
+        '\u{b93c}', GC_LV), ('\u{b93d}', '\u{b957}', GC_LVT), ('\u{b958}', '\u{b958}', GC_LV),
+        ('\u{b959}', '\u{b973}', GC_LVT), ('\u{b974}', '\u{b974}', GC_LV), ('\u{b975}', '\u{b98f}',
+        GC_LVT), ('\u{b990}', '\u{b990}', GC_LV), ('\u{b991}', '\u{b9ab}', GC_LVT), ('\u{b9ac}',
+        '\u{b9ac}', GC_LV), ('\u{b9ad}', '\u{b9c7}', GC_LVT), ('\u{b9c8}', '\u{b9c8}', GC_LV),
+        ('\u{b9c9}', '\u{b9e3}', GC_LVT), ('\u{b9e4}', '\u{b9e4}', GC_LV), ('\u{b9e5}', '\u{b9ff}',
+        GC_LVT), ('\u{ba00}', '\u{ba00}', GC_LV), ('\u{ba01}', '\u{ba1b}', GC_LVT), ('\u{ba1c}',
+        '\u{ba1c}', GC_LV), ('\u{ba1d}', '\u{ba37}', GC_LVT), ('\u{ba38}', '\u{ba38}', GC_LV),
+        ('\u{ba39}', '\u{ba53}', GC_LVT), ('\u{ba54}', '\u{ba54}', GC_LV), ('\u{ba55}', '\u{ba6f}',
+        GC_LVT), ('\u{ba70}', '\u{ba70}', GC_LV), ('\u{ba71}', '\u{ba8b}', GC_LVT), ('\u{ba8c}',
+        '\u{ba8c}', GC_LV), ('\u{ba8d}', '\u{baa7}', GC_LVT), ('\u{baa8}', '\u{baa8}', GC_LV),
+        ('\u{baa9}', '\u{bac3}', GC_LVT), ('\u{bac4}', '\u{bac4}', GC_LV), ('\u{bac5}', '\u{badf}',
+        GC_LVT), ('\u{bae0}', '\u{bae0}', GC_LV), ('\u{bae1}', '\u{bafb}', GC_LVT), ('\u{bafc}',
+        '\u{bafc}', GC_LV), ('\u{bafd}', '\u{bb17}', GC_LVT), ('\u{bb18}', '\u{bb18}', GC_LV),
+        ('\u{bb19}', '\u{bb33}', GC_LVT), ('\u{bb34}', '\u{bb34}', GC_LV), ('\u{bb35}', '\u{bb4f}',
+        GC_LVT), ('\u{bb50}', '\u{bb50}', GC_LV), ('\u{bb51}', '\u{bb6b}', GC_LVT), ('\u{bb6c}',
+        '\u{bb6c}', GC_LV), ('\u{bb6d}', '\u{bb87}', GC_LVT), ('\u{bb88}', '\u{bb88}', GC_LV),
+        ('\u{bb89}', '\u{bba3}', GC_LVT), ('\u{bba4}', '\u{bba4}', GC_LV), ('\u{bba5}', '\u{bbbf}',
+        GC_LVT), ('\u{bbc0}', '\u{bbc0}', GC_LV), ('\u{bbc1}', '\u{bbdb}', GC_LVT), ('\u{bbdc}',
+        '\u{bbdc}', GC_LV), ('\u{bbdd}', '\u{bbf7}', GC_LVT), ('\u{bbf8}', '\u{bbf8}', GC_LV),
+        ('\u{bbf9}', '\u{bc13}', GC_LVT), ('\u{bc14}', '\u{bc14}', GC_LV), ('\u{bc15}', '\u{bc2f}',
+        GC_LVT), ('\u{bc30}', '\u{bc30}', GC_LV), ('\u{bc31}', '\u{bc4b}', GC_LVT), ('\u{bc4c}',
+        '\u{bc4c}', GC_LV), ('\u{bc4d}', '\u{bc67}', GC_LVT), ('\u{bc68}', '\u{bc68}', GC_LV),
+        ('\u{bc69}', '\u{bc83}', GC_LVT), ('\u{bc84}', '\u{bc84}', GC_LV), ('\u{bc85}', '\u{bc9f}',
+        GC_LVT), ('\u{bca0}', '\u{bca0}', GC_LV), ('\u{bca1}', '\u{bcbb}', GC_LVT), ('\u{bcbc}',
+        '\u{bcbc}', GC_LV), ('\u{bcbd}', '\u{bcd7}', GC_LVT), ('\u{bcd8}', '\u{bcd8}', GC_LV),
+        ('\u{bcd9}', '\u{bcf3}', GC_LVT), ('\u{bcf4}', '\u{bcf4}', GC_LV), ('\u{bcf5}', '\u{bd0f}',
+        GC_LVT), ('\u{bd10}', '\u{bd10}', GC_LV), ('\u{bd11}', '\u{bd2b}', GC_LVT), ('\u{bd2c}',
+        '\u{bd2c}', GC_LV), ('\u{bd2d}', '\u{bd47}', GC_LVT), ('\u{bd48}', '\u{bd48}', GC_LV),
+        ('\u{bd49}', '\u{bd63}', GC_LVT), ('\u{bd64}', '\u{bd64}', GC_LV), ('\u{bd65}', '\u{bd7f}',
+        GC_LVT), ('\u{bd80}', '\u{bd80}', GC_LV), ('\u{bd81}', '\u{bd9b}', GC_LVT), ('\u{bd9c}',
+        '\u{bd9c}', GC_LV), ('\u{bd9d}', '\u{bdb7}', GC_LVT), ('\u{bdb8}', '\u{bdb8}', GC_LV),
+        ('\u{bdb9}', '\u{bdd3}', GC_LVT), ('\u{bdd4}', '\u{bdd4}', GC_LV), ('\u{bdd5}', '\u{bdef}',
+        GC_LVT), ('\u{bdf0}', '\u{bdf0}', GC_LV), ('\u{bdf1}', '\u{be0b}', GC_LVT), ('\u{be0c}',
+        '\u{be0c}', GC_LV), ('\u{be0d}', '\u{be27}', GC_LVT), ('\u{be28}', '\u{be28}', GC_LV),
+        ('\u{be29}', '\u{be43}', GC_LVT), ('\u{be44}', '\u{be44}', GC_LV), ('\u{be45}', '\u{be5f}',
+        GC_LVT), ('\u{be60}', '\u{be60}', GC_LV), ('\u{be61}', '\u{be7b}', GC_LVT), ('\u{be7c}',
+        '\u{be7c}', GC_LV), ('\u{be7d}', '\u{be97}', GC_LVT), ('\u{be98}', '\u{be98}', GC_LV),
+        ('\u{be99}', '\u{beb3}', GC_LVT), ('\u{beb4}', '\u{beb4}', GC_LV), ('\u{beb5}', '\u{becf}',
+        GC_LVT), ('\u{bed0}', '\u{bed0}', GC_LV), ('\u{bed1}', '\u{beeb}', GC_LVT), ('\u{beec}',
+        '\u{beec}', GC_LV), ('\u{beed}', '\u{bf07}', GC_LVT), ('\u{bf08}', '\u{bf08}', GC_LV),
+        ('\u{bf09}', '\u{bf23}', GC_LVT), ('\u{bf24}', '\u{bf24}', GC_LV), ('\u{bf25}', '\u{bf3f}',
+        GC_LVT), ('\u{bf40}', '\u{bf40}', GC_LV), ('\u{bf41}', '\u{bf5b}', GC_LVT), ('\u{bf5c}',
+        '\u{bf5c}', GC_LV), ('\u{bf5d}', '\u{bf77}', GC_LVT), ('\u{bf78}', '\u{bf78}', GC_LV),
+        ('\u{bf79}', '\u{bf93}', GC_LVT), ('\u{bf94}', '\u{bf94}', GC_LV), ('\u{bf95}', '\u{bfaf}',
+        GC_LVT), ('\u{bfb0}', '\u{bfb0}', GC_LV), ('\u{bfb1}', '\u{bfcb}', GC_LVT), ('\u{bfcc}',
+        '\u{bfcc}', GC_LV), ('\u{bfcd}', '\u{bfe7}', GC_LVT), ('\u{bfe8}', '\u{bfe8}', GC_LV),
+        ('\u{bfe9}', '\u{c003}', GC_LVT), ('\u{c004}', '\u{c004}', GC_LV), ('\u{c005}', '\u{c01f}',
+        GC_LVT), ('\u{c020}', '\u{c020}', GC_LV), ('\u{c021}', '\u{c03b}', GC_LVT), ('\u{c03c}',
+        '\u{c03c}', GC_LV), ('\u{c03d}', '\u{c057}', GC_LVT), ('\u{c058}', '\u{c058}', GC_LV),
+        ('\u{c059}', '\u{c073}', GC_LVT), ('\u{c074}', '\u{c074}', GC_LV), ('\u{c075}', '\u{c08f}',
+        GC_LVT), ('\u{c090}', '\u{c090}', GC_LV), ('\u{c091}', '\u{c0ab}', GC_LVT), ('\u{c0ac}',
+        '\u{c0ac}', GC_LV), ('\u{c0ad}', '\u{c0c7}', GC_LVT), ('\u{c0c8}', '\u{c0c8}', GC_LV),
+        ('\u{c0c9}', '\u{c0e3}', GC_LVT), ('\u{c0e4}', '\u{c0e4}', GC_LV), ('\u{c0e5}', '\u{c0ff}',
+        GC_LVT), ('\u{c100}', '\u{c100}', GC_LV), ('\u{c101}', '\u{c11b}', GC_LVT), ('\u{c11c}',
+        '\u{c11c}', GC_LV), ('\u{c11d}', '\u{c137}', GC_LVT), ('\u{c138}', '\u{c138}', GC_LV),
+        ('\u{c139}', '\u{c153}', GC_LVT), ('\u{c154}', '\u{c154}', GC_LV), ('\u{c155}', '\u{c16f}',
+        GC_LVT), ('\u{c170}', '\u{c170}', GC_LV), ('\u{c171}', '\u{c18b}', GC_LVT), ('\u{c18c}',
+        '\u{c18c}', GC_LV), ('\u{c18d}', '\u{c1a7}', GC_LVT), ('\u{c1a8}', '\u{c1a8}', GC_LV),
+        ('\u{c1a9}', '\u{c1c3}', GC_LVT), ('\u{c1c4}', '\u{c1c4}', GC_LV), ('\u{c1c5}', '\u{c1df}',
+        GC_LVT), ('\u{c1e0}', '\u{c1e0}', GC_LV), ('\u{c1e1}', '\u{c1fb}', GC_LVT), ('\u{c1fc}',
+        '\u{c1fc}', GC_LV), ('\u{c1fd}', '\u{c217}', GC_LVT), ('\u{c218}', '\u{c218}', GC_LV),
+        ('\u{c219}', '\u{c233}', GC_LVT), ('\u{c234}', '\u{c234}', GC_LV), ('\u{c235}', '\u{c24f}',
+        GC_LVT), ('\u{c250}', '\u{c250}', GC_LV), ('\u{c251}', '\u{c26b}', GC_LVT), ('\u{c26c}',
+        '\u{c26c}', GC_LV), ('\u{c26d}', '\u{c287}', GC_LVT), ('\u{c288}', '\u{c288}', GC_LV),
+        ('\u{c289}', '\u{c2a3}', GC_LVT), ('\u{c2a4}', '\u{c2a4}', GC_LV), ('\u{c2a5}', '\u{c2bf}',
+        GC_LVT), ('\u{c2c0}', '\u{c2c0}', GC_LV), ('\u{c2c1}', '\u{c2db}', GC_LVT), ('\u{c2dc}',
+        '\u{c2dc}', GC_LV), ('\u{c2dd}', '\u{c2f7}', GC_LVT), ('\u{c2f8}', '\u{c2f8}', GC_LV),
+        ('\u{c2f9}', '\u{c313}', GC_LVT), ('\u{c314}', '\u{c314}', GC_LV), ('\u{c315}', '\u{c32f}',
+        GC_LVT), ('\u{c330}', '\u{c330}', GC_LV), ('\u{c331}', '\u{c34b}', GC_LVT), ('\u{c34c}',
+        '\u{c34c}', GC_LV), ('\u{c34d}', '\u{c367}', GC_LVT), ('\u{c368}', '\u{c368}', GC_LV),
+        ('\u{c369}', '\u{c383}', GC_LVT), ('\u{c384}', '\u{c384}', GC_LV), ('\u{c385}', '\u{c39f}',
+        GC_LVT), ('\u{c3a0}', '\u{c3a0}', GC_LV), ('\u{c3a1}', '\u{c3bb}', GC_LVT), ('\u{c3bc}',
+        '\u{c3bc}', GC_LV), ('\u{c3bd}', '\u{c3d7}', GC_LVT), ('\u{c3d8}', '\u{c3d8}', GC_LV),
+        ('\u{c3d9}', '\u{c3f3}', GC_LVT), ('\u{c3f4}', '\u{c3f4}', GC_LV), ('\u{c3f5}', '\u{c40f}',
+        GC_LVT), ('\u{c410}', '\u{c410}', GC_LV), ('\u{c411}', '\u{c42b}', GC_LVT), ('\u{c42c}',
+        '\u{c42c}', GC_LV), ('\u{c42d}', '\u{c447}', GC_LVT), ('\u{c448}', '\u{c448}', GC_LV),
+        ('\u{c449}', '\u{c463}', GC_LVT), ('\u{c464}', '\u{c464}', GC_LV), ('\u{c465}', '\u{c47f}',
+        GC_LVT), ('\u{c480}', '\u{c480}', GC_LV), ('\u{c481}', '\u{c49b}', GC_LVT), ('\u{c49c}',
+        '\u{c49c}', GC_LV), ('\u{c49d}', '\u{c4b7}', GC_LVT), ('\u{c4b8}', '\u{c4b8}', GC_LV),
+        ('\u{c4b9}', '\u{c4d3}', GC_LVT), ('\u{c4d4}', '\u{c4d4}', GC_LV), ('\u{c4d5}', '\u{c4ef}',
+        GC_LVT), ('\u{c4f0}', '\u{c4f0}', GC_LV), ('\u{c4f1}', '\u{c50b}', GC_LVT), ('\u{c50c}',
+        '\u{c50c}', GC_LV), ('\u{c50d}', '\u{c527}', GC_LVT), ('\u{c528}', '\u{c528}', GC_LV),
+        ('\u{c529}', '\u{c543}', GC_LVT), ('\u{c544}', '\u{c544}', GC_LV), ('\u{c545}', '\u{c55f}',
+        GC_LVT), ('\u{c560}', '\u{c560}', GC_LV), ('\u{c561}', '\u{c57b}', GC_LVT), ('\u{c57c}',
+        '\u{c57c}', GC_LV), ('\u{c57d}', '\u{c597}', GC_LVT), ('\u{c598}', '\u{c598}', GC_LV),
+        ('\u{c599}', '\u{c5b3}', GC_LVT), ('\u{c5b4}', '\u{c5b4}', GC_LV), ('\u{c5b5}', '\u{c5cf}',
+        GC_LVT), ('\u{c5d0}', '\u{c5d0}', GC_LV), ('\u{c5d1}', '\u{c5eb}', GC_LVT), ('\u{c5ec}',
+        '\u{c5ec}', GC_LV), ('\u{c5ed}', '\u{c607}', GC_LVT), ('\u{c608}', '\u{c608}', GC_LV),
+        ('\u{c609}', '\u{c623}', GC_LVT), ('\u{c624}', '\u{c624}', GC_LV), ('\u{c625}', '\u{c63f}',
+        GC_LVT), ('\u{c640}', '\u{c640}', GC_LV), ('\u{c641}', '\u{c65b}', GC_LVT), ('\u{c65c}',
+        '\u{c65c}', GC_LV), ('\u{c65d}', '\u{c677}', GC_LVT), ('\u{c678}', '\u{c678}', GC_LV),
+        ('\u{c679}', '\u{c693}', GC_LVT), ('\u{c694}', '\u{c694}', GC_LV), ('\u{c695}', '\u{c6af}',
+        GC_LVT), ('\u{c6b0}', '\u{c6b0}', GC_LV), ('\u{c6b1}', '\u{c6cb}', GC_LVT), ('\u{c6cc}',
+        '\u{c6cc}', GC_LV), ('\u{c6cd}', '\u{c6e7}', GC_LVT), ('\u{c6e8}', '\u{c6e8}', GC_LV),
+        ('\u{c6e9}', '\u{c703}', GC_LVT), ('\u{c704}', '\u{c704}', GC_LV), ('\u{c705}', '\u{c71f}',
+        GC_LVT), ('\u{c720}', '\u{c720}', GC_LV), ('\u{c721}', '\u{c73b}', GC_LVT), ('\u{c73c}',
+        '\u{c73c}', GC_LV), ('\u{c73d}', '\u{c757}', GC_LVT), ('\u{c758}', '\u{c758}', GC_LV),
+        ('\u{c759}', '\u{c773}', GC_LVT), ('\u{c774}', '\u{c774}', GC_LV), ('\u{c775}', '\u{c78f}',
+        GC_LVT), ('\u{c790}', '\u{c790}', GC_LV), ('\u{c791}', '\u{c7ab}', GC_LVT), ('\u{c7ac}',
+        '\u{c7ac}', GC_LV), ('\u{c7ad}', '\u{c7c7}', GC_LVT), ('\u{c7c8}', '\u{c7c8}', GC_LV),
+        ('\u{c7c9}', '\u{c7e3}', GC_LVT), ('\u{c7e4}', '\u{c7e4}', GC_LV), ('\u{c7e5}', '\u{c7ff}',
+        GC_LVT), ('\u{c800}', '\u{c800}', GC_LV), ('\u{c801}', '\u{c81b}', GC_LVT), ('\u{c81c}',
+        '\u{c81c}', GC_LV), ('\u{c81d}', '\u{c837}', GC_LVT), ('\u{c838}', '\u{c838}', GC_LV),
+        ('\u{c839}', '\u{c853}', GC_LVT), ('\u{c854}', '\u{c854}', GC_LV), ('\u{c855}', '\u{c86f}',
+        GC_LVT), ('\u{c870}', '\u{c870}', GC_LV), ('\u{c871}', '\u{c88b}', GC_LVT), ('\u{c88c}',
+        '\u{c88c}', GC_LV), ('\u{c88d}', '\u{c8a7}', GC_LVT), ('\u{c8a8}', '\u{c8a8}', GC_LV),
+        ('\u{c8a9}', '\u{c8c3}', GC_LVT), ('\u{c8c4}', '\u{c8c4}', GC_LV), ('\u{c8c5}', '\u{c8df}',
+        GC_LVT), ('\u{c8e0}', '\u{c8e0}', GC_LV), ('\u{c8e1}', '\u{c8fb}', GC_LVT), ('\u{c8fc}',
+        '\u{c8fc}', GC_LV), ('\u{c8fd}', '\u{c917}', GC_LVT), ('\u{c918}', '\u{c918}', GC_LV),
+        ('\u{c919}', '\u{c933}', GC_LVT), ('\u{c934}', '\u{c934}', GC_LV), ('\u{c935}', '\u{c94f}',
+        GC_LVT), ('\u{c950}', '\u{c950}', GC_LV), ('\u{c951}', '\u{c96b}', GC_LVT), ('\u{c96c}',
+        '\u{c96c}', GC_LV), ('\u{c96d}', '\u{c987}', GC_LVT), ('\u{c988}', '\u{c988}', GC_LV),
+        ('\u{c989}', '\u{c9a3}', GC_LVT), ('\u{c9a4}', '\u{c9a4}', GC_LV), ('\u{c9a5}', '\u{c9bf}',
+        GC_LVT), ('\u{c9c0}', '\u{c9c0}', GC_LV), ('\u{c9c1}', '\u{c9db}', GC_LVT), ('\u{c9dc}',
+        '\u{c9dc}', GC_LV), ('\u{c9dd}', '\u{c9f7}', GC_LVT), ('\u{c9f8}', '\u{c9f8}', GC_LV),
+        ('\u{c9f9}', '\u{ca13}', GC_LVT), ('\u{ca14}', '\u{ca14}', GC_LV), ('\u{ca15}', '\u{ca2f}',
+        GC_LVT), ('\u{ca30}', '\u{ca30}', GC_LV), ('\u{ca31}', '\u{ca4b}', GC_LVT), ('\u{ca4c}',
+        '\u{ca4c}', GC_LV), ('\u{ca4d}', '\u{ca67}', GC_LVT), ('\u{ca68}', '\u{ca68}', GC_LV),
+        ('\u{ca69}', '\u{ca83}', GC_LVT), ('\u{ca84}', '\u{ca84}', GC_LV), ('\u{ca85}', '\u{ca9f}',
+        GC_LVT), ('\u{caa0}', '\u{caa0}', GC_LV), ('\u{caa1}', '\u{cabb}', GC_LVT), ('\u{cabc}',
+        '\u{cabc}', GC_LV), ('\u{cabd}', '\u{cad7}', GC_LVT), ('\u{cad8}', '\u{cad8}', GC_LV),
+        ('\u{cad9}', '\u{caf3}', GC_LVT), ('\u{caf4}', '\u{caf4}', GC_LV), ('\u{caf5}', '\u{cb0f}',
+        GC_LVT), ('\u{cb10}', '\u{cb10}', GC_LV), ('\u{cb11}', '\u{cb2b}', GC_LVT), ('\u{cb2c}',
+        '\u{cb2c}', GC_LV), ('\u{cb2d}', '\u{cb47}', GC_LVT), ('\u{cb48}', '\u{cb48}', GC_LV),
+        ('\u{cb49}', '\u{cb63}', GC_LVT), ('\u{cb64}', '\u{cb64}', GC_LV), ('\u{cb65}', '\u{cb7f}',
+        GC_LVT), ('\u{cb80}', '\u{cb80}', GC_LV), ('\u{cb81}', '\u{cb9b}', GC_LVT), ('\u{cb9c}',
+        '\u{cb9c}', GC_LV), ('\u{cb9d}', '\u{cbb7}', GC_LVT), ('\u{cbb8}', '\u{cbb8}', GC_LV),
+        ('\u{cbb9}', '\u{cbd3}', GC_LVT), ('\u{cbd4}', '\u{cbd4}', GC_LV), ('\u{cbd5}', '\u{cbef}',
+        GC_LVT), ('\u{cbf0}', '\u{cbf0}', GC_LV), ('\u{cbf1}', '\u{cc0b}', GC_LVT), ('\u{cc0c}',
+        '\u{cc0c}', GC_LV), ('\u{cc0d}', '\u{cc27}', GC_LVT), ('\u{cc28}', '\u{cc28}', GC_LV),
+        ('\u{cc29}', '\u{cc43}', GC_LVT), ('\u{cc44}', '\u{cc44}', GC_LV), ('\u{cc45}', '\u{cc5f}',
+        GC_LVT), ('\u{cc60}', '\u{cc60}', GC_LV), ('\u{cc61}', '\u{cc7b}', GC_LVT), ('\u{cc7c}',
+        '\u{cc7c}', GC_LV), ('\u{cc7d}', '\u{cc97}', GC_LVT), ('\u{cc98}', '\u{cc98}', GC_LV),
+        ('\u{cc99}', '\u{ccb3}', GC_LVT), ('\u{ccb4}', '\u{ccb4}', GC_LV), ('\u{ccb5}', '\u{cccf}',
+        GC_LVT), ('\u{ccd0}', '\u{ccd0}', GC_LV), ('\u{ccd1}', '\u{cceb}', GC_LVT), ('\u{ccec}',
+        '\u{ccec}', GC_LV), ('\u{cced}', '\u{cd07}', GC_LVT), ('\u{cd08}', '\u{cd08}', GC_LV),
+        ('\u{cd09}', '\u{cd23}', GC_LVT), ('\u{cd24}', '\u{cd24}', GC_LV), ('\u{cd25}', '\u{cd3f}',
+        GC_LVT), ('\u{cd40}', '\u{cd40}', GC_LV), ('\u{cd41}', '\u{cd5b}', GC_LVT), ('\u{cd5c}',
+        '\u{cd5c}', GC_LV), ('\u{cd5d}', '\u{cd77}', GC_LVT), ('\u{cd78}', '\u{cd78}', GC_LV),
+        ('\u{cd79}', '\u{cd93}', GC_LVT), ('\u{cd94}', '\u{cd94}', GC_LV), ('\u{cd95}', '\u{cdaf}',
+        GC_LVT), ('\u{cdb0}', '\u{cdb0}', GC_LV), ('\u{cdb1}', '\u{cdcb}', GC_LVT), ('\u{cdcc}',
+        '\u{cdcc}', GC_LV), ('\u{cdcd}', '\u{cde7}', GC_LVT), ('\u{cde8}', '\u{cde8}', GC_LV),
+        ('\u{cde9}', '\u{ce03}', GC_LVT), ('\u{ce04}', '\u{ce04}', GC_LV), ('\u{ce05}', '\u{ce1f}',
+        GC_LVT), ('\u{ce20}', '\u{ce20}', GC_LV), ('\u{ce21}', '\u{ce3b}', GC_LVT), ('\u{ce3c}',
+        '\u{ce3c}', GC_LV), ('\u{ce3d}', '\u{ce57}', GC_LVT), ('\u{ce58}', '\u{ce58}', GC_LV),
+        ('\u{ce59}', '\u{ce73}', GC_LVT), ('\u{ce74}', '\u{ce74}', GC_LV), ('\u{ce75}', '\u{ce8f}',
+        GC_LVT), ('\u{ce90}', '\u{ce90}', GC_LV), ('\u{ce91}', '\u{ceab}', GC_LVT), ('\u{ceac}',
+        '\u{ceac}', GC_LV), ('\u{cead}', '\u{cec7}', GC_LVT), ('\u{cec8}', '\u{cec8}', GC_LV),
+        ('\u{cec9}', '\u{cee3}', GC_LVT), ('\u{cee4}', '\u{cee4}', GC_LV), ('\u{cee5}', '\u{ceff}',
+        GC_LVT), ('\u{cf00}', '\u{cf00}', GC_LV), ('\u{cf01}', '\u{cf1b}', GC_LVT), ('\u{cf1c}',
+        '\u{cf1c}', GC_LV), ('\u{cf1d}', '\u{cf37}', GC_LVT), ('\u{cf38}', '\u{cf38}', GC_LV),
+        ('\u{cf39}', '\u{cf53}', GC_LVT), ('\u{cf54}', '\u{cf54}', GC_LV), ('\u{cf55}', '\u{cf6f}',
+        GC_LVT), ('\u{cf70}', '\u{cf70}', GC_LV), ('\u{cf71}', '\u{cf8b}', GC_LVT), ('\u{cf8c}',
+        '\u{cf8c}', GC_LV), ('\u{cf8d}', '\u{cfa7}', GC_LVT), ('\u{cfa8}', '\u{cfa8}', GC_LV),
+        ('\u{cfa9}', '\u{cfc3}', GC_LVT), ('\u{cfc4}', '\u{cfc4}', GC_LV), ('\u{cfc5}', '\u{cfdf}',
+        GC_LVT), ('\u{cfe0}', '\u{cfe0}', GC_LV), ('\u{cfe1}', '\u{cffb}', GC_LVT), ('\u{cffc}',
+        '\u{cffc}', GC_LV), ('\u{cffd}', '\u{d017}', GC_LVT), ('\u{d018}', '\u{d018}', GC_LV),
+        ('\u{d019}', '\u{d033}', GC_LVT), ('\u{d034}', '\u{d034}', GC_LV), ('\u{d035}', '\u{d04f}',
+        GC_LVT), ('\u{d050}', '\u{d050}', GC_LV), ('\u{d051}', '\u{d06b}', GC_LVT), ('\u{d06c}',
+        '\u{d06c}', GC_LV), ('\u{d06d}', '\u{d087}', GC_LVT), ('\u{d088}', '\u{d088}', GC_LV),
+        ('\u{d089}', '\u{d0a3}', GC_LVT), ('\u{d0a4}', '\u{d0a4}', GC_LV), ('\u{d0a5}', '\u{d0bf}',
+        GC_LVT), ('\u{d0c0}', '\u{d0c0}', GC_LV), ('\u{d0c1}', '\u{d0db}', GC_LVT), ('\u{d0dc}',
+        '\u{d0dc}', GC_LV), ('\u{d0dd}', '\u{d0f7}', GC_LVT), ('\u{d0f8}', '\u{d0f8}', GC_LV),
+        ('\u{d0f9}', '\u{d113}', GC_LVT), ('\u{d114}', '\u{d114}', GC_LV), ('\u{d115}', '\u{d12f}',
+        GC_LVT), ('\u{d130}', '\u{d130}', GC_LV), ('\u{d131}', '\u{d14b}', GC_LVT), ('\u{d14c}',
+        '\u{d14c}', GC_LV), ('\u{d14d}', '\u{d167}', GC_LVT), ('\u{d168}', '\u{d168}', GC_LV),
+        ('\u{d169}', '\u{d183}', GC_LVT), ('\u{d184}', '\u{d184}', GC_LV), ('\u{d185}', '\u{d19f}',
+        GC_LVT), ('\u{d1a0}', '\u{d1a0}', GC_LV), ('\u{d1a1}', '\u{d1bb}', GC_LVT), ('\u{d1bc}',
+        '\u{d1bc}', GC_LV), ('\u{d1bd}', '\u{d1d7}', GC_LVT), ('\u{d1d8}', '\u{d1d8}', GC_LV),
+        ('\u{d1d9}', '\u{d1f3}', GC_LVT), ('\u{d1f4}', '\u{d1f4}', GC_LV), ('\u{d1f5}', '\u{d20f}',
+        GC_LVT), ('\u{d210}', '\u{d210}', GC_LV), ('\u{d211}', '\u{d22b}', GC_LVT), ('\u{d22c}',
+        '\u{d22c}', GC_LV), ('\u{d22d}', '\u{d247}', GC_LVT), ('\u{d248}', '\u{d248}', GC_LV),
+        ('\u{d249}', '\u{d263}', GC_LVT), ('\u{d264}', '\u{d264}', GC_LV), ('\u{d265}', '\u{d27f}',
+        GC_LVT), ('\u{d280}', '\u{d280}', GC_LV), ('\u{d281}', '\u{d29b}', GC_LVT), ('\u{d29c}',
+        '\u{d29c}', GC_LV), ('\u{d29d}', '\u{d2b7}', GC_LVT), ('\u{d2b8}', '\u{d2b8}', GC_LV),
+        ('\u{d2b9}', '\u{d2d3}', GC_LVT), ('\u{d2d4}', '\u{d2d4}', GC_LV), ('\u{d2d5}', '\u{d2ef}',
+        GC_LVT), ('\u{d2f0}', '\u{d2f0}', GC_LV), ('\u{d2f1}', '\u{d30b}', GC_LVT), ('\u{d30c}',
+        '\u{d30c}', GC_LV), ('\u{d30d}', '\u{d327}', GC_LVT), ('\u{d328}', '\u{d328}', GC_LV),
+        ('\u{d329}', '\u{d343}', GC_LVT), ('\u{d344}', '\u{d344}', GC_LV), ('\u{d345}', '\u{d35f}',
+        GC_LVT), ('\u{d360}', '\u{d360}', GC_LV), ('\u{d361}', '\u{d37b}', GC_LVT), ('\u{d37c}',
+        '\u{d37c}', GC_LV), ('\u{d37d}', '\u{d397}', GC_LVT), ('\u{d398}', '\u{d398}', GC_LV),
+        ('\u{d399}', '\u{d3b3}', GC_LVT), ('\u{d3b4}', '\u{d3b4}', GC_LV), ('\u{d3b5}', '\u{d3cf}',
+        GC_LVT), ('\u{d3d0}', '\u{d3d0}', GC_LV), ('\u{d3d1}', '\u{d3eb}', GC_LVT), ('\u{d3ec}',
+        '\u{d3ec}', GC_LV), ('\u{d3ed}', '\u{d407}', GC_LVT), ('\u{d408}', '\u{d408}', GC_LV),
+        ('\u{d409}', '\u{d423}', GC_LVT), ('\u{d424}', '\u{d424}', GC_LV), ('\u{d425}', '\u{d43f}',
+        GC_LVT), ('\u{d440}', '\u{d440}', GC_LV), ('\u{d441}', '\u{d45b}', GC_LVT), ('\u{d45c}',
+        '\u{d45c}', GC_LV), ('\u{d45d}', '\u{d477}', GC_LVT), ('\u{d478}', '\u{d478}', GC_LV),
+        ('\u{d479}', '\u{d493}', GC_LVT), ('\u{d494}', '\u{d494}', GC_LV), ('\u{d495}', '\u{d4af}',
+        GC_LVT), ('\u{d4b0}', '\u{d4b0}', GC_LV), ('\u{d4b1}', '\u{d4cb}', GC_LVT), ('\u{d4cc}',
+        '\u{d4cc}', GC_LV), ('\u{d4cd}', '\u{d4e7}', GC_LVT), ('\u{d4e8}', '\u{d4e8}', GC_LV),
+        ('\u{d4e9}', '\u{d503}', GC_LVT), ('\u{d504}', '\u{d504}', GC_LV), ('\u{d505}', '\u{d51f}',
+        GC_LVT), ('\u{d520}', '\u{d520}', GC_LV), ('\u{d521}', '\u{d53b}', GC_LVT), ('\u{d53c}',
+        '\u{d53c}', GC_LV), ('\u{d53d}', '\u{d557}', GC_LVT), ('\u{d558}', '\u{d558}', GC_LV),
+        ('\u{d559}', '\u{d573}', GC_LVT), ('\u{d574}', '\u{d574}', GC_LV), ('\u{d575}', '\u{d58f}',
+        GC_LVT), ('\u{d590}', '\u{d590}', GC_LV), ('\u{d591}', '\u{d5ab}', GC_LVT), ('\u{d5ac}',
+        '\u{d5ac}', GC_LV), ('\u{d5ad}', '\u{d5c7}', GC_LVT), ('\u{d5c8}', '\u{d5c8}', GC_LV),
+        ('\u{d5c9}', '\u{d5e3}', GC_LVT), ('\u{d5e4}', '\u{d5e4}', GC_LV), ('\u{d5e5}', '\u{d5ff}',
+        GC_LVT), ('\u{d600}', '\u{d600}', GC_LV), ('\u{d601}', '\u{d61b}', GC_LVT), ('\u{d61c}',
+        '\u{d61c}', GC_LV), ('\u{d61d}', '\u{d637}', GC_LVT), ('\u{d638}', '\u{d638}', GC_LV),
+        ('\u{d639}', '\u{d653}', GC_LVT), ('\u{d654}', '\u{d654}', GC_LV), ('\u{d655}', '\u{d66f}',
+        GC_LVT), ('\u{d670}', '\u{d670}', GC_LV), ('\u{d671}', '\u{d68b}', GC_LVT), ('\u{d68c}',
+        '\u{d68c}', GC_LV), ('\u{d68d}', '\u{d6a7}', GC_LVT), ('\u{d6a8}', '\u{d6a8}', GC_LV),
+        ('\u{d6a9}', '\u{d6c3}', GC_LVT), ('\u{d6c4}', '\u{d6c4}', GC_LV), ('\u{d6c5}', '\u{d6df}',
+        GC_LVT), ('\u{d6e0}', '\u{d6e0}', GC_LV), ('\u{d6e1}', '\u{d6fb}', GC_LVT), ('\u{d6fc}',
+        '\u{d6fc}', GC_LV), ('\u{d6fd}', '\u{d717}', GC_LVT), ('\u{d718}', '\u{d718}', GC_LV),
+        ('\u{d719}', '\u{d733}', GC_LVT), ('\u{d734}', '\u{d734}', GC_LV), ('\u{d735}', '\u{d74f}',
+        GC_LVT), ('\u{d750}', '\u{d750}', GC_LV), ('\u{d751}', '\u{d76b}', GC_LVT), ('\u{d76c}',
+        '\u{d76c}', GC_LV), ('\u{d76d}', '\u{d787}', GC_LVT), ('\u{d788}', '\u{d788}', GC_LV),
+        ('\u{d789}', '\u{d7a3}', GC_LVT), ('\u{d7b0}', '\u{d7c6}', GC_V), ('\u{d7cb}', '\u{d7fb}',
+        GC_T), ('\u{fb1e}', '\u{fb1e}', GC_Extend), ('\u{fe00}', '\u{fe0f}', GC_Extend),
         ('\u{fe20}', '\u{fe2d}', GC_Extend), ('\u{feff}', '\u{feff}', GC_Control), ('\u{ff9e}',
         '\u{ff9f}', GC_Extend), ('\u{fff0}', '\u{fffb}', GC_Control), ('\u{101fd}', '\u{101fd}',
         GC_Extend), ('\u{102e0}', '\u{102e0}', GC_Extend), ('\u{10376}', '\u{1037a}', GC_Extend),
@@ -8326,7 +8321,7 @@ pub fn grapheme_category(c: char) -> GraphemeCat {
         ('\u{1d173}', '\u{1d17a}', GC_Control), ('\u{1d17b}', '\u{1d182}', GC_Extend), ('\u{1d185}',
         '\u{1d18b}', GC_Extend), ('\u{1d1aa}', '\u{1d1ad}', GC_Extend), ('\u{1d242}', '\u{1d244}',
         GC_Extend), ('\u{1e8d0}', '\u{1e8d6}', GC_Extend), ('\u{1f1e6}', '\u{1f1ff}',
-        GC_RegionalIndicator), ('\u{e0000}', '\u{e00ff}', GC_Control), ('\u{e0100}', '\u{e01ef}',
+        GC_Regional_Indicator), ('\u{e0000}', '\u{e00ff}', GC_Control), ('\u{e0100}', '\u{e01ef}',
         GC_Extend), ('\u{e01f0}', '\u{e0fff}', GC_Control)
     ];
 
index 3f9dd8ab635c3bd64bf973f06354e0cd4eb59a3e..6852cfe11eb7211b33458a4e672417ce0c2ccecc 100644 (file)
@@ -20,7 +20,7 @@
 
 use core::char;
 use core::cmp;
-use core::iter::{Filter, AdditiveIterator};
+use core::iter::Filter;
 use core::mem;
 use core::slice;
 use core::str::Split;
@@ -199,7 +199,7 @@ fn next(&mut self) -> Option<&'a str> {
                     gr::GC_L => HangulL,
                     gr::GC_LV | gr::GC_V => HangulLV,
                     gr::GC_LVT | gr::GC_T => HangulLVT,
-                    gr::GC_RegionalIndicator => Regional,
+                    gr::GC_Regional_Indicator => Regional,
                     _ => FindExtend
                 },
                 FindExtend => {         // found non-extending when looking for extending
@@ -231,7 +231,7 @@ fn next(&mut self) -> Option<&'a str> {
                     }
                 },
                 Regional => match cat {     // rule GB8a
-                    gr::GC_RegionalIndicator => continue,
+                    gr::GC_Regional_Indicator => continue,
                     _ => {
                         take_curr = false;
                         break;
@@ -300,7 +300,7 @@ fn next_back(&mut self) -> Option<&'a str> {
                     gr::GC_L | gr::GC_LV | gr::GC_LVT => HangulL,
                     gr::GC_V => HangulLV,
                     gr::GC_T => HangulLVT,
-                    gr::GC_RegionalIndicator => Regional,
+                    gr::GC_Regional_Indicator => Regional,
                     gr::GC_Control => {
                         take_curr = Start == state;
                         break;
@@ -332,7 +332,7 @@ fn next_back(&mut self) -> Option<&'a str> {
                     }
                 },
                 Regional => match cat {     // rule GB8a
-                    gr::GC_RegionalIndicator => continue,
+                    gr::GC_Regional_Indicator => continue,
                     _ => {
                         take_curr = false;
                         break;
index a08481f8be94e0473c8cfc6b77167bf83d7aa4c1..2d630d8fe8de7ebd4a03d17cfcd1502832a53efb 100644 (file)
@@ -13,7 +13,6 @@
 use std::io::prelude::*;
 use std::io::BufReader;
 use std::iter;
-use std::iter::AdditiveIterator;
 use std::path::{Path, PathBuf};
 
 pub struct BookItem {
@@ -151,7 +150,7 @@ fn collapse(stack: &mut Vec<BookItem>,
                 '\t' => 4,
                 _ => unreachable!()
             }
-        }).sum() / 4 + 1;
+        }).sum::<usize>() / 4 + 1;
 
         if level > stack.len() + 1 {
             errors.push(format!("section '{}' is indented too deeply; \
index c0268e816cf3e537b9c2b7653a4c89680fbebb66..5fcbe773299927148134d204ba48660644753a40 100644 (file)
@@ -43,7 +43,7 @@
 #![allow(non_snake_case)]
 #![feature(unboxed_closures, core, os)]
 
-use std::iter::{repeat, AdditiveIterator};
+use std::iter::repeat;
 use std::thread;
 use std::mem;
 use std::num::Float;
diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs
new file mode 100644 (file)
index 0000000..ac59694
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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 main() {
+    let a: &[i32] = &[1, 2, 3];
+    let b: Box<[i32]> = Box::new([1, 2, 3]);
+    let p = a as *const [i32];
+
+    a as usize; //~ ERROR cast from fat pointer
+    b as usize; //~ ERROR cast from fat pointer
+    p as usize; //~ ERROR cast from fat pointer
+}
diff --git a/src/test/compile-fail/issue-22560.rs b/src/test/compile-fail/issue-22560.rs
new file mode 100644 (file)
index 0000000..b458e10
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+use std::ops::{Add, Sub};
+
+type Test = Add +
+            //~^ ERROR the type parameter `RHS` must be explicitly specified in an object type because its default value `Self` references the type `Self`
+            Sub;
+            //~^ ERROR only the builtin traits can be used as closure or object bounds
+
+fn main() { }
diff --git a/src/test/compile-fail/issue-23338-locals-die-before-temps-of-body.rs b/src/test/compile-fail/issue-23338-locals-die-before-temps-of-body.rs
new file mode 100644 (file)
index 0000000..9938934
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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.
+
+// This is just checking that we still reject code where temp values
+// are borrowing values for longer than they will be around.
+//
+// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
+
+use std::cell::RefCell;
+
+fn foo(x: RefCell<String>) -> String {
+    let y = x;
+    y.borrow().clone() //~ ERROR `y` does not live long enough
+}
+
+fn foo2(x: RefCell<String>) -> String {
+    let ret = {
+        let y = x;
+        y.borrow().clone() //~ ERROR `y` does not live long enough
+    };
+    ret
+}
+
+fn main() {
+    let r = RefCell::new(format!("data"));
+    assert_eq!(foo(r), "data");
+    let r = RefCell::new(format!("data"));
+    assert_eq!(foo2(r), "data");
+}
index 53b29ccb0c0c7580b48be88f1ff096e0795fd921..b3ce84c7e6f1a2dbfcd46c49e2f9e13910146c0c 100644 (file)
@@ -24,12 +24,12 @@ macro_rules! ignored_pat {
     () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,`
 }
 
-ignored_item!();
+ignored_item!(); //~ NOTE caused by the macro expansion here
 
 fn main() {
-    ignored_expr!();
+    ignored_expr!(); //~ NOTE caused by the macro expansion here
     match 1 {
-        ignored_pat!() => (),
+        ignored_pat!() => (), //~ NOTE caused by the macro expansion here
         _ => (),
     }
 }
index 3ae61722bcff3e9c7206b875f3d403b0361add99..826e4283ef82748fb400c0b2208ed75f67e5c9a8 100644 (file)
@@ -19,6 +19,7 @@ pub fn main() {
     for i in false..true {}
     //~^ ERROR the trait
     //~^^ ERROR the trait
+    //~^^^ ERROR the trait
 
     // Unsized type.
     let arr: &[_] = &[1, 2, 3];
diff --git a/src/test/compile-fail/self-impl.rs b/src/test/compile-fail/self-impl.rs
new file mode 100644 (file)
index 0000000..d058c6a
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 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 unsupported uses of `Self` in impls don't crash
+
+struct Bar;
+
+trait Foo {
+    type Baz;
+}
+
+trait SuperFoo {
+    type SuperBaz;
+}
+
+impl Foo for Bar {
+    type Baz = bool;
+}
+
+impl SuperFoo for Bar {
+    type SuperBaz = bool;
+}
+
+impl Bar {
+    fn f() {
+        let _: <Self>::Baz = true;
+//~^ERROR: ambiguous associated type; specify the type using the syntax `<Bar as Trait>::Baz`
+        let _: Self::Baz = true;
+//~^ERROR: ambiguous associated type; specify the type using the syntax `<Bar as Trait>::Baz`
+    }
+}
+
+fn main() {}
index c9837da58e75a1d4a86801075a806d1c873199bf..bb7e02d0d8b9bebf5abc9c9c26f9811b7f18cd21 100644 (file)
@@ -12,7 +12,7 @@
 
 trait One<A> { fn foo(&self) -> A; }
 
-fn foo(_: &One()) //~ ERROR no associated type `Output` defined in `One<()>`
+fn foo(_: &One()) //~ ERROR associated type `Output` not found for `One<()>`
 {}
 
 fn main() { }
index 9f0682df3fe443c70b639a85a9515b06067ab5ed..20fdd52b82a3e257127e9d588a07a0767abfc51e 100644 (file)
@@ -14,7 +14,7 @@
 
 fn foo(_: &Three())
 //~^ ERROR wrong number of type arguments
-//~| ERROR no associated type `Output`
+//~| ERROR associated type `Output` not found
 {}
 
 fn main() { }
index 40635cf3ddda32ca7bd689f94c011bad1eaa42e3..027fa6b0fe3b0866a70d208681c06dd8422ba1f5 100644 (file)
@@ -14,7 +14,7 @@
 
 fn foo(_: Zero())
     //~^ ERROR wrong number of type arguments
-    //~| ERROR no associated type `Output` defined in `Zero`
+    //~| ERROR associated type `Output` not found for `Zero`
 {}
 
 fn main() { }
index e6e18d996b9e2e7adce47d19f41e49daa46c2204..04bbfc445edeaab920911845a249d8f4a30d7220 100644 (file)
@@ -14,6 +14,6 @@ trait Trait {}
 
 fn f<F:Trait(isize) -> isize>(x: F) {}
 //~^ ERROR wrong number of type arguments: expected 0, found 1
-//~| ERROR no associated type `Output`
+//~| ERROR associated type `Output` not found
 
 fn main() {}
index ca17c898ec37cdf2e582b028cb79b4a18d6aa50b..b4246f2ed87f3009e181b2a501f31cd8e42e4d80 100644 (file)
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME: #13993
-// error-pattern:unsupported cast
+// error-pattern:illegal cast
+
+#![feature(libc)]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/atomic-print.rs b/src/test/run-pass/atomic-print.rs
new file mode 100644 (file)
index 0000000..df3b572
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright 2015 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::{env, fmt, process, sync, thread};
+
+struct SlowFmt(u32);
+impl fmt::Debug for SlowFmt {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        thread::sleep_ms(3);
+        self.0.fmt(f)
+    }
+}
+
+fn do_print(x: u32) {
+    let x = SlowFmt(x);
+    println!("{:?}{:?}{:?}{:?}{:?}", x, x, x, x, x);
+}
+
+fn main(){
+    if env::args().count() == 2 {
+        let barrier = sync::Arc::new(sync::Barrier::new(2));
+        let tbarrier = barrier.clone();
+        let t = thread::scoped(||{
+            tbarrier.wait();
+            do_print(1);
+        });
+        barrier.wait();
+        do_print(2);
+        t.join();
+    } else {
+        let this = env::args().next().unwrap();
+        let output = process::Command::new(this).arg("-").output().unwrap();
+        for line in String::from_utf8(output.stdout).unwrap().lines() {
+            match line.chars().next().unwrap() {
+                '1' => assert_eq!(line, "11111"),
+                '2' => assert_eq!(line, "22222"),
+                _   => panic!("Unexpected character")
+            }
+        }
+    }
+}
diff --git a/src/test/run-pass/fmt-pointer-trait.rs b/src/test/run-pass/fmt-pointer-trait.rs
new file mode 100644 (file)
index 0000000..be8ecde
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2015 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.
+
+#![feature(libc)]
+extern crate libc;
+use std::ptr;
+use std::rc::Rc;
+use std::sync::Arc;
+
+fn main() {
+    let p: *const libc::c_void = ptr::null();
+    let rc = Rc::new(1usize);
+    let arc = Arc::new(1usize);
+    let b = Box::new("hi");
+
+    let _ = format!("{:p}{:p}{:p}",
+                    rc, arc, b);
+
+    assert_eq!(format!("{:p}", p),
+               "0x0");
+}
index 6c76f1595dc0de1d748e6ebac54ec76fe7357127..c1ecd3eba48bd3f79962b69f19997d1f4495b827 100644 (file)
@@ -12,8 +12,7 @@
 
 #![feature(core)]
 
-use std::iter::AdditiveIterator;
 fn main() {
     let x: [u64; 3] = [1, 2, 3];
-    assert_eq!(6, (0..3).map(|i| x[i]).sum());
+    assert_eq!(6, (0..3).map(|i| x[i]).sum::<u64>());
 }
diff --git a/src/test/run-pass/issue-23338-ensure-param-drop-order.rs b/src/test/run-pass/issue-23338-ensure-param-drop-order.rs
new file mode 100644 (file)
index 0000000..0815ff0
--- /dev/null
@@ -0,0 +1,171 @@
+// Copyright 2015 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.
+
+// ignore-pretty : (#23623) problems when  ending with // comments
+
+// This test is ensuring that parameters are indeed dropped after
+// temporaries in a fn body.
+
+use std::cell::RefCell;
+
+use self::d::D;
+
+pub fn main() {
+    let log = RefCell::new(vec![]);
+    d::println(&format!("created empty log"));
+    test(&log);
+
+    assert_eq!(&log.borrow()[..],
+               [
+                   //                                    created empty log
+                   //    +-- Make D(da_0, 0)
+                   //    | +-- Make D(de_1, 1)
+                   //    | |                             calling foo
+                   //    | |                             entered foo
+                   //    | | +-- Make D(de_2, 2)
+                   //    | | | +-- Make D(da_1, 3)
+                   //    | | | | +-- Make D(de_3, 4)
+                   //    | | | | | +-- Make D(de_4, 5)
+                   3, // | | | +-- Drop D(da_1, 3)
+                   //    | | |   | |
+                   4, // | | |   +-- Drop D(de_3, 4)
+                   //    | | |     |
+                   //    | | |     |                     eval tail of foo
+                   //    | | | +-- Make D(de_5, 6)
+                   //    | | | | +-- Make D(de_6, 7)
+                   6, // | | | +-- Drop D(de_5, 6)
+                   //    | | |   | |
+                   5, // | | |   | +-- Drop D(de_4, 5)
+                   //    | | |   |
+                   2, // | | +-- Drop D(de_2, 2)
+                   //    | |     |
+                   1, // | +-- Drop D(de_1, 1)
+                   //    |       |
+                   0, // +-- Drop D(da_0, 0)
+                   //            |
+                   //            |                       result D(de_6, 7)
+                   7 //          +-- Drop D(de_6, 7)
+
+                       ]);
+}
+
+fn test<'a>(log: d::Log<'a>) {
+    let da = D::new("da", 0, log);
+    let de = D::new("de", 1, log);
+    d::println(&format!("calling foo"));
+    let result = foo(da, de);
+    d::println(&format!("result {}", result));
+}
+
+fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
+    d::println(&format!("entered foo"));
+    let de2 = de1.incr();      // creates D(de_2, 2)
+    let de4 = {
+        let _da1 = da0.incr(); // creates D(da_1, 3)
+        de2.incr().incr()      // creates D(de_3, 4) and D(de_4, 5)
+    };
+    d::println(&format!("eval tail of foo"));
+    de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
+}
+
+// This module provides simultaneous printouts of the dynamic extents
+// of all of the D values, in addition to logging the order that each
+// is dropped.
+
+const PREF_INDENT: u32 = 16;
+
+pub mod d {
+    #![allow(unused_parens)]
+    use std::fmt;
+    use std::mem;
+    use std::cell::RefCell;
+
+    static mut counter: u32 = 0;
+    static mut trails: u64 = 0;
+
+    pub type Log<'a> = &'a RefCell<Vec<u32>>;
+
+    pub fn current_width() -> u32 {
+        unsafe { max_width() - trails.leading_zeros() }
+    }
+
+    pub fn max_width() -> u32 {
+        unsafe {
+            (mem::size_of_val(&trails)*8) as u32
+        }
+    }
+
+    pub fn indent_println(my_trails: u32, s: &str) {
+        let mut indent: String = String::new();
+        for i in 0..my_trails {
+            unsafe {
+                if trails & (1 << i) != 0 {
+                    indent = indent + "| ";
+                } else {
+                    indent = indent + "  ";
+                }
+            }
+        }
+        println!("{}{}", indent, s);
+    }
+
+    pub fn println(s: &str) {
+        indent_println(super::PREF_INDENT, s);
+    }
+
+    fn first_avail() -> u32 {
+        unsafe {
+            for i in 0..64 {
+                if trails & (1 << i) == 0 {
+                    return i;
+                }
+            }
+        }
+        panic!("exhausted trails");
+    }
+
+    pub struct D<'a> {
+        name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
+    }
+
+    impl<'a> fmt::Display for D<'a> {
+        fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+            write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
+        }
+    }
+
+    impl<'a> D<'a> {
+        pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> {
+            unsafe {
+                let trail = first_avail();
+                let ctr = counter;
+                counter += 1;
+                trails |= (1 << trail);
+                let ret = D {
+                    name: name, i: i, log: log, uid: ctr, trail: trail
+                };
+                indent_println(trail, &format!("+-- Make {}", ret));
+                ret
+            }
+        }
+        pub fn incr(&self) -> D<'a> {
+            D::new(self.name, self.i + 1, self.log)
+        }
+    }
+
+    impl<'a> Drop for D<'a> {
+        fn drop(&mut self) {
+            unsafe { trails &= !(1 << self.trail); };
+            self.log.borrow_mut().push(self.uid);
+            indent_println(self.trail, &format!("+-- Drop {}", self));
+            indent_println(::PREF_INDENT, "");
+        }
+    }
+}
diff --git a/src/test/run-pass/issue-23338-params-outlive-temps-of-body.rs b/src/test/run-pass/issue-23338-params-outlive-temps-of-body.rs
new file mode 100644 (file)
index 0000000..cb9e852
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+// This is largely checking that we now accept code where temp values
+// are borrowing from the input parameters (the `foo` case below).
+//
+// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs
+//
+// (The `foo2` case is just for parity with the above test, which
+//  shows what happens when you move the `y`-binding to the inside of
+//  the inner block.)
+
+use std::cell::RefCell;
+
+fn foo(x: RefCell<String>) -> String {
+    x.borrow().clone()
+}
+
+fn foo2(x: RefCell<String>) -> String {
+    let y = x;
+    let ret = {
+        y.borrow().clone()
+    };
+    ret
+}
+
+pub fn main() {
+    let r = RefCell::new(format!("data"));
+    assert_eq!(foo(r), "data");
+    let r = RefCell::new(format!("data"));
+    assert_eq!(foo2(r), "data");
+}
diff --git a/src/test/run-pass/issue-24161.rs b/src/test/run-pass/issue-24161.rs
new file mode 100644 (file)
index 0000000..2445ef1
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+#[derive(Copy,Clone)]
+struct Functions {
+    a: fn(u32) -> u32,
+    b: extern "C" fn(u32) -> u32,
+    c: unsafe fn(u32) -> u32,
+    d: unsafe extern "C" fn(u32) -> u32
+}
+
+pub fn main() {}
index 12f6a7caf6c399f783038f1686df4cb151368290..d1f63564979c8ba74c1642bdbd3908c2fe0dbc89 100644 (file)
 
 #![feature(core)]
 
-use std::iter::AdditiveIterator;
-
 fn square_sum(v: &[i64]) -> i64 {
-    let sum = v.iter().cloned().sum();
+    let sum: i64 = v.iter().cloned().sum();
     sum * sum
 }
 
index c32773aa88c2aaf5a91eee4500777479eabeb187..688b66a0a87744553a75916813929b52775b879c 100644 (file)
@@ -22,6 +22,17 @@ impl Foo {
     fn foo(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
         Foo
     }
+
+    fn baz() {
+        // Test that Self cannot be shadowed.
+        type Foo = i32;
+        // There is no empty method on i32.
+        Self::empty();
+
+        let _: Self = Foo;
+    }
+
+    fn empty() {}
 }
 
 // Test uses when implementing a trait and with a type parameter.
@@ -29,13 +40,31 @@ pub struct Baz<X> {
     pub f: X,
 }
 
-trait Bar<X> {
-    fn bar(x: Self, y: &Self, z: Box<Self>) -> Self;
+trait SuperBar {
+    type SuperQux;
+}
+
+trait Bar<X>: SuperBar {
+    type Qux;
+
+    fn bar(x: Self, y: &Self, z: Box<Self>, _: Self::SuperQux) -> Self;
     fn dummy(&self, x: X) { }
 }
 
+impl SuperBar for Box<Baz<isize>> {
+    type SuperQux = bool;
+}
+
 impl Bar<isize> for Box<Baz<isize>> {
-    fn bar(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
+    type Qux = i32;
+
+    fn bar(_x: Self, _y: &Self, _z: Box<Self>, _: Self::SuperQux) -> Self {
+        let _: Self::Qux = 42;
+        let _: <Self as Bar<isize>>::Qux = 42;
+
+        let _: Self::SuperQux = true;
+        let _: <Self as SuperBar>::SuperQux = true;
+
         box Baz { f: 42 }
     }
 }
@@ -43,6 +72,7 @@ fn bar(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
 fn main() {
     let _: Foo = Foo::foo(Foo, &Foo, box Foo);
     let _: Box<Baz<isize>> = Bar::bar(box Baz { f: 42 },
-                                    &box Baz { f: 42 },
-                                    box box Baz { f: 42 });
+                                      &box Baz { f: 42 },
+                                      box box Baz { f: 42 },
+                                      true);
 }