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>
// 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 \
.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 {
(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"
+ }
+}
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`.
# 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`:
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:
# 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)
* [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)
+++ /dev/null
-% 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.
+++ /dev/null
-% 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!
+++ /dev/null
-% 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.
--- /dev/null
+% 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.
--- /dev/null
+% Attributes
+
+Coming Soon!
+++ /dev/null
-% 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.
--- /dev/null
+% Casting Between Types
+
+Coming Soon
--- /dev/null
+% 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`.
+++ /dev/null
-% 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
+++ /dev/null
-% 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!
--- /dev/null
+% Conditional Compilation
+
+Coming Soon!
--- /dev/null
+% `const`
+
+Coming soon!
--- /dev/null
+% `Debug` and `Display`
+
+Coming soon!
--- /dev/null
+% `Deref` coercions
+
+Coming soon!
--- /dev/null
+% `Drop`
+
+Coming soon!
--- /dev/null
+% Effective Rust
--- /dev/null
+% 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
--- /dev/null
+% `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.
--- /dev/null
+% Getting Started
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.
-% 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
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`
+++ /dev/null
-% 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.
--- /dev/null
+% Learn Rust
--- /dev/null
+% Lifetimes
+
+Coming soon!
+++ /dev/null
-% 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.
* `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.
+++ /dev/null
-% 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);
-```
--- /dev/null
+% Move Semantics
+
+Coming Soon
--- /dev/null
+% Mutability
+
+Coming Soon
--- /dev/null
+% 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.
+
--- /dev/null
+% Operators and Overloading
+
+Coming soon!
+++ /dev/null
-% 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`.
+++ /dev/null
-% 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
--- /dev/null
+% Primitive Types
+
+Coming Soon!
--- /dev/null
+% References and Borrowing
+
+Coming Soon!
--- /dev/null
+% 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.
+++ /dev/null
-% 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.
--- /dev/null
+% `static`
+
+Coming soon!
--- /dev/null
+% 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)`.
--- /dev/null
+% Syntax and Semantics
--- /dev/null
+% The Stack and the Heap
+
+Coming Soon
+++ /dev/null
-% 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.
--- /dev/null
+% 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.
--- /dev/null
+% 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`.
--- /dev/null
+% 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.
--- /dev/null
+% `type` Aliases
+
+Coming soon
--- /dev/null
+% Universal Function Call Syntax
+
+Coming soon
--- /dev/null
+% 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.
+++ /dev/null
-% 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.
--- /dev/null
+% Unsized Types
+
+Coming Soon!
+++ /dev/null
-% 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.
-
--- /dev/null
+% 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.
--- /dev/null
+% `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.
# This script uses the following Unicode tables:
# - DerivedCoreProperties.txt
+# - DerivedNormalizationProps.txt
# - EastAsianWidth.txt
+# - auxiliary/GraphemeBreakProperty.txt
# - PropList.txt
+# - ReadMe.txt
# - Scripts.txt
# - UnicodeData.txt
#
'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)
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
(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",
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)
### 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:
}
}
+#[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")]
}
}
+#[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;
}
}
+#[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
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;
#[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))
}
}
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;
// 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;
// except according to those terms.
use std::cmp::Ordering::{Equal, Greater, Less};
-use std::iter::AdditiveIterator;
use std::str::{Utf8Error, from_utf8};
#[test]
#[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 }
+ }
)
}
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;
///
/// ```
/// # #![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]
}
}
}
+
+ /// 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")]
}
}
-/// 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)]
/// 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>;
#[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]
#[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> {
#[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
}
#[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]
#[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)
}
}
}
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",
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;
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)
+ }
+}
#[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]
#![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
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)
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,
};
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),
}
}
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) }
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;
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 {
#[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 */),
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"),
}
}
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)
}
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)),
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) },
}
}
match ast_map.find(self.node_id()) {
Some(ast_map::NodeBlock(ref blk)) => {
match *self {
+ CodeExtent::ParameterScope { .. } |
CodeExtent::Misc(_) |
CodeExtent::DestructionScope(_) => Some(blk.span),
Block(ast::NodeId),
Statement(DeclaringStatementContext),
Match(ast::NodeId),
+ FnDecl { fn_id: ast::NodeId, body_id: ast::NodeId },
}
impl InnermostDeclaringBlock {
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(),
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);
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);
};
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
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) =>
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));
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...
}
}
}
- DefTyParam(..) | DefSelfTy(_) => {
+ DefTyParam(..) | DefSelfTy(..) => {
for rib in ribs {
match rib.kind {
NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
}
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(_) => {
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()));
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,
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(_) => {}
}
- }
+ });
});
});
});
def::DefFn(..) => Some(recorder::FnRef),
- def::DefSelfTy(_) |
+ def::DefSelfTy(..) |
def::DefRegion(_) |
def::DefLabel(_) |
def::DefTyParam(..) |
use std;
use std::cmp::Ordering;
-use std::iter::AdditiveIterator;
use std::rc::Rc;
use syntax::ast;
use syntax::ast::{DUMMY_NODE_ID, NodeId};
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};
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)
}
}
}
- 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 { // |
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
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,
&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)
_ => 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()
};
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));
}
}
-// 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
}
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)
}
// 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,
"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;
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);
}
--- /dev/null
+// 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);
+ }
+}
pub mod method;
mod upvar;
pub mod wf;
+mod cast;
mod closure;
mod callee;
mod compare_method;
// 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> {
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)]
}
-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 }
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,
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();
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;
// 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) => {
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
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");
},
_ => {}
}
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! {
// 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.
/// 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.
/// 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()))))
}
}
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.
/// 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.
/// 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.
/// 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())))
}
}
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
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};
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 {
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};
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) => {
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
///
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;
mod future;
mod mutex;
mod once;
-mod poison;
mod rwlock;
mod semaphore;
//! });
//! 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")]
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
///
/// 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.
///
+++ /dev/null
-// 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)))
- }
-}
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
///
pub mod mutex;
pub mod net;
pub mod net2;
+pub mod poison;
+pub mod remutex;
pub mod rwlock;
pub mod stack;
pub mod thread;
--- /dev/null
+// 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)))
+ }
+}
--- /dev/null
+// 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);
+ }
+}
use cell::UnsafeCell;
use sys::sync as ffi;
+use mem;
pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
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);
+ }
+}
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;
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"))]
__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__],
__sig: _PTHREAD_RWLOCK_SIG_INIT,
__opaque: [0; __PTHREAD_RWLOCK_SIZE__],
};
+
+ pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
}
#[cfg(target_os = "linux")]
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],
__align: 0,
size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
};
+ pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
}
#[cfg(target_os = "android")]
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)]
pendingWriters: 0,
reserved: [0 as *mut _; 4],
};
+ pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
}
use cell::UnsafeCell;
use sys::sync as ffi;
+use mem;
pub struct Mutex { inner: UnsafeCell<ffi::SRWLOCK> }
// ...
}
}
+
+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());
+ }
+}
// 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 _,
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);
}
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
/// 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 }
}
}
}
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_ {
.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)
}
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> {
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[..]);
}
}
}
// 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 {
}
}
+#[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);
#[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,
}
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),
('\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)
];
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;
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
}
},
Regional => match cat { // rule GB8a
- gr::GC_RegionalIndicator => continue,
+ gr::GC_Regional_Indicator => continue,
_ => {
take_curr = false;
break;
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;
}
},
Regional => match cat { // rule GB8a
- gr::GC_RegionalIndicator => continue,
+ gr::GC_Regional_Indicator => continue,
_ => {
take_curr = false;
break;
use std::io::prelude::*;
use std::io::BufReader;
use std::iter;
-use std::iter::AdditiveIterator;
use std::path::{Path, PathBuf};
pub struct BookItem {
'\t' => 4,
_ => unreachable!()
}
- }).sum() / 4 + 1;
+ }).sum::<usize>() / 4 + 1;
if level > stack.len() + 1 {
errors.push(format!("section '{}' is indented too deeply; \
#![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;
--- /dev/null
+// 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
+}
--- /dev/null
+// 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() { }
--- /dev/null
+// 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");
+}
() => ( 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
_ => (),
}
}
for i in false..true {}
//~^ ERROR the trait
//~^^ ERROR the trait
+ //~^^^ ERROR the trait
// Unsized type.
let arr: &[_] = &[1, 2, 3];
--- /dev/null
+// 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() {}
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() { }
fn foo(_: &Three())
//~^ ERROR wrong number of type arguments
-//~| ERROR no associated type `Output`
+//~| ERROR associated type `Output` not found
{}
fn main() { }
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() { }
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() {}
// 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;
--- /dev/null
+// 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")
+ }
+ }
+ }
+}
--- /dev/null
+// 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");
+}
#![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>());
}
--- /dev/null
+// 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, "");
+ }
+ }
+}
--- /dev/null
+// 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");
+}
--- /dev/null
+// 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() {}
#![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
}
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.
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 }
}
}
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);
}